From fc1e07da39d76f9950a4e053ab9f196b190933f7 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Wed, 22 Mar 2023 23:55:48 +0800 Subject: [PATCH 001/161] refactor(nc-gui): change to multiple selection --- packages/nc-gui/components/webhook/Editor.vue | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/nc-gui/components/webhook/Editor.vue b/packages/nc-gui/components/webhook/Editor.vue index 2d46cc7726..a488a8d0d3 100644 --- a/packages/nc-gui/components/webhook/Editor.vue +++ b/packages/nc-gui/components/webhook/Editor.vue @@ -41,13 +41,13 @@ const meta = inject(MetaInj, ref()) const useForm = Form.useForm const hook = reactive< - Omit & { notification: Record; eventOperation: string; condition: boolean } + Omit & { notification: Record; eventOperation?: string; condition: boolean } >({ id: '', title: '', event: undefined, operation: undefined, - eventOperation: '', + eventOperation: undefined, notification: { type: 'URL', payload: { @@ -496,6 +496,7 @@ onMounted(async () => { Date: Thu, 23 Mar 2023 14:13:31 +0800 Subject: [PATCH 002/161] refactor(nc-gui): remove payload body editor for url --- packages/nc-gui/components/webhook/Editor.vue | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/nc-gui/components/webhook/Editor.vue b/packages/nc-gui/components/webhook/Editor.vue index a488a8d0d3..212090a08f 100644 --- a/packages/nc-gui/components/webhook/Editor.vue +++ b/packages/nc-gui/components/webhook/Editor.vue @@ -572,15 +572,6 @@ onMounted(async () => { - - - - From 5b91a97ac09cd58c53e04261a0509290d7762891 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Thu, 23 Mar 2023 14:29:17 +0800 Subject: [PATCH 003/161] refactor(nc-gui): make it single select back --- packages/nc-gui/components/webhook/Editor.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/nc-gui/components/webhook/Editor.vue b/packages/nc-gui/components/webhook/Editor.vue index 212090a08f..099e4cde13 100644 --- a/packages/nc-gui/components/webhook/Editor.vue +++ b/packages/nc-gui/components/webhook/Editor.vue @@ -496,7 +496,6 @@ onMounted(async () => { Date: Thu, 23 Mar 2023 14:33:35 +0800 Subject: [PATCH 004/161] refactor(nc-gui): remove unused info --- packages/nc-gui/components/webhook/Editor.vue | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/packages/nc-gui/components/webhook/Editor.vue b/packages/nc-gui/components/webhook/Editor.vue index 099e4cde13..ff68397dca 100644 --- a/packages/nc-gui/components/webhook/Editor.vue +++ b/packages/nc-gui/components/webhook/Editor.vue @@ -686,24 +686,6 @@ onMounted(async () => { -
- Use context variable data to refer the record under consideration - - - - - - - -
- - + From 52d48b1503696e4d3c6699e3cca4268e18107d2b Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Thu, 23 Mar 2023 14:40:09 +0800 Subject: [PATCH 007/161] refactor(nc-gui): remove collapse block --- packages/nc-gui/components/webhook/Test.vue | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/nc-gui/components/webhook/Test.vue b/packages/nc-gui/components/webhook/Test.vue index 2f7ad98cd9..53ff9f41fb 100644 --- a/packages/nc-gui/components/webhook/Test.vue +++ b/packages/nc-gui/components/webhook/Test.vue @@ -17,7 +17,6 @@ const meta = inject(MetaInj, ref()) const sampleData = ref({ data: {}, }) -const activeKey = ref(0) watch( () => hook?.operation, @@ -59,9 +58,6 @@ onMounted(async () => { From 30e5da661d2ca18bbcdd6f7c36a473e6546ed5c3 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Thu, 23 Mar 2023 16:51:31 +0800 Subject: [PATCH 008/161] refactor(nocodb): remove duplicate code --- .../src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts index 5d44e363c3..2d8e4b7d25 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts @@ -1560,9 +1560,6 @@ class BaseModelSqlv2 { await this.beforeInsert(insertObj, trx, cookie); } - // if ('beforeInsert' in this) { - // await this.beforeInsert(insertObj, trx, cookie); - // } await this.model.getColumns(); let response; // const driver = trx ? trx : this.dbDriver; From 3e1feedffd79ad19a20864c343f1cf312eaf7517 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Thu, 23 Mar 2023 18:05:52 +0800 Subject: [PATCH 009/161] feat(nocodb): include view as well --- .../nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts index 2d8e4b7d25..31c40cbaae 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts @@ -2325,7 +2325,7 @@ class BaseModelSqlv2 { }); for (const hook of hooks) { if (hook.active) { - invokeWebhook(hook, this.model, data, req?.user); + invokeWebhook(hook, this.model, view, data, req?.user); } } } catch (e) { From 5cbe7c5f335a61d9528fa6c676e788fedec80448 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Thu, 23 Mar 2023 18:06:07 +0800 Subject: [PATCH 010/161] feat(nocodb): add constructWebHookData --- .../src/lib/meta/helpers/webhookHelpers.ts | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts index a80ac3efd3..3b85830b14 100644 --- a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts +++ b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts @@ -1,10 +1,11 @@ import Handlebars from 'handlebars'; import Filter from '../../models/Filter'; +import Model from '../../models/Model'; +import View from '../../models/View'; +import Hook from '../../models/Hook'; import HookLog from '../../models/HookLog'; import NcPluginMgrv2 from './NcPluginMgrv2'; -import type Model from '../../models/Model'; import type Column from '../../models/Column'; -import type Hook from '../../models/Hook'; import type { HookLogType } from 'nocodb-sdk'; import type FormView from '../../models/FormView'; @@ -133,13 +134,35 @@ export async function validateCondition(filters: Filter[], data: any) { return isValid; } -export async function handleHttpWebHook(apiMeta, user, data) { - // try { +export function constructWebHookData(hook, model, view, data) { + // extend in the future - currently only support records + const scope = 'records'; + + return { + type: `${scope}.${hook.event}.${hook.operation}`, + id: 'TBC', + data: { + table_id: model.id, + table_name: model.title, + view_id: view.id, + view_name: view.title, + rows: [data], + }, + }; +} + +export async function handleHttpWebHook( + hook, + model, + view, + apiMeta, + user, + data +) { + data = constructWebHookData(hook, model, view, data); + console.log(data); const req = axiosRequestMake(apiMeta, user, data); await require('axios')(req); - // } catch (e) { - // console.log(e); - // } } export function axiosRequestMake(_apiMeta, _user, data) { @@ -203,7 +226,8 @@ export function axiosRequestMake(_apiMeta, _user, data) { export async function invokeWebhook( hook: Hook, - _model: Model, + model: Model, + view: View, data, user, testFilters = null, @@ -251,6 +275,9 @@ export async function invokeWebhook( case 'URL': { const res = await handleHttpWebHook( + hook, + model, + view, notification?.payload, user, data From ee001d9ac9c63952985d575dfd06572e2058449d Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Thu, 23 Mar 2023 18:21:07 +0800 Subject: [PATCH 011/161] feat(nocodb): pass prevData to hooks --- .../sql-data-mapper/lib/sql/BaseModelSqlv2.ts | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts index 31c40cbaae..65d579e676 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts @@ -1696,15 +1696,17 @@ class BaseModelSqlv2 { await this.beforeUpdate(data, trx, cookie); + const prevData = await this.readByPk(id); + const query = this.dbDriver(this.tnPath) .update(updateObj) .where(await this._wherePk(id)); await this.execAndParse(query); - const response = await this.readByPk(id); - await this.afterUpdate(response, trx, cookie); - return response; + const newData = await this.readByPk(id); + await this.afterUpdate(prevData, newData, trx, cookie); + return newData; } catch (e) { console.log(e); await this.errorUpdate(e, data, trx, cookie); @@ -2122,11 +2124,11 @@ class BaseModelSqlv2 { * */ public async beforeInsert(data: any, _trx: any, req): Promise { - await this.handleHooks('Before.insert', data, req); + await this.handleHooks('Before.insert', null, data, req); } public async afterInsert(data: any, _trx: any, req): Promise { - await this.handleHooks('After.insert', data, req); + await this.handleHooks('After.insert', null, data, req); // if (req?.headers?.['xc-gui']) { const id = this._extractPksValues(data); await Audit.insert({ @@ -2194,12 +2196,18 @@ class BaseModelSqlv2 { } } if (ignoreWebhook === undefined || ignoreWebhook === 'false') { - await this.handleHooks('Before.update', data, req); + await this.handleHooks('Before.update', null, data, req); } } - public async afterUpdate(data: any, _trx: any, req): Promise { - const id = this._extractPksValues(data); + public async afterUpdate( + prevData: any, + newData: any, + _trx: any, + req + ): Promise { + const id = this._extractPksValues(newData); + await Audit.insert({ fk_model_id: this.model.id, row_id: id, @@ -2218,12 +2226,12 @@ class BaseModelSqlv2 { } } if (ignoreWebhook === undefined || ignoreWebhook === 'false') { - await this.handleHooks('After.update', data, req); + await this.handleHooks('After.update', prevData, newData, req); } } public async beforeDelete(data: any, _trx: any, req): Promise { - await this.handleHooks('Before.delete', data, req); + await this.handleHooks('Before.delete', null, data, req); } public async afterDelete(data: any, _trx: any, req): Promise { @@ -2240,10 +2248,10 @@ class BaseModelSqlv2 { user: req?.user?.email, }); // } - await this.handleHooks('After.delete', data, req); + await this.handleHooks('After.delete', null, data, req); } - private async handleHooks(hookName, data, req): Promise { + private async handleHooks(hookName, prevData, newData, req): Promise { const view = await View.get(this.viewId); // handle form view data submission @@ -2297,7 +2305,7 @@ class BaseModelSqlv2 { .map((a) => a[0]); if (emails?.length) { const transformedData = _transformSubmittedFormDataForEmail( - data, + newData, formView, filteredColumns ); @@ -2325,7 +2333,7 @@ class BaseModelSqlv2 { }); for (const hook of hooks) { if (hook.active) { - invokeWebhook(hook, this.model, view, data, req?.user); + invokeWebhook(hook, this.model, view, prevData, newData, req?.user); } } } catch (e) { From 2cfe3164200308b4559906627333c7551db23dac Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Thu, 23 Mar 2023 18:21:33 +0800 Subject: [PATCH 012/161] feat(nocodb): enrich previous_rows if provided --- .../src/lib/meta/helpers/webhookHelpers.ts | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts index 3b85830b14..316e13139c 100644 --- a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts +++ b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts @@ -1,10 +1,10 @@ import Handlebars from 'handlebars'; import Filter from '../../models/Filter'; -import Model from '../../models/Model'; -import View from '../../models/View'; -import Hook from '../../models/Hook'; import HookLog from '../../models/HookLog'; import NcPluginMgrv2 from './NcPluginMgrv2'; +import type Model from '../../models/Model'; +import type View from '../../models/View'; +import type Hook from '../../models/Hook'; import type Column from '../../models/Column'; import type { HookLogType } from 'nocodb-sdk'; import type FormView from '../../models/FormView'; @@ -134,7 +134,7 @@ export async function validateCondition(filters: Filter[], data: any) { return isValid; } -export function constructWebHookData(hook, model, view, data) { +export function constructWebHookData(hook, model, view, prevData, newData) { // extend in the future - currently only support records const scope = 'records'; @@ -146,7 +146,8 @@ export function constructWebHookData(hook, model, view, data) { table_name: model.title, view_id: view.id, view_name: view.title, - rows: [data], + ...(prevData && { previous_rows: prevData }), + rows: [newData], }, }; } @@ -157,11 +158,14 @@ export async function handleHttpWebHook( view, apiMeta, user, - data + prevData, + newData ) { - data = constructWebHookData(hook, model, view, data); - console.log(data); - const req = axiosRequestMake(apiMeta, user, data); + const req = axiosRequestMake( + apiMeta, + user, + constructWebHookData(hook, model, view, prevData, newData) + ); await require('axios')(req); } @@ -228,7 +232,8 @@ export async function invokeWebhook( hook: Hook, model: Model, view: View, - data, + prevData, + newData, user, testFilters = null, throwErrorOnFailure = false @@ -246,7 +251,7 @@ export async function invokeWebhook( if ( !(await validateCondition( testFilters || (await hook.getFilters()), - data + newData )) ) { return; @@ -259,9 +264,9 @@ export async function invokeWebhook( const res = await ( await NcPluginMgrv2.emailAdapter() )?.mailSend({ - to: parseBody(notification?.payload?.to, data), - subject: parseBody(notification?.payload?.subject, data), - html: parseBody(notification?.payload?.body, data), + to: parseBody(notification?.payload?.to, newData), + subject: parseBody(notification?.payload?.subject, newData), + html: parseBody(notification?.payload?.body, newData), }); hookLog = { ...hook, @@ -280,7 +285,8 @@ export async function invokeWebhook( view, notification?.payload, user, - data + prevData, + newData ); hookLog = { @@ -297,9 +303,11 @@ export async function invokeWebhook( const res = await ( await NcPluginMgrv2.webhookNotificationAdapters(notification.type) ).sendMessage( - parseBody(notification?.payload?.body, data), + parseBody(notification?.payload?.body, newData), JSON.parse(JSON.stringify(notification?.payload), (_key, value) => { - return typeof value === 'string' ? parseBody(value, data) : value; + return typeof value === 'string' + ? parseBody(value, newData) + : value; }) ); From 766189302ba08ad9453f3d8dbce0fdbd5175715b Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Thu, 23 Mar 2023 19:15:23 +0800 Subject: [PATCH 013/161] fix(nocodb): typo and data position in delByPk --- .../src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts index 65d579e676..5f22b46809 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts @@ -1631,7 +1631,7 @@ class BaseModelSqlv2 { async delByPk(id, trx?, cookie?) { try { - // retrieve data for handling paramas in hook + // retrieve data for handling params in hook const data = await this.readByPk(id); await this.beforeDelete(id, trx, cookie); const response = await this.dbDriver(this.tnPath) @@ -2248,7 +2248,7 @@ class BaseModelSqlv2 { user: req?.user?.email, }); // } - await this.handleHooks('After.delete', null, data, req); + await this.handleHooks('After.delete', data, null, req); } private async handleHooks(hookName, prevData, newData, req): Promise { From 40470703fe1abdce21dc02b8e98f3532d6293370 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Thu, 23 Mar 2023 19:15:35 +0800 Subject: [PATCH 014/161] feat(nocodb): enrich deleted_rows --- packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts index 316e13139c..adfb1739ce 100644 --- a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts +++ b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts @@ -146,8 +146,12 @@ export function constructWebHookData(hook, model, view, prevData, newData) { table_name: model.title, view_id: view.id, view_name: view.title, - ...(prevData && { previous_rows: prevData }), - rows: [newData], + ...(prevData && { + [hook.operation === 'delete' ? 'deleted_rows' : 'previous_rows']: [ + prevData, + ], + }), + ...(newData && { rows: [newData] }), }, }; } From 316779b81076756936bb96020e6a55791a1f9c81 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 11:13:13 +0800 Subject: [PATCH 015/161] refactor(nc-gui): revise hook sample data structure --- packages/nc-gui/components/webhook/Test.vue | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/nc-gui/components/webhook/Test.vue b/packages/nc-gui/components/webhook/Test.vue index 53ff9f41fb..2bff4fafa1 100644 --- a/packages/nc-gui/components/webhook/Test.vue +++ b/packages/nc-gui/components/webhook/Test.vue @@ -14,9 +14,7 @@ const { $api } = useNuxtApp() const meta = inject(MetaInj, ref()) -const sampleData = ref({ - data: {}, -}) +const sampleData = ref() watch( () => hook?.operation, @@ -26,9 +24,7 @@ watch( ) async function loadSampleData() { - sampleData.value = { - data: await $api.dbTableWebhook.samplePayloadGet(meta?.value?.id as string, hook?.operation || 'insert'), - } + sampleData.value = await $api.dbTableWebhook.samplePayloadGet(meta?.value?.id as string, hook?.operation || 'insert') } async function testWebhook() { From 88948ca15fe1eee911e196cd56fe94a430df5450 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 11:58:31 +0800 Subject: [PATCH 016/161] refactor(nocodb): revise hook sample data structure --- .../lib/meta/helpers/populateSamplePayload.ts | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/nocodb/src/lib/meta/helpers/populateSamplePayload.ts b/packages/nocodb/src/lib/meta/helpers/populateSamplePayload.ts index 8167134b27..c92152a584 100644 --- a/packages/nocodb/src/lib/meta/helpers/populateSamplePayload.ts +++ b/packages/nocodb/src/lib/meta/helpers/populateSamplePayload.ts @@ -9,9 +9,10 @@ import type SelectOption from '../../models/SelectOption'; export default async function populateSamplePayload( viewOrModel: View | Model, includeNested = false, - operation = 'insert' + operation = 'insert', + scope = 'records' ) { - const out = {}; + const rows = {}; let columns: Column[] = []; let model: Model; if (viewOrModel instanceof View) { @@ -26,6 +27,18 @@ export default async function populateSamplePayload( model = viewOrModel; } + await model.getViews(); + + const samplePayload = { + type: `${scope}.after.${operation}`, + data: { + table_id: model.id, + table_name: model.title, + view_id: model.views[0].id, + view_name: model.views[0].title, + }, + }; + for (const column of columns) { if ( !includeNested && @@ -33,13 +46,23 @@ export default async function populateSamplePayload( ) continue; - if (operation === 'delete' && model.primaryKey?.title !== column.title) - continue; + rows[column.title] = await getSampleColumnValue(column); + } - out[column.title] = await getSampleColumnValue(column); + let prevRows; + if (operation !== 'insert') { + prevRows = rows; } - return out; + samplePayload.data = { + ...samplePayload.data, + ...(prevRows && { + [operation === 'delete' ? 'deleted_rows' : 'previous_rows']: [prevRows], + }), + ...(operation !== 'delete' && rows && { rows: [rows] }), + }; + + return samplePayload; } async function getSampleColumnValue(column: Column): Promise { From 14f7f496fb8a4a0360773e8696b50e087e8e9d47 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 13:17:42 +0800 Subject: [PATCH 017/161] feat(nocodb): url hook for bulk operations --- .../src/lib/meta/helpers/webhookHelpers.ts | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts index adfb1739ce..c148f7f702 100644 --- a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts +++ b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts @@ -245,20 +245,44 @@ export async function invokeWebhook( let hookLog: HookLogType; const startTime = process.hrtime(); try { - // for (const hook of hooks) { const notification = typeof hook.notification === 'string' ? JSON.parse(hook.notification) : hook.notification; + const isBulkOperation = Array.isArray(newData); + + if (isBulkOperation && notification?.type !== 'URL') { + // only URL hook is supported for bulk operations + return; + } + if (hook.condition) { - if ( - !(await validateCondition( - testFilters || (await hook.getFilters()), - newData - )) - ) { - return; + if (isBulkOperation) { + const filteredData = []; + for (const data of newData) { + if ( + await validateCondition( + testFilters || (await hook.getFilters()), + data + ) + ) { + filteredData.push(data); + } + if (!filteredData.length) { + return; + } + newData = filteredData; + } + } else { + if ( + !(await validateCondition( + testFilters || (await hook.getFilters()), + newData + )) + ) { + return; + } } } From 7a25fc04c074607cbdb39e88171ef987b7609cbe Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 13:18:28 +0800 Subject: [PATCH 018/161] feat(nocodb): add handleHooks to afterBulkInsert --- .../src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts index 5f22b46809..9152b1fab8 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts @@ -1954,7 +1954,7 @@ class BaseModelSqlv2 { chunkSize ); - await this.afterBulkInsert(insertDatas, this.dbDriver, cookie); + await this.afterBulkInsert(response, this.dbDriver, cookie); return response; } catch (e) { @@ -2175,6 +2175,8 @@ class BaseModelSqlv2 { } public async afterBulkInsert(data: any[], _trx: any, req): Promise { + await this.handleHooks('After.insert', null, data, req); + await Audit.insert({ fk_model_id: this.model.id, op_type: AuditOperationTypes.DATA, From cadddebfbbbfe99208400d96b95fc04517ee9f68 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 13:39:34 +0800 Subject: [PATCH 019/161] feat(nocodb): add handleHooks to afterBulkUpdate --- .../db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts index 9152b1fab8..ac9de54b4d 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts @@ -1982,13 +1982,11 @@ class BaseModelSqlv2 { continue; } const wherePk = await this._wherePk(pkValues); - const response = await transaction(this.tnPath) - .update(d) - .where(wherePk); - res.push(response); + await transaction(this.tnPath).update(d).where(wherePk); + res.push(wherePk); } - await this.afterBulkUpdate(updateDatas.length, this.dbDriver, cookie); + await this.afterBulkUpdate(res, this.dbDriver, cookie); transaction.commit(); return res; @@ -2041,7 +2039,7 @@ class BaseModelSqlv2 { } const count = queryResponse ?? 0; - await this.afterBulkUpdate(count, this.dbDriver, cookie); + await this.afterBulkUpdate(queryResponse, this.dbDriver, cookie); return count; } catch (e) { @@ -2146,13 +2144,15 @@ class BaseModelSqlv2 { // } } - public async afterBulkUpdate(count: number, _trx: any, req): Promise { + public async afterBulkUpdate(data: any, _trx: any, req): Promise { + await this.handleHooks('After.update', null, data, req); + await Audit.insert({ fk_model_id: this.model.id, op_type: AuditOperationTypes.DATA, op_sub_type: AuditOperationSubTypes.BULK_UPDATE, description: DOMPurify.sanitize( - `${count} records bulk updated in ${this.model.title}` + `${data.length} records bulk updated in ${this.model.title}` ), // details: JSON.stringify(data), ip: req?.clientIp, From a6eb67b4bef698fd5d0e7a89d383ce441daa8fbf Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 14:03:23 +0800 Subject: [PATCH 020/161] refactor(nocodb): bulkUpdateAll logic --- .../db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts index ac9de54b4d..5ee052ab85 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts @@ -2003,7 +2003,7 @@ class BaseModelSqlv2 { data, { cookie }: { cookie?: any } = {} ) { - let queryResponse; + let res = []; try { const updateData = await this.model.mapAliasToColumn(data); await this.validate(updateData); @@ -2035,13 +2035,19 @@ class BaseModelSqlv2 { ); qb.update(updateData); - queryResponse = (await qb) as any; + + if (this.isPg || this.isMssql) { + qb.returning( + `${this.model.primaryKey.column_name} as ${this.model.primaryKey.title}` + ); + } + + res = (await qb) as any; } - const count = queryResponse ?? 0; - await this.afterBulkUpdate(queryResponse, this.dbDriver, cookie); + await this.afterBulkUpdate(res, this.dbDriver, cookie); - return count; + return res.length; } catch (e) { throw e; } From 7c55bf900a3d6df4e9ebfc4dd752ae3b982ea73d Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 14:39:23 +0800 Subject: [PATCH 021/161] feat(nocodb): afterBulkDelete logic --- .../sql-data-mapper/lib/sql/BaseModelSqlv2.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts index 5ee052ab85..ab4caaf1ef 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts @@ -2066,15 +2066,15 @@ class BaseModelSqlv2 { const res = []; for (const d of deleteIds) { if (Object.keys(d).length) { - const response = await transaction(this.tnPath).del().where(d); - res.push(response); + await transaction(this.tnPath).del().where(d); + res.push(d); } } // await this.afterDeleteb(res, transaction); transaction.commit(); - await this.afterBulkDelete(ids.length, this.dbDriver, cookie); + await this.afterBulkDelete(res, this.dbDriver, cookie); return res; } catch (e) { @@ -2112,7 +2112,15 @@ class BaseModelSqlv2 { qb, this.dbDriver ); + qb.del(); + + if (this.isPg || this.isMssql) { + qb.returning( + `${this.model.primaryKey.column_name} as ${this.model.primaryKey.title}` + ); + } + const count = (await qb) as any; await this.afterBulkDelete(count, this.dbDriver, cookie); @@ -2166,13 +2174,15 @@ class BaseModelSqlv2 { }); } - public async afterBulkDelete(count: number, _trx: any, req): Promise { + public async afterBulkDelete(data: any, _trx: any, req): Promise { + await this.handleHooks('After.delete', data, null, req); + await Audit.insert({ fk_model_id: this.model.id, op_type: AuditOperationTypes.DATA, op_sub_type: AuditOperationSubTypes.BULK_DELETE, description: DOMPurify.sanitize( - `${count} records bulk deleted in ${this.model.title}` + `${data.length} records bulk deleted in ${this.model.title}` ), // details: JSON.stringify(data), ip: req?.clientIp, From f1d6f22a40a777a949fb410282e6aa34495fa3e3 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 16:50:15 +0800 Subject: [PATCH 022/161] refactor(nocodb): remove unnecessary comments --- .../sql-data-mapper/lib/sql/BaseModelSqlv2.ts | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts index ab4caaf1ef..4a51d42504 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts @@ -1890,21 +1890,14 @@ class BaseModelSqlv2 { rowId = response[this.model.primaryKey.title] || response[this.model.primaryKey.column_name]; - await Promise.all(postInsertOps.map((f) => f())); - // if (!trx) { - // await driver.commit(); - // } + await Promise.all(postInsertOps.map((f) => f())); await this.afterInsert(response, this.dbDriver, cookie); return response; } catch (e) { console.log(e); - // await this.errorInsert(e, data, trx, cookie); - // if (!trx) { - // await driver.rollback(e); - // } throw e; } } @@ -1932,11 +1925,6 @@ class BaseModelSqlv2 { for (const data of datas) { await this.validate(data); } - // let chunkSize = 50; - // - // if (this.isSqlite && datas[0]) { - // chunkSize = Math.max(1, Math.floor(999 / Object.keys(datas[0]).length)); - // } // fallbacks to `10` if database client is sqlite // to avoid `too many SQL variables` error @@ -1992,8 +1980,6 @@ class BaseModelSqlv2 { return res; } catch (e) { if (transaction) transaction.rollback(); - // console.log(e); - // await this.errorUpdateb(e, data, null); throw e; } } @@ -2061,7 +2047,6 @@ class BaseModelSqlv2 { ); transaction = await this.dbDriver.transaction(); - // await this.beforeDeleteb(ids, transaction); const res = []; for (const d of deleteIds) { @@ -2070,7 +2055,6 @@ class BaseModelSqlv2 { res.push(d); } } - // await this.afterDeleteb(res, transaction); transaction.commit(); @@ -2080,7 +2064,6 @@ class BaseModelSqlv2 { } catch (e) { if (transaction) transaction.rollback(); console.log(e); - // await this.errorDeleteb(e, ids); throw e; } } @@ -2141,7 +2124,6 @@ class BaseModelSqlv2 { public async afterInsert(data: any, _trx: any, req): Promise { await this.handleHooks('After.insert', null, data, req); - // if (req?.headers?.['xc-gui']) { const id = this._extractPksValues(data); await Audit.insert({ fk_model_id: this.model.id, @@ -2155,7 +2137,6 @@ class BaseModelSqlv2 { ip: req?.clientIp, user: req?.user?.email, }); - // } } public async afterBulkUpdate(data: any, _trx: any, req): Promise { @@ -2253,7 +2234,6 @@ class BaseModelSqlv2 { } public async afterDelete(data: any, _trx: any, req): Promise { - // if (req?.headers?.['xc-gui']) { const id = req?.params?.id; await Audit.insert({ fk_model_id: this.model.id, @@ -2265,7 +2245,6 @@ class BaseModelSqlv2 { ip: req?.clientIp, user: req?.user?.email, }); - // } await this.handleHooks('After.delete', data, null, req); } From 9da494ff315b0d40a064cd4bfccf25335db0685e Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 17:21:53 +0800 Subject: [PATCH 023/161] feat(nocodb): nc_029_alter_hooklog_response_types --- .../src/lib/migrations/XcMigrationSourcev2.ts | 4 +++ .../v2/nc_029_alter_hooklog_response_types.ts | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 packages/nocodb/src/lib/migrations/v2/nc_029_alter_hooklog_response_types.ts diff --git a/packages/nocodb/src/lib/migrations/XcMigrationSourcev2.ts b/packages/nocodb/src/lib/migrations/XcMigrationSourcev2.ts index 239b89529a..c5d65a7100 100644 --- a/packages/nocodb/src/lib/migrations/XcMigrationSourcev2.ts +++ b/packages/nocodb/src/lib/migrations/XcMigrationSourcev2.ts @@ -16,6 +16,7 @@ import * as nc_025_add_row_height from './v2/nc_025_add_row_height'; import * as nc_026_map_view from './v2/nc_026_map_view'; import * as nc_027_add_comparison_sub_op from './v2/nc_027_add_comparison_sub_op'; import * as nc_028_add_enable_scanner_in_form_columns_meta_table from './v2/nc_026_add_enable_scanner_in_form_columns_meta_table'; +import * as nc_029_alter_hooklog_response_types from './v2/nc_029_alter_hooklog_response_types'; // Create a custom migration source class export default class XcMigrationSourcev2 { @@ -43,6 +44,7 @@ export default class XcMigrationSourcev2 { 'nc_026_map_view', 'nc_027_add_comparison_sub_op', 'nc_028_add_enable_scanner_in_form_columns_meta_table', + 'nc_029_alter_hooklog_response_types', ]); } @@ -88,6 +90,8 @@ export default class XcMigrationSourcev2 { return nc_027_add_comparison_sub_op; case 'nc_028_add_enable_scanner_in_form_columns_meta_table': return nc_028_add_enable_scanner_in_form_columns_meta_table; + case 'nc_029_alter_hooklog_response_types': + return nc_029_alter_hooklog_response_types; } } } diff --git a/packages/nocodb/src/lib/migrations/v2/nc_029_alter_hooklog_response_types.ts b/packages/nocodb/src/lib/migrations/v2/nc_029_alter_hooklog_response_types.ts new file mode 100644 index 0000000000..3aaff5d397 --- /dev/null +++ b/packages/nocodb/src/lib/migrations/v2/nc_029_alter_hooklog_response_types.ts @@ -0,0 +1,27 @@ +import { MetaTable } from '../../utils/globals'; +import type { Knex } from 'knex'; + +const up = async (knex: Knex) => { + if (knex.client.config.client === 'mssql') { + await knex.schema.alterTable(MetaTable.HOOK_LOGS, (table) => { + table.dropColumn('response'); + }); + await knex.schema.alterTable(MetaTable.HOOK_LOGS, (table) => { + table.text('response'); + }); + } else if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable(MetaTable.HOOK_LOGS, (table) => { + table.text('response').alter(); + }); + } +}; + +const down = async (knex) => { + if (knex.client.config.client !== 'sqlite3') { + await knex.schema.alterTable(MetaTable.HOOK_LOGS, (table) => { + table.boolean('response').alter(); + }); + } +}; + +export { up, down }; From 1932b01af382477cfd543632e0493282b5ebedeb Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 17:27:44 +0800 Subject: [PATCH 024/161] fix(nocodb): hook response in hook log --- .../nocodb/src/lib/meta/helpers/webhookHelpers.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts index c148f7f702..6d41599e3c 100644 --- a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts +++ b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts @@ -170,7 +170,7 @@ export async function handleHttpWebHook( user, constructWebHookData(hook, model, view, prevData, newData) ); - await require('axios')(req); + return require('axios')(req); } export function axiosRequestMake(_apiMeta, _user, data) { @@ -321,7 +321,18 @@ export async function invokeWebhook( ...hook, type: notification.type, payload: JSON.stringify(notification?.payload), - response: JSON.stringify(res), + response: JSON.stringify({ + status: res.status, + statusText: res.statusText, + headers: res.headers, + config: { + url: res.config.url, + method: res.config.method, + data: res.config.data, + headers: res.config.headers, + params: res.config.params, + }, + }), triggered_by: user?.email, }; } From c7a300217023d6e3080a309784801cf7e6cd0c77 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 18:26:05 +0800 Subject: [PATCH 025/161] feat(nocodb): include fk_hook_id in hook log --- packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts index 6d41599e3c..e982233841 100644 --- a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts +++ b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts @@ -319,6 +319,7 @@ export async function invokeWebhook( hookLog = { ...hook, + fk_hook_id: hook.id, type: notification.type, payload: JSON.stringify(notification?.payload), response: JSON.stringify({ @@ -352,6 +353,7 @@ export async function invokeWebhook( hookLog = { ...hook, + fk_hook_id: hook.id, type: notification.type, payload: JSON.stringify(notification?.payload), response: JSON.stringify(res), From 4b10d700d8f89bab4e74849639d883b4265a3d7a Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 18:26:18 +0800 Subject: [PATCH 026/161] feat(nocodb): use hkl as prefix for hook_logs --- packages/nocodb/src/lib/meta/NcMetaIOImpl.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/nocodb/src/lib/meta/NcMetaIOImpl.ts b/packages/nocodb/src/lib/meta/NcMetaIOImpl.ts index 31000760c6..b04157a088 100644 --- a/packages/nocodb/src/lib/meta/NcMetaIOImpl.ts +++ b/packages/nocodb/src/lib/meta/NcMetaIOImpl.ts @@ -855,6 +855,9 @@ export default class NcMetaIOImpl extends NcMetaIO { case MetaTable.HOOKS: prefix = 'hk_'; break; + case MetaTable.HOOK_LOGS: + prefix = 'hkl_'; + break; case MetaTable.AUDIT: prefix = 'adt_'; break; From fab502479dfa1c2abff23cf03e099e5fc630ab9e Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 18:44:51 +0800 Subject: [PATCH 027/161] feat(nc-gui): MdiHistory --- packages/nc-gui/components.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/nc-gui/components.d.ts b/packages/nc-gui/components.d.ts index 7c5b61f85e..409d580112 100644 --- a/packages/nc-gui/components.d.ts +++ b/packages/nc-gui/components.d.ts @@ -193,6 +193,7 @@ declare module '@vue/runtime-core' { MdiGpsFixed: typeof import('~icons/mdi/gps-fixed')['default'] MdiGraphOutline: typeof import('~icons/mdi/graph-outline')['default'] MdiHeart: typeof import('~icons/mdi/heart')['default'] + MdiHistory: typeof import('~icons/mdi/history')['default'] MdiHook: typeof import('~icons/mdi/hook')['default'] MdiInformation: typeof import('~icons/mdi/information')['default'] MdiJson: typeof import('~icons/mdi/json')['default'] From 1ce979f2d899c913e355af5b7dab47b12c91b0db Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 18:46:03 +0800 Subject: [PATCH 028/161] feat(nc-gui): include LazyWebhookCallLog component --- packages/nc-gui/components/webhook/Editor.vue | 500 +++++++++--------- 1 file changed, 261 insertions(+), 239 deletions(-) diff --git a/packages/nc-gui/components/webhook/Editor.vue b/packages/nc-gui/components/webhook/Editor.vue index 9625ec9b68..4d61f0da5a 100644 --- a/packages/nc-gui/components/webhook/Editor.vue +++ b/packages/nc-gui/components/webhook/Editor.vue @@ -38,6 +38,8 @@ const { appInfo } = $(useGlobal()) const meta = inject(MetaInj, ref()) +const hookTabKey = ref('hook-edit') + const useForm = Form.useForm const hook = reactive< @@ -461,243 +463,263 @@ onMounted(async () => { - - - - - - - {{ $t('activity.enableWebhook') }} - - - - - - - - - - - - - - - - - - - - {{ event.text.join(' ') }} - - - - - - - - - -
- - - - - - - - - - - - - - - - - {{ notificationOption.type }} -
-
-
-
-
-
- - - - - - {{ method.title }} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - On Condition - - - - - - - - - - - - -
-
+ + + + + + + + + + {{ $t('activity.enableWebhook') }} + + + + + + + + + + + + + + + + + + + + {{ event.text.join(' ') }} + + + + + + + + + +
+ + + + + + + + + + + + + + + + + {{ notificationOption.type }} +
+
+
+
+
+
+ + + + + + {{ method.title }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + On Condition + + + + + + + + + + + + +
+
+
+ + + + + +
From 3eb472b34eb693c006b964c8e1d6b36fe6a40927 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 18:51:17 +0800 Subject: [PATCH 029/161] feat(nocodb): use uuid in hook --- packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts index e982233841..1158fa467b 100644 --- a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts +++ b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts @@ -1,4 +1,5 @@ import Handlebars from 'handlebars'; +import { v4 as uuidv4 } from 'uuid'; import Filter from '../../models/Filter'; import HookLog from '../../models/HookLog'; import NcPluginMgrv2 from './NcPluginMgrv2'; @@ -140,7 +141,7 @@ export function constructWebHookData(hook, model, view, prevData, newData) { return { type: `${scope}.${hook.event}.${hook.operation}`, - id: 'TBC', + id: uuidv4(), data: { table_id: model.id, table_name: model.title, From f4861df4b58f69496b2dddca2e4a8c73d07364c4 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 19:03:35 +0800 Subject: [PATCH 030/161] feat(nc-gui): add disabled for hook log tab and pass hook to LazyWebhookCallLog --- packages/nc-gui/components/webhook/Editor.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nc-gui/components/webhook/Editor.vue b/packages/nc-gui/components/webhook/Editor.vue index 4d61f0da5a..f338d5448f 100644 --- a/packages/nc-gui/components/webhook/Editor.vue +++ b/packages/nc-gui/components/webhook/Editor.vue @@ -712,14 +712,14 @@ onMounted(async () => { - + - +
From 4d1b99cb2d76726bde4fb83183a0018738633b8f Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 19:08:15 +0800 Subject: [PATCH 031/161] refactor(nocodb): remove unused comments --- packages/nocodb/src/lib/models/HookLog.ts | 24 ++--------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/packages/nocodb/src/lib/models/HookLog.ts b/packages/nocodb/src/lib/models/HookLog.ts index 09f18063af..e88e26202b 100644 --- a/packages/nocodb/src/lib/models/HookLog.ts +++ b/packages/nocodb/src/lib/models/HookLog.ts @@ -24,8 +24,8 @@ export default class HookLog implements HookLogType { response?: string; triggered_by?: string; - constructor(hook: Partial) { - Object.assign(this, hook); + constructor(hookLog: Partial) { + Object.assign(this, hookLog); } static async list( @@ -36,31 +36,11 @@ export default class HookLog implements HookLogType { }, ncMeta = Noco.ncMeta ) { - // todo: redis cache ?? - // let hooks = await NocoCache.getList(CacheScope.HOOK, [param.fk_model_id]); - // if (!hooks.length) { const hookLogs = await ncMeta.metaList(null, null, MetaTable.HOOK_LOGS, { condition: { fk_hook_id: param.fk_hook_id, - // ...(param.event ? { event: param.event?.toLowerCase?.() } : {}), - // ...(param.operation - // ? { operation: param.operation?.toLowerCase?.() } - // : {}) }, }); - // await NocoCache.setList(CacheScope.HOOK, [param.fk_model_id], hooks); - // } - // // filter event & operation - // if (param.event) { - // hooks = hooks.filter( - // h => h.event?.toLowerCase() === param.event?.toLowerCase() - // ); - // } - // if (param.operation) { - // hooks = hooks.filter( - // h => h.operation?.toLowerCase() === param.operation?.toLowerCase() - // ); - // } return hookLogs?.map((h) => new HookLog(h)); } From a11516c4a9d6c7ff2c5fc4f595fd728193edc19e Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 19:18:17 +0800 Subject: [PATCH 032/161] feat(nocodb): add hookLogList --- .../nocodb/src/lib/controllers/hook.ctl.ts | 22 ++++++++++++++++++- packages/nocodb/src/lib/services/hook.svc.ts | 6 ++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/nocodb/src/lib/controllers/hook.ctl.ts b/packages/nocodb/src/lib/controllers/hook.ctl.ts index 7e671d2ec1..7e158b878d 100644 --- a/packages/nocodb/src/lib/controllers/hook.ctl.ts +++ b/packages/nocodb/src/lib/controllers/hook.ctl.ts @@ -4,7 +4,7 @@ import { PagedResponseImpl } from '../meta/helpers/PagedResponse'; import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; import { metaApiMetrics } from '../meta/helpers/apiMetrics'; import { hookService } from '../services'; -import type { HookListType, HookType } from 'nocodb-sdk'; +import type { HookListType, HookLogListType, HookType } from 'nocodb-sdk'; import type { Request, Response } from 'express'; export async function hookList( @@ -63,12 +63,25 @@ export async function tableSampleData(req: Request, res: Response) { ); } +export async function hookLogList( + req: Request, + res: Response +) { + res.json( + new PagedResponseImpl( + await hookService.hookLogList({ tableId: req.params.hookId }) + ) + ); +} + const router = Router({ mergeParams: true }); + router.get( '/api/v1/db/meta/tables/:tableId/hooks', metaApiMetrics, ncMetaAclMw(hookList, 'hookList') ); + router.post( '/api/v1/db/meta/tables/:tableId/hooks/test', metaApiMetrics, @@ -94,4 +107,11 @@ router.get( metaApiMetrics, catchError(tableSampleData) ); + +router.get( + '/api/v1/db/meta/hooks/:hookId/logs', + metaApiMetrics, + ncMetaAclMw(hookLogList, 'hookLogList') +); + export default router; diff --git a/packages/nocodb/src/lib/services/hook.svc.ts b/packages/nocodb/src/lib/services/hook.svc.ts index 04d2dc5f96..ec5d32f669 100644 --- a/packages/nocodb/src/lib/services/hook.svc.ts +++ b/packages/nocodb/src/lib/services/hook.svc.ts @@ -1,7 +1,7 @@ import { T } from 'nc-help'; import { validatePayload } from '../meta/api/helpers'; import { NcError } from '../meta/helpers/catchError'; -import { Hook, Model } from '../models'; +import { Hook, HookLog, Model } from '../models'; import { invokeWebhook } from '../meta/helpers/webhookHelpers'; import populateSamplePayload from '../meta/helpers/populateSamplePayload'; import type { HookReqType, HookTestReqType } from 'nocodb-sdk'; @@ -26,6 +26,10 @@ export async function hookList(param: { tableId: string }) { return await Hook.list({ fk_model_id: param.tableId }); } +export async function hookLogList(param: { hookId: string }) { + return await HookLog.list({ fk_hook_id: param.hookId }); +} + export async function hookCreate(param: { tableId: string; hook: HookReqType; From 41c5e83d537aba9c8178f8a96e25222eb94881a5 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 19:18:38 +0800 Subject: [PATCH 033/161] fix(nocodb): tableId -> hookId in hook.ctl.ts --- packages/nocodb/src/lib/controllers/hook.ctl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/controllers/hook.ctl.ts b/packages/nocodb/src/lib/controllers/hook.ctl.ts index 7e158b878d..4b09fb4f45 100644 --- a/packages/nocodb/src/lib/controllers/hook.ctl.ts +++ b/packages/nocodb/src/lib/controllers/hook.ctl.ts @@ -69,7 +69,7 @@ export async function hookLogList( ) { res.json( new PagedResponseImpl( - await hookService.hookLogList({ tableId: req.params.hookId }) + await hookService.hookLogList({ hookId: req.params.hookId }) ) ); } From 9df8b8b23e46e92a8c52d7f9ac1bd7223c96fe10 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 19:19:27 +0800 Subject: [PATCH 034/161] refactor(nocodb): change operation type to insert or update in hook.ctl.ts --- packages/nocodb/src/lib/controllers/hook.ctl.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/nocodb/src/lib/controllers/hook.ctl.ts b/packages/nocodb/src/lib/controllers/hook.ctl.ts index 4b09fb4f45..ae7b7ce112 100644 --- a/packages/nocodb/src/lib/controllers/hook.ctl.ts +++ b/packages/nocodb/src/lib/controllers/hook.ctl.ts @@ -57,8 +57,7 @@ export async function tableSampleData(req: Request, res: Response) { res.json( await hookService.tableSampleData({ tableId: req.params.tableId, - // todo: replace any with type - operation: req.params.operation as any, + operation: req.params.operation as 'insert' | 'update', }) ); } From 0b43f8c670d4777fbd3ffc6ed91645e6db5aab10 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 19:52:37 +0800 Subject: [PATCH 035/161] feat(nocodb): add hook logs api --- packages/nocodb/src/schema/swagger.json | 603 +++++++++++++++++++----- 1 file changed, 474 insertions(+), 129 deletions(-) diff --git a/packages/nocodb/src/schema/swagger.json b/packages/nocodb/src/schema/swagger.json index 60fc44bfff..c7f32b6be6 100644 --- a/packages/nocodb/src/schema/swagger.json +++ b/packages/nocodb/src/schema/swagger.json @@ -5934,6 +5934,76 @@ ] } }, + "/api/v1/db/meta/hooks/{hookId}/logs": { + "parameters": [ + { + "schema": { + "$ref": "#/components/schemas/Id", + "example": "hk_0063k4o1frnxbr" + }, + "name": "hookId", + "in": "path", + "required": true, + "description": "Unique Hook ID" + } + ], + "get": { + "summary": "Get Hook Logs", + "operationId": "db-table-webhook-logs-list", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HookLogList" + }, + "examples": { + "Example 1": { + "value": { + "list": [ + { + "base_id": "ds_jxuewivwbxeum2", + "event": "after", + "execution_time": "98", + "fk_hook_id": "hk_035ijv5qdi97y5", + "id": "string", + "notifications": "{\"type\":\"URL\",\"payload\":{\"method\":\"POST\",\"body\":\"{{ json data }}\",\"headers\":[{}],\"parameters\":[{}],\"auth\":\"\",\"path\":\"https://webhook.site/6eb45ce5-b611-4be1-8b96-c2965755662b\"}}", + "operation": "insert", + "payload": "{\"method\":\"POST\",\"body\":\"{{ json data }}\",\"headers\":[{}],\"parameters\":[{}],\"auth\":\"\",\"path\":\"https://webhook.site/6eb45ce5-b611-4be1-8b96-c2965755662b\"}", + "project_id": "p_tbhl1hnycvhe5l", + "response": "{\"status\":200,\"statusText\":\"OK\",\"headers\":{\"server\":\"nginx\",\"content-type\":\"text/plain; charset=UTF-8\",\"transfer-encoding\":\"chunked\",\"connection\":\"close\",\"vary\":\"Accept-Encoding\",\"x-request-id\":\"53844a7d-ede8-4798-adf7-8af441908a72\",\"x-token-id\":\"6eb45ce5-b611-4be1-8b96-c2965755662b\",\"cache-control\":\"no-cache, private\",\"date\":\"Fri, 24 Mar 2023 10:50:10 GMT\"},\"config\":{\"url\":\"https://webhook.site/6eb45ce5-b611-4be1-8b96-c2965755662b\",\"method\":\"post\",\"data\":\"{\\\"type\\\":\\\"records.after.insert\\\",\\\"id\\\":\\\"a77d97dc-a3e4-4719-9b46-45f93e0cc99a\\\",\\\"data\\\":{\\\"table_id\\\":\\\"md_d8v403o74mf5lf\\\",\\\"table_name\\\":\\\"Sheet-2\\\"}}\",\"headers\":{\"Accept\":\"application/json, text/plain, */*\",\"Content-Type\":\"application/x-www-form-urlencoded\",\"User-Agent\":\"axios/0.21.4\",\"Content-Length\":138},\"params\":{}}}", + "test_call": 0, + "triggered_by": "w@nocodb.com", + "type": "URL" + } + ], + "pageInfo": { + "isFirstPage": true, + "isLastPage": true, + "page": 1, + "pageSize": 10, + "totalRows": 1 + } + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + } + }, + "tags": ["DB Table Webhook Logs"], + "description": "Get the log data in a given Hook", + "parameters": [ + { + "$ref": "#/components/parameters/xc-auth" + } + ] + } + }, "/api/v1/db/meta/filters/{filterId}": { "parameters": [ { @@ -13646,7 +13716,7 @@ } }, "x-stoplight": { - "id": "zc9ztw0ih4ttt" + "id": "it370mpkpd4mo" } }, "ApiTokenReq": { @@ -13667,13 +13737,13 @@ } }, "x-stoplight": { - "id": "t9dpbaw4dhpx3" + "id": "uwroiaim8dm2p" } }, "ApiTokenList": { "description": "Model for API Token List", "x-stoplight": { - "id": "dgoo5jfkvypld" + "id": "wnzpsmdzrwhi2" }, "examples": [ { @@ -13778,7 +13848,7 @@ } }, "x-stoplight": { - "id": "9uff8of377ouf" + "id": "3fmfrjdlcgmrd" } }, "AttachmentReq": { @@ -13816,7 +13886,7 @@ } }, "x-stoplight": { - "id": "7mvkmys63d0bx" + "id": "o5x54q347g7wk" } }, "Audit": { @@ -13941,7 +14011,7 @@ } }, "x-stoplight": { - "id": "dz9hjvx07jaje" + "id": "9evk17q5ozhen" } }, "AuditRowUpdateReq": { @@ -13981,7 +14051,7 @@ } }, "x-stoplight": { - "id": "t4l2bqjgukcr1" + "id": "gaksc2zunsxn3" } }, "Base": { @@ -14058,7 +14128,7 @@ } }, "x-stoplight": { - "id": "l5nhyvoa0dfag" + "id": "cjc1f3xdpuhn0" } }, "BaseList": { @@ -14160,7 +14230,7 @@ }, "required": ["list", "pageInfo"], "x-stoplight": { - "id": "pn96b18y3k0je" + "id": "ufkgy8ah526p9" } }, "BaseReq": { @@ -14216,7 +14286,7 @@ "title": "Base Request", "type": "object", "x-stoplight": { - "id": "gebxq2b5pp1a3" + "id": "ec2gzuidrzb05" } }, "Bool": { @@ -14238,7 +14308,7 @@ ], "title": "Bool Model", "x-stoplight": { - "id": "6qmxbfclxa8em" + "id": "ok0vakhbd76t7" } }, "Column": { @@ -14526,7 +14596,7 @@ } }, "x-stoplight": { - "id": "0nszsk1q6done" + "id": "57ep883sdtjxj" } }, "ColumnList": { @@ -14634,7 +14704,7 @@ }, "required": ["list", "pageInfo"], "x-stoplight": { - "id": "fjqsqgw1ahlon" + "id": "7nxvevdrdye9b" } }, "ColumnReq": { @@ -14726,7 +14796,7 @@ "title": "Column Request Model", "type": "object", "x-stoplight": { - "id": "fw6an7vvhpqfu" + "id": "5fibed0jjtlr8" } }, "CommentReq": { @@ -14759,13 +14829,13 @@ }, "required": ["fk_model_id", "row_id"], "x-stoplight": { - "id": "k7vnf7oc33p6m" + "id": "akpy6abwus2l2" } }, "CommentUpdateReq": { "description": "Model for Comment Update Request", "x-stoplight": { - "id": "wan84coiq9lyn" + "id": "icceq4bw1v0km" }, "examples": [ { @@ -14938,7 +15008,7 @@ "title": "Filter Model", "type": "object", "x-stoplight": { - "id": "goytqs4ua69w0" + "id": "bvrjq1rxu3nsp" } }, "FilterList": { @@ -15027,9 +15097,98 @@ }, "required": ["list", "pageInfo"], "x-stoplight": { - "id": "wzp2nwu7k19uj" + "id": "r6vkd94fyxozp" } }, + "FilterLogList": { + "description": "Model for Filter Log List", + "x-stoplight": { + "id": "fnkro33vma0hm" + }, + "examples": [ + { + "list": [ + { + "base_id": "ds_g4ccx6e77h1dmi", + "comparison_op": "eq", + "comparison_sub_op": null, + "created_at": "2023-03-02 18:18:05", + "fk_column_id": "cl_d7ah9n2qfupgys", + "fk_hook_id": null, + "fk_parent_id": null, + "fk_view_id": "vw_b739e29vqmrxnf", + "id": "fi_xn647tpmdq8fu8", + "is_group": null, + "logical_op": "and", + "order": 1, + "project_id": "p_xm3thidrblw4n7", + "updated_at": "2023-03-02 18:18:05", + "value": "foo" + } + ], + "pageInfo": { + "isFirstPage": true, + "isLastPage": true, + "page": 1, + "pageSize": 10, + "totalRows": 1 + } + } + ], + "title": "Filter Log List Model", + "type": "object", + "x-examples": { + "example-1": { + "bases": { + "list": [ + { + "alias": "string", + "database": "string", + "host": "string", + "id": "string", + "params": "string", + "password": "string", + "port": 0, + "project_id": "string", + "ssl": "string", + "type": "string", + "url": "string", + "username": "string" + } + ], + "pageInfo": { + "isFirstPage": true, + "isLastPage": true, + "pageSize": 0, + "sort": "string", + "totalRows": 0 + } + } + } + }, + "properties": { + "list": { + "type": "array", + "x-stoplight": { + "id": "22sgv37ve9kxo" + }, + "description": "List of filter objects", + "items": { + "$ref": "#/components/schemas/Filter", + "x-stoplight": { + "id": "ttw5rxhy83k8p" + } + } + }, + "pageInfo": { + "$ref": "#/components/schemas/Paginated", + "x-stoplight": { + "id": "7cyrb1770mrzz" + } + } + }, + "required": ["list", "pageInfo"] + }, "FilterReq": { "description": "Model for Filter Request", "examples": [ @@ -15045,7 +15204,7 @@ "title": "Filter Request Model", "type": "object", "x-stoplight": { - "id": "viq9ex4d7k8k2" + "id": "y84fnz0i7hbvs" }, "properties": { "comparison_op": { @@ -15266,7 +15425,7 @@ } }, "x-stoplight": { - "id": "bjh5qbmqyzy1k" + "id": "afkypb9o3rq26" } }, "FormUpdateReq": { @@ -15337,7 +15496,7 @@ } }, "x-stoplight": { - "id": "76m5jsz93rjsc" + "id": "m6bhkjsewt4ca" } }, "FormColumn": { @@ -15431,7 +15590,7 @@ } }, "x-stoplight": { - "id": "liiv7vd1hgeqf" + "id": "257zo728yca9v" } }, "FormColumnReq": { @@ -15498,7 +15657,7 @@ } }, "x-stoplight": { - "id": "21k1kvmq14s9a" + "id": "fkb1v0345thvk" } }, "Formula": { @@ -15539,7 +15698,7 @@ } }, "x-stoplight": { - "id": "8ahp8va0147v1" + "id": "vj4rcanzq3kfi" } }, "FormulaColumnReq": { @@ -15576,7 +15735,7 @@ } }, "x-stoplight": { - "id": "s3c9yjip3dank" + "id": "gnaln1acb43hm" } }, "Gallery": { @@ -15670,7 +15829,7 @@ "title": "Gallery Model", "type": "object", "x-stoplight": { - "id": "e1o8q9fieshbc" + "id": "a74prkhtnnyhm" } }, "GalleryColumn": { @@ -15705,13 +15864,13 @@ "title": "Gallery Column Model", "type": "object", "x-stoplight": { - "id": "llcstnvsjdgz0" + "id": "jvg5iiax5wl2w" } }, "GalleryUpdateReq": { "description": "Model for Gallery View Update Request", "x-stoplight": { - "id": "5cxhum5vh2nr2" + "id": "w9wics1pxeiut" }, "examples": [ { @@ -15764,7 +15923,7 @@ "title": "Geo Location Model", "type": "object", "x-stoplight": { - "id": "hwuzujovr9qwx" + "id": "hbtz74i4vhlpb" } }, "Grid": { @@ -15874,7 +16033,117 @@ } }, "x-stoplight": { - "id": "xntep33dod0ys" + "id": "536fsmtot3wyr" + } + }, + "Grid - copy": { + "description": "Model for Grid", + "x-stoplight": { + "id": "lu6lfh8g5zjcr" + }, + "examples": [ + { + "project_id": "p_xm3thidrblw4n7", + "base_id": "ds_g4ccx6e77h1dmi", + "fk_view_id": "vw_p2jcatxz4mvcfw", + "row_height": 1, + "meta": null, + "columns": [ + { + "id": "cl_phvuuwjrzcdo0g", + "base_id": "ds_g4ccx6e77h1dmi", + "project_id": "p_xm3thidrblw4n7", + "fk_model_id": "md_rsu68aqjsbyqtl", + "title": "Id", + "column_name": "id", + "uidt": "ID", + "dt": "int", + "np": "10", + "ns": "0", + "clen": null, + "cop": "1", + "pk": 1, + "pv": null, + "rqd": 1, + "un": 1, + "ct": "int unsigned", + "ai": 1, + "unique": 0, + "cdf": null, + "cc": "", + "csn": null, + "dtx": "specificType", + "dtxp": "", + "dtxs": "0", + "au": 0, + "validate": null, + "virtual": null, + "deleted": null, + "system": 0, + "order": 1, + "created_at": "2023-03-02 17:04:06", + "updated_at": "2023-03-02 17:04:06", + "meta": null + } + ] + } + ], + "title": "Grid Model", + "type": "object", + "properties": { + "id": { + "$ref": "#/components/schemas/Id", + "description": "Unique ID", + "x-stoplight": { + "id": "e3ti3fc0ocjyu" + } + }, + "project_id": { + "$ref": "#/components/schemas/Id", + "description": "Project ID", + "x-stoplight": { + "id": "e3ti3fc0ocjyu" + } + }, + "base_id": { + "$ref": "#/components/schemas/Id", + "description": "Base ID", + "x-stoplight": { + "id": "m8v3iyf1tidy9" + } + }, + "fk_view_id": { + "$ref": "#/components/schemas/Id", + "description": "Foreign Key to View", + "x-stoplight": { + "id": "m8v3iyf1tidy9" + } + }, + "row_height": { + "type": "number", + "example": 1, + "description": "Row Height" + }, + "meta": { + "$ref": "#/components/schemas/Meta", + "x-stoplight": { + "id": "n8cud3jyqw5yv" + }, + "description": "Meta info for Grid Model" + }, + "columns": { + "type": "array", + "x-stoplight": { + "id": "22y0gipx2jdf8" + }, + "description": "Grid View Columns", + "items": { + "$ref": "#/components/schemas/GridColumn", + "x-stoplight": { + "id": "nmzp6w3o6b24u" + } + } + } } }, "GridColumn": { @@ -15958,7 +16227,7 @@ } }, "x-stoplight": { - "id": "2go3w0igl2243" + "id": "f7xbsa3t5ct1x" } }, "GridColumnReq": { @@ -15996,13 +16265,13 @@ "title": "Grid Column Request Model", "type": "object", "x-stoplight": { - "id": "2j3uyoabzmsrz" + "id": "ulgt2hbbj9lxr" } }, "GridUpdateReq": { "description": "Model for Grid View Update", "x-stoplight": { - "id": "2q9ya4zmyr5x7" + "id": "yy9okqonhfj6u" }, "examples": [ { @@ -16122,13 +16391,13 @@ } }, "x-stoplight": { - "id": "q8cxkpronjmyx" + "id": "zge9ad0ftmp1b" } }, "HookReq": { "description": "Model for Hook", "x-stoplight": { - "id": "4zlzrppfjxrqb" + "id": "0zcc73h12ebop" }, "examples": [ { @@ -16306,90 +16575,166 @@ }, "required": ["list", "pageInfo"], "x-stoplight": { - "id": "2tsq8h6hjctju" + "id": "5metgdb0snm6t" } }, "HookLog": { "description": "Model for Hook Log", "examples": [ { - "base_id": "string", - "conditions": "string", - "error": "string", - "error_code": "string", - "error_message": "string", - "event": "string", - "execution_time": "string", - "fk_hook_id": "string", + "base_id": "ds_jxuewivwbxeum2", + "event": "after", + "execution_time": "98", + "fk_hook_id": "hk_035ijv5qdi97y5", "id": "string", - "notifications": "string", - "operation": "string", - "payload": null, - "project_id": "string", - "response": "string", - "test_call": true, - "triggered_by": "string", - "type": "string" + "notifications": "{\"type\":\"URL\",\"payload\":{\"method\":\"POST\",\"body\":\"{{ json data }}\",\"headers\":[{}],\"parameters\":[{}],\"auth\":\"\",\"path\":\"https://webhook.site/6eb45ce5-b611-4be1-8b96-c2965755662b\"}}", + "operation": "insert", + "payload": "{\"method\":\"POST\",\"body\":\"{{ json data }}\",\"headers\":[{}],\"parameters\":[{}],\"auth\":\"\",\"path\":\"https://webhook.site/6eb45ce5-b611-4be1-8b96-c2965755662b\"}", + "project_id": "p_tbhl1hnycvhe5l", + "response": "{\"status\":200,\"statusText\":\"OK\",\"headers\":{\"server\":\"nginx\",\"content-type\":\"text/plain; charset=UTF-8\",\"transfer-encoding\":\"chunked\",\"connection\":\"close\",\"vary\":\"Accept-Encoding\",\"x-request-id\":\"53844a7d-ede8-4798-adf7-8af441908a72\",\"x-token-id\":\"6eb45ce5-b611-4be1-8b96-c2965755662b\",\"cache-control\":\"no-cache, private\",\"date\":\"Fri, 24 Mar 2023 10:50:10 GMT\"},\"config\":{\"url\":\"https://webhook.site/6eb45ce5-b611-4be1-8b96-c2965755662b\",\"method\":\"post\",\"data\":\"{\\\"type\\\":\\\"records.after.insert\\\",\\\"id\\\":\\\"a77d97dc-a3e4-4719-9b46-45f93e0cc99a\\\",\\\"data\\\":{\\\"table_id\\\":\\\"md_d8v403o74mf5lf\\\",\\\"table_name\\\":\\\"Sheet-2\\\"}}\",\"headers\":{\"Accept\":\"application/json, text/plain, */*\",\"Content-Type\":\"application/x-www-form-urlencoded\",\"User-Agent\":\"axios/0.21.4\",\"Content-Length\":138},\"params\":{}}}", + "test_call": 0, + "triggered_by": "w@nocodb.com", + "type": "URL" } ], "title": "Hook Log Model", "type": "object", + "x-stoplight": { + "id": "2ecbvr0ha9nha" + }, "properties": { "base_id": { - "type": "string" + "type": "string", + "description": "Unique Base ID", + "example": "ds_jxuewivwbxeum2" }, "conditions": { - "type": "string" + "type": "string", + "description": "Hook Conditions" }, "error": { - "type": "string" + "$ref": "#/components/schemas/StringOrNull", + "description": "Error" }, "error_code": { - "type": "string" + "$ref": "#/components/schemas/StringOrNull", + "description": "Error Code" }, "error_message": { - "type": "string" + "$ref": "#/components/schemas/StringOrNull", + "description": "Error Message" }, "event": { - "type": "string" + "type": "string", + "description": "Hook Event", + "example": "after", + "enum": ["after", "before"] }, "execution_time": { - "type": "string" + "type": "string", + "description": "Execution Time in milliseconds", + "example": "98" }, "fk_hook_id": { - "$ref": "#/components/schemas/StringOrNull" + "$ref": "#/components/schemas/StringOrNull", + "description": "Foreign Key to Hook" }, "id": { - "$ref": "#/components/schemas/Id", + "$ref": "#/components/schemas/StringOrNull", "description": "Unique ID" }, "notifications": { - "type": "string" + "type": "string", + "description": "Hook Notification" }, "operation": { - "type": "string" + "type": "string", + "description": "Hook Operation", + "enum": ["insert", "update", "delete"], + "example": "insert" + }, + "payload": { + "type": "string", + "description": "Hook Payload", + "example": "{\"method\":\"POST\",\"body\":\"{{ json data }}\",\"headers\":[{}],\"parameters\":[{}],\"auth\":\"\",\"path\":\"https://webhook.site/6eb45ce5-b611-4be1-8b96-c2965755662b\"}" }, - "payload": {}, "project_id": { - "type": "string" + "type": "string", + "description": "Project ID", + "example": "p_tbhl1hnycvhe5l" }, "response": { - "type": "string" + "$ref": "#/components/schemas/StringOrNull", + "description": "Hook Response" }, "test_call": { - "$ref": "#/components/schemas/Bool" + "$ref": "#/components/schemas/Bool", + "description": "Is this testing hook call?" }, "triggered_by": { - "type": "string" + "$ref": "#/components/schemas/StringOrNull", + "description": "Who triggered the hook?" }, "type": { - "type": "string" + "type": "string", + "example": "URL", + "description": "Hook Type" } - }, - "x-stoplight": { - "id": "t3hlkw7zdqpom" } }, + "HookLogList": { + "description": "Model for Hook Log List", + "x-stoplight": { + "id": "upury390qrd53" + }, + "examples": [], + "title": "Hook Log List Model", + "type": "object", + "x-examples": { + "example-1": { + "bases": { + "list": [ + { + "alias": "string", + "database": "string", + "host": "string", + "id": "string", + "params": "string", + "password": "string", + "port": 0, + "project_id": "string", + "ssl": "string", + "type": "string", + "url": "string", + "username": "string" + } + ], + "pageInfo": { + "isFirstPage": true, + "isLastPage": true, + "pageSize": 0, + "sort": "string", + "totalRows": 0 + } + } + } + }, + "properties": { + "list": { + "minItems": 1, + "type": "array", + "uniqueItems": true, + "description": "List of hook objects", + "items": { + "$ref": "#/components/schemas/HookLog" + } + }, + "pageInfo": { + "$ref": "#/components/schemas/Paginated" + } + }, + "required": ["list", "pageInfo"] + }, "HookTestReq": { "description": "Model for Hook Test Request", "examples": [ @@ -16441,7 +16786,7 @@ }, "required": ["hook", "payload"], "x-stoplight": { - "id": "p2t60nmuy6x26" + "id": "t523aaetv4ouo" } }, "Id": { @@ -16452,7 +16797,7 @@ "title": "ID Model", "type": "string", "x-stoplight": { - "id": "srvzhcm5j7d65" + "id": "y6fmtic1d1shr" } }, "Kanban": { @@ -16519,7 +16864,7 @@ } }, "x-stoplight": { - "id": "1jq82nu2uugxr" + "id": "5r5zzs9a7ai64" } }, "KanbanColumn": { @@ -16592,7 +16937,7 @@ } }, "x-stoplight": { - "id": "ipigcz5c7b5qy" + "id": "pjk7pky2i6w7j" } }, "KanbanUpdateReq": { @@ -16669,7 +17014,7 @@ } }, "x-stoplight": { - "id": "ufp4dyqfvlk6a" + "id": "nzhwki0tq91mj" } }, "LicenseReq": { @@ -16691,7 +17036,7 @@ "title": "License Key Request Model", "type": "object", "x-stoplight": { - "id": "2hys6jqfbam2w" + "id": "2tr020jyvzaje" } }, "LinkToAnotherColumnReq": { @@ -16740,7 +17085,7 @@ "title": "LinkToAnotherColumn Request Model", "type": "object", "x-stoplight": { - "id": "nx1h0s2wseid0" + "id": "3x9fwotpk3vde" } }, "LinkToAnotherRecord": { @@ -16816,7 +17161,7 @@ "title": "LinkToAnotherRecord Model", "type": "object", "x-stoplight": { - "id": "845623nb0zp0w" + "id": "5m22fq1stz0bs" } }, "Lookup": { @@ -16856,7 +17201,7 @@ } }, "x-stoplight": { - "id": "22i9gmsgqt79n" + "id": "qhodn5h5sjbsz" } }, "LookupColumnReq": { @@ -16893,7 +17238,7 @@ } }, "x-stoplight": { - "id": "dhmss9g7ljbw7" + "id": "9cgn1ltvand3u" } }, "Map": { @@ -16970,13 +17315,13 @@ "title": "Map Model", "type": "object", "x-stoplight": { - "id": "2gkbn859ho3ct" + "id": "0g3zvgirw5kaz" } }, "MapUpdateReq": { "description": "Model for Map", "x-stoplight": { - "id": "u7xywz40dryws" + "id": "ulnej4ox46lau" }, "examples": [ { @@ -17051,7 +17396,7 @@ "title": "Map Column Model", "type": "object", "x-stoplight": { - "id": "ftaul6uruvc4z" + "id": "ymw6dfgts8s3q" } }, "Meta": { @@ -17070,7 +17415,7 @@ ], "title": "Meta Model", "x-stoplight": { - "id": "pqxyr0shwtrp5" + "id": "o5pfub7ud6bk6" } }, "ModelRoleVisibility": { @@ -17113,7 +17458,7 @@ "title": "ModelRoleVisibility Model", "type": "object", "x-stoplight": { - "id": "d3j1x4pulo4ng" + "id": "ep1wmfm8zzjw7" } }, "NormalColumnRequest": { @@ -17292,7 +17637,7 @@ "type": "object", "required": ["column_name"], "x-stoplight": { - "id": "uzaqliigop3nw" + "id": "e715zmc8glgpl" } }, "OrgUserReq": { @@ -17317,7 +17662,7 @@ "title": "Organisation User Request Model", "type": "object", "x-stoplight": { - "id": "pk8a8itnqcis1" + "id": "rgo441jq0x5ld" } }, "Paginated": { @@ -17359,7 +17704,7 @@ "title": "Paginated Model", "type": "object", "x-stoplight": { - "id": "a5zhehpll01cm" + "id": "695ek5fqx7l65" } }, "Password": { @@ -17370,7 +17715,7 @@ "title": "Password Model", "type": "string", "x-stoplight": { - "id": "mleq9lljoh76x" + "id": "juk25fjpj8jdk" } }, "PasswordChangeReq": { @@ -17394,7 +17739,7 @@ "title": "Password Change Request Model", "type": "object", "x-stoplight": { - "id": "8a21c5za82w87" + "id": "063yexshac0xr" } }, "PasswordForgotReq": { @@ -17415,7 +17760,7 @@ "title": "Password Forgot Request Model", "type": "object", "x-stoplight": { - "id": "ggt9lpf2gz2va" + "id": "vewwishkot5gy" } }, "PasswordResetReq": { @@ -17437,7 +17782,7 @@ "title": "Password Reset Request Model", "type": "object", "x-stoplight": { - "id": "f63x3tpb8ti9r" + "id": "juiq70hujawwd" } }, "Plugin": { @@ -17554,7 +17899,7 @@ } }, "x-stoplight": { - "id": "0atoct4o6csg1" + "id": "5tnitw91zxe22" } }, "PluginReq": { @@ -17578,7 +17923,7 @@ } }, "x-stoplight": { - "id": "w6jwfvgpbhmt0" + "id": "jwg0bw0jjvoz4" } }, "PluginTestReq": { @@ -17620,7 +17965,7 @@ }, "required": ["title", "input", "category"], "x-stoplight": { - "id": "yye6yekmme06k" + "id": "sfunw9hbi6eti" } }, "Project": { @@ -17710,7 +18055,7 @@ } }, "x-stoplight": { - "id": "xzqakuahxm8d1" + "id": "cokbbcuqg6ggf" } }, "ProjectList": { @@ -17806,7 +18151,7 @@ }, "required": ["list", "pageInfo"], "x-stoplight": { - "id": "rb5o2yaf8ue64" + "id": "37n1y48c6mfux" } }, "ProjectReq": { @@ -17859,13 +18204,13 @@ "title": "Project Request Model", "type": "object", "x-stoplight": { - "id": "km2fj1ebsroys" + "id": "gsxle49ts2t1m" } }, "ProjectUpdateReq": { "description": "Model for Project Update Request", "x-stoplight": { - "id": "ou8zri28ak9yl" + "id": "98gjamvw0ps9f" }, "examples": [ { @@ -17930,7 +18275,7 @@ }, "required": ["email", "roles"], "x-stoplight": { - "id": "9pgemwq7iirkp" + "id": "j8mnx42dkx0oo" } }, "Rollup": { @@ -17979,7 +18324,7 @@ } }, "x-stoplight": { - "id": "rq1o1yy2htfv0" + "id": "70tktm8p5ghjk" } }, "RollupColumnReq": { @@ -18030,7 +18375,7 @@ } }, "x-stoplight": { - "id": "8yc4ashgpj37h" + "id": "qtjqawfmifm16" } }, "SelectOption": { @@ -18072,7 +18417,7 @@ } }, "x-stoplight": { - "id": "sc5hl2s3rm8x7" + "id": "dpmp6frg1ns6q" } }, "SelectOptions": { @@ -18103,7 +18448,7 @@ }, "required": ["options"], "x-stoplight": { - "id": "r6d5rziqt288w" + "id": "nesh72pk907o9" } }, "SharedBaseReq": { @@ -18131,7 +18476,7 @@ } }, "x-stoplight": { - "id": "ybt81tfrpfvd2" + "id": "de0d2izgi3ssd" } }, "SharedView": { @@ -18169,7 +18514,7 @@ } ], "x-stoplight": { - "id": "9wxqjviu1tfd4" + "id": "kt8tyazx1hl9p" } }, "SharedViewList": { @@ -18263,7 +18608,7 @@ }, "required": ["list", "pageInfo"], "x-stoplight": { - "id": "jtlp6vswbc96e" + "id": "5af0r928phzi8" } }, "SharedViewReq": { @@ -18287,7 +18632,7 @@ } }, "x-stoplight": { - "id": "zja4lmiol065l" + "id": "7rn8w0bn6rj27" } }, "SignInReq": { @@ -18313,7 +18658,7 @@ "title": "Signin Request Model", "type": "object", "x-stoplight": { - "id": "2m1y6fuop0adc" + "id": "uuk84yov9ug31" } }, "SignUpReq": { @@ -18372,7 +18717,7 @@ }, "required": ["email", "password"], "x-stoplight": { - "id": "t7stkblz9wllz" + "id": "gcgfe08qwd747" } }, "Sort": { @@ -18425,7 +18770,7 @@ } }, "x-stoplight": { - "id": "tlcmtmjzcyhm6" + "id": "ia9gyblndemhc" } }, "SortList": { @@ -18506,7 +18851,7 @@ }, "required": ["list", "pageInfo"], "x-stoplight": { - "id": "7j3nbohh43tyy" + "id": "ufp0ghdiwrj7l" } }, "SortReq": { @@ -18532,7 +18877,7 @@ } }, "x-stoplight": { - "id": "shzdd8k3xswo9" + "id": "t6uwa7bvhea9w" } }, "StringOrNull": { @@ -18549,7 +18894,7 @@ ], "title": "StringOrNull Model", "x-stoplight": { - "id": "1lecfrpmnndhi" + "id": "mjdkmqlwnnpqa" } }, "Table": { @@ -18978,7 +19323,7 @@ }, "required": ["table_name", "title"], "x-stoplight": { - "id": "986a3bp33neka" + "id": "jbfaq3weq7pqu" } }, "TableList": { @@ -19108,7 +19453,7 @@ }, "required": ["list", "pageInfo"], "x-stoplight": { - "id": "gemdr6sjuj4gl" + "id": "q6831buusfkmr" } }, "TableReq": { @@ -19249,7 +19594,7 @@ "title": "Table Request Model", "type": "object", "x-stoplight": { - "id": "3i0r55tix0aso" + "id": "2778zbubk8oke" } }, "User": { @@ -19301,7 +19646,7 @@ }, "required": ["email", "email_verified", "firstname", "id", "lastname"], "x-stoplight": { - "id": "2uxbpdjvs379s" + "id": "j1eup2eblptjz" } }, "UserInfo": { @@ -19345,7 +19690,7 @@ "title": "User Info Model", "type": "object", "x-stoplight": { - "id": "uatcf3jcnna1t" + "id": "gh2ryk6eif3ow" } }, "UserList": { @@ -19426,7 +19771,7 @@ }, "required": ["list", "pageInfo"], "x-stoplight": { - "id": "ygjybmp21hdgp" + "id": "46tznvolzhh6f" } }, "View": { @@ -19540,7 +19885,7 @@ }, "required": ["fk_model_id", "show", "title", "type"], "x-stoplight": { - "id": "66ki9gaxq3kwg" + "id": "97nh4i07eyrac" } }, "ViewList": { @@ -19668,13 +20013,13 @@ }, "required": ["list", "pageInfo"], "x-stoplight": { - "id": "2iat5dhhl4hoa" + "id": "82hxym7ti79r2" } }, "ViewCreateReq": { "type": "object", "x-stoplight": { - "id": "venaxkw5uod3n" + "id": "1p0way06fnz8n" }, "title": "ViewCreateReq", "description": "Model for View Create Request", @@ -19743,7 +20088,7 @@ "ViewUpdateReq": { "description": "Model for View Update Request", "x-stoplight": { - "id": "bo1mzzdpk82z0" + "id": "astobhpdfnmob" }, "examples": [ { @@ -19808,7 +20153,7 @@ "ViewColumnUpdateReq": { "description": "Model for View Column Update Request", "x-stoplight": { - "id": "jmhr4prd02ssy" + "id": "9a3vtqvzn30xs" }, "examples": [ { @@ -19837,7 +20182,7 @@ "ViewColumnReq": { "description": "Model for View Column Request", "x-stoplight": { - "id": "05tr5rxotp432" + "id": "2cj4deea7o4zb" }, "examples": [ { @@ -19928,7 +20273,7 @@ "title": "Visibility Rule Request Model", "type": "array", "x-stoplight": { - "id": "c6q9v9rtiduxg" + "id": "49mghoeqaud3a" } } }, From 917c1804fcfc997aa26951e1fb58f76d9d1b8001 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 19:52:50 +0800 Subject: [PATCH 036/161] refactor(nocodb): revise event and operation types --- packages/nocodb/src/lib/models/HookLog.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/nocodb/src/lib/models/HookLog.ts b/packages/nocodb/src/lib/models/HookLog.ts index e88e26202b..b7d5231dde 100644 --- a/packages/nocodb/src/lib/models/HookLog.ts +++ b/packages/nocodb/src/lib/models/HookLog.ts @@ -6,13 +6,12 @@ import type { HookLogType } from 'nocodb-sdk'; export default class HookLog implements HookLogType { id?: string; - base_id?: string; project_id?: string; fk_hook_id?: string; type?: string; - event?: string; - operation?: string; + event?: 'after' | 'before'; + operation?: 'insert' | 'update' | 'delete'; test_call?: boolean; payload?: string; conditions?: string; From 13a05fc0c7a50e861df94f76c17811256cec11ca Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 19:53:03 +0800 Subject: [PATCH 037/161] chore(sdk): regenerate Api.ts --- packages/nocodb-sdk/src/lib/Api.ts | 129 ++++++++++++++++++++++++++--- 1 file changed, 118 insertions(+), 11 deletions(-) diff --git a/packages/nocodb-sdk/src/lib/Api.ts b/packages/nocodb-sdk/src/lib/Api.ts index be2fca8810..a3fa0b7e0e 100644 --- a/packages/nocodb-sdk/src/lib/Api.ts +++ b/packages/nocodb-sdk/src/lib/Api.ts @@ -622,6 +622,16 @@ export interface FilterListType { pageInfo: PaginatedType; } +/** + * Model for Filter Log List + */ +export interface FilterLogListType { + /** List of filter objects */ + list: FilterType[]; + /** Model for Paginated */ + pageInfo: PaginatedType; +} + /** * Model for Filter Request */ @@ -983,6 +993,29 @@ export interface GridType { columns?: GridColumnType[]; } +/** + * Model for Grid + */ +export interface GridCopyType { + /** Unique ID */ + id?: IdType; + /** Project ID */ + project_id?: IdType; + /** Base ID */ + base_id?: IdType; + /** Foreign Key to View */ + fk_view_id?: IdType; + /** + * Row Height + * @example 1 + */ + row_height?: number; + /** Meta info for Grid Model */ + meta?: MetaType; + /** Grid View Columns */ + columns?: GridColumnType[]; +} + /** * Model for Grid Column */ @@ -1181,28 +1214,73 @@ export interface HookListType { * Model for Hook Log */ export interface HookLogType { + /** + * Unique Base ID + * @example ds_jxuewivwbxeum2 + */ base_id?: string; + /** Hook Conditions */ conditions?: string; - error?: string; - error_code?: string; - error_message?: string; - event?: string; + /** Error */ + error?: StringOrNullType; + /** Error Code */ + error_code?: StringOrNullType; + /** Error Message */ + error_message?: StringOrNullType; + /** + * Hook Event + * @example after + */ + event?: 'after' | 'before'; + /** + * Execution Time in milliseconds + * @example 98 + */ execution_time?: string; - /** Model for StringOrNull */ + /** Foreign Key to Hook */ fk_hook_id?: StringOrNullType; /** Unique ID */ - id?: IdType; + id?: StringOrNullType; + /** Hook Notification */ notifications?: string; - operation?: string; - payload?: any; + /** + * Hook Operation + * @example insert + */ + operation?: 'insert' | 'update' | 'delete'; + /** + * Hook Payload + * @example {"method":"POST","body":"{{ json data }}","headers":[{}],"parameters":[{}],"auth":"","path":"https://webhook.site/6eb45ce5-b611-4be1-8b96-c2965755662b"} + */ + payload?: string; + /** + * Project ID + * @example p_tbhl1hnycvhe5l + */ project_id?: string; - response?: string; - /** Model for Bool */ + /** Hook Response */ + response?: StringOrNullType; + /** Is this testing hook call? */ test_call?: BoolType; - triggered_by?: string; + /** Who triggered the hook? */ + triggered_by?: StringOrNullType; + /** + * Hook Type + * @example URL + */ type?: string; } +/** + * Model for Hook Log List + */ +export interface HookLogListType { + /** List of hook objects */ + list: HookLogType[]; + /** Model for Paginated */ + pageInfo: PaginatedType; +} + /** * Model for Hook Test Request */ @@ -6397,6 +6475,35 @@ export class Api< ...params, }), }; + dbTableWebhookLogs = { + /** + * @description Get the log data in a given Hook + * + * @tags DB Table Webhook Logs + * @name List + * @summary Get Hook Logs + * @request GET:/api/v1/db/meta/hooks/{hookId}/logs + * @response `200` `HookLogListType` OK + * @response `400` `{ + \** @example BadRequest [Error]: *\ + msg: string, + +}` + */ + list: (hookId: IdType, params: RequestParams = {}) => + this.request< + HookLogListType, + { + /** @example BadRequest [Error]: */ + msg: string; + } + >({ + path: `/api/v1/db/meta/hooks/${hookId}/logs`, + method: 'GET', + format: 'json', + ...params, + }), + }; dbTableRow = { /** * @description List all table rows in a given table and project From 5359080d975f72470aa52377f4ebfb86321e37d0 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 24 Mar 2023 19:53:53 +0800 Subject: [PATCH 038/161] wip(nc-gui): CallLog component --- .../nc-gui/components/webhook/CallLog.vue | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 packages/nc-gui/components/webhook/CallLog.vue diff --git a/packages/nc-gui/components/webhook/CallLog.vue b/packages/nc-gui/components/webhook/CallLog.vue new file mode 100644 index 0000000000..34c2a44d4a --- /dev/null +++ b/packages/nc-gui/components/webhook/CallLog.vue @@ -0,0 +1,28 @@ + + + From 97600cf41c0dbda29e73322d677c525f0fdf8b4d Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Sat, 25 Mar 2023 12:25:49 +0800 Subject: [PATCH 039/161] feat(nocodb): add id to hook samplePayload --- packages/nocodb/src/lib/meta/helpers/populateSamplePayload.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/nocodb/src/lib/meta/helpers/populateSamplePayload.ts b/packages/nocodb/src/lib/meta/helpers/populateSamplePayload.ts index c92152a584..e598d4baea 100644 --- a/packages/nocodb/src/lib/meta/helpers/populateSamplePayload.ts +++ b/packages/nocodb/src/lib/meta/helpers/populateSamplePayload.ts @@ -1,4 +1,5 @@ import { RelationTypes, UITypes } from 'nocodb-sdk'; +import { v4 as uuidv4 } from 'uuid'; import View from '../../models/View'; import Column from '../../models/Column'; import Model from '../../models/Model'; @@ -31,6 +32,7 @@ export default async function populateSamplePayload( const samplePayload = { type: `${scope}.after.${operation}`, + id: uuidv4(), data: { table_id: model.id, table_name: model.title, From 8baf2fe42897fe38e57783c9083238445d66ff7f Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Sat, 25 Mar 2023 13:14:33 +0800 Subject: [PATCH 040/161] refactor(nc-gui): remove icon margin in webhook list --- packages/nc-gui/components/webhook/List.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nc-gui/components/webhook/List.vue b/packages/nc-gui/components/webhook/List.vue index f1063e062d..50efd053c4 100644 --- a/packages/nc-gui/components/webhook/List.vue +++ b/packages/nc-gui/components/webhook/List.vue @@ -135,7 +135,7 @@ onMounted(() => { \ No newline at end of file + From 7fa474e0a0eb4bf39d6320cbb588c33a28bff132 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Sat, 25 Mar 2023 14:28:46 +0800 Subject: [PATCH 044/161] feat(nc-gui): hook call log --- .../nc-gui/components/webhook/CallLog.vue | 58 +++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/packages/nc-gui/components/webhook/CallLog.vue b/packages/nc-gui/components/webhook/CallLog.vue index 34c2a44d4a..bb3e8fce26 100644 --- a/packages/nc-gui/components/webhook/CallLog.vue +++ b/packages/nc-gui/components/webhook/CallLog.vue @@ -1,6 +1,6 @@ + + From be7e4a514d8c5f249a11a09229ca1f0dbeb70668 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Sat, 25 Mar 2023 16:34:59 +0800 Subject: [PATCH 045/161] feat(nc-gui): revise hook call log style --- packages/nc-gui/components/webhook/CallLog.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nc-gui/components/webhook/CallLog.vue b/packages/nc-gui/components/webhook/CallLog.vue index bb3e8fce26..3e513d9985 100644 --- a/packages/nc-gui/components/webhook/CallLog.vue +++ b/packages/nc-gui/components/webhook/CallLog.vue @@ -31,7 +31,7 @@ onBeforeMount(async () => {
records.{{ hookLog.event }}.{{ hookLog.operation }} ({{ timeAgo(hookLog.created_at) }})
{{ parseProp(hookLog.response).status }} @@ -68,7 +68,7 @@ onBeforeMount(async () => {