From 4cbd4308152cd40d3ba2e26f9efc9e554017bd7a Mon Sep 17 00:00:00 2001 From: surajmn1 Date: Tue, 4 Oct 2022 11:46:22 +0530 Subject: [PATCH 01/10] update webhook logs route --- server/service/core/action/webhook/route.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/service/core/action/webhook/route.go b/server/service/core/action/webhook/route.go index 171617757..b799c6782 100644 --- a/server/service/core/action/webhook/route.go +++ b/server/service/core/action/webhook/route.go @@ -22,8 +22,8 @@ func Router() chi.Router { r.With(util.CheckKetoPolicy(entity, "get")).Get("/", list) r.With(util.CheckKetoPolicy(entity, "create")).Post("/", create) - r.With(util.CheckKetoPolicy(entity, "get")).Get("/logs", logs) r.Route("/{webhook_id}", func(r chi.Router) { + r.With(util.CheckKetoPolicy(entity, "get")).Get("/logs", logs) r.With(util.CheckKetoPolicy(entity, "get")).Get("/", details) r.With(util.CheckKetoPolicy(entity, "update")).Put("/", update) r.With(util.CheckKetoPolicy(entity, "delete")).Delete("/", delete) From 3d62abf4de153c1f4a017c6f70dde92284320047 Mon Sep 17 00:00:00 2001 From: surajmn1 Date: Tue, 4 Oct 2022 11:47:49 +0530 Subject: [PATCH 02/10] fetch logs by spaceId and webhookId --- server/service/core/action/webhook/logs.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/server/service/core/action/webhook/logs.go b/server/service/core/action/webhook/logs.go index 4a8886a02..292e3e757 100644 --- a/server/service/core/action/webhook/logs.go +++ b/server/service/core/action/webhook/logs.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "strconv" "github.com/factly/dega-server/service/core/model" "github.com/factly/x/errorx" @@ -11,6 +12,7 @@ import ( "github.com/factly/x/middlewarex" "github.com/factly/x/renderx" "github.com/factly/x/requestx" + "github.com/go-chi/chi" "github.com/spf13/viper" ) @@ -32,6 +34,15 @@ type logPaging struct { // @Success 200 {object} paging // @Router /core/webhooks/logs [get] func logs(w http.ResponseWriter, r *http.Request) { + webhookID := chi.URLParam(r, "webhook_id") + wID, err := strconv.Atoi(webhookID) + + if err != nil { + loggerx.Error(err) + errorx.Render(w, errorx.Parser(errorx.InvalidID())) + return + } + uID, err := middlewarex.GetUser(r.Context()) if err != nil { loggerx.Error(err) @@ -46,7 +57,7 @@ func logs(w http.ResponseWriter, r *http.Request) { return } - hukzURL := viper.GetString("hukz_url") + "/webhooks/logs?tag=app:dega&tag=space:" + fmt.Sprint(sID) + "&limit=" + r.URL.Query().Get("limit") + "&page=" + r.URL.Query().Get("page") + hukzURL := viper.GetString("hukz_url") + "/webhooks/space/" + fmt.Sprint(sID) + "/webhook/" + fmt.Sprint(wID) + "/logs?tag=app:dega&tag=space:" + fmt.Sprint(sID) + "&limit=" + r.URL.Query().Get("limit") + "&page=" + r.URL.Query().Get("page") resp, err := requestx.Request("GET", hukzURL, nil, map[string]string{ "X-User": fmt.Sprint(uID), From a3c0aced5a49a221e691964038d674e432b746ee Mon Sep 17 00:00:00 2001 From: surajmn1 Date: Tue, 4 Oct 2022 11:48:36 +0530 Subject: [PATCH 03/10] added reducer for webhook logs --- studio/src/reducers/webhooklogsReducer.js | 51 +++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 studio/src/reducers/webhooklogsReducer.js diff --git a/studio/src/reducers/webhooklogsReducer.js b/studio/src/reducers/webhooklogsReducer.js new file mode 100644 index 000000000..b05fae570 --- /dev/null +++ b/studio/src/reducers/webhooklogsReducer.js @@ -0,0 +1,51 @@ +import { + ADD_WEBHOOKLOG, + ADD_WEBHOOKLOGS, + ADD_WEBHOOKLOGS_REQUEST, + SET_WEBHOOKLOGS_LOADING, + RESET_WEBHOOKLOGS, +} from '../constants/webhooklogs'; +import deepEqual from 'deep-equal'; + +const initialState = { + req: [], + details: {}, + loading: true, +}; + +export default function webhooklogsReducer(state = initialState, action = {}) { + switch (action.type) { + case RESET_WEBHOOKLOGS: + return { + ...state, + req: [], + details: {}, + loading: true, + }; + case SET_WEBHOOKLOGS_LOADING: + return { + ...state, + loading: action.payload, + }; + case ADD_WEBHOOKLOGS_REQUEST: + return { + ...state, + req: state.req + .filter((value) => !deepEqual(value.query, action.payload.query)) + .concat(action.payload), + }; + case ADD_WEBHOOKLOGS: + if (action.payload.length === 0) { + return state; + } + return { + ...state, + details: { + ...state.details, + ...action?.payload?.reduce((obj, item) => Object.assign(obj, { [item.id]: item }), {}), + }, + }; + default: + return state; + } +} From b33418d6a2637734ae2ca82552e9ff4b35e0fb59 Mon Sep 17 00:00:00 2001 From: surajmn1 Date: Tue, 4 Oct 2022 11:49:37 +0530 Subject: [PATCH 04/10] added constants for webhook logs --- studio/src/constants/webhooklogs.js | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 studio/src/constants/webhooklogs.js diff --git a/studio/src/constants/webhooklogs.js b/studio/src/constants/webhooklogs.js new file mode 100644 index 000000000..64cc3d3be --- /dev/null +++ b/studio/src/constants/webhooklogs.js @@ -0,0 +1,6 @@ +//Actions +export const ADD_WEBHOOKLOG = 'ADD_WEBHOOKLOG'; +export const ADD_WEBHOOKLOGS = 'ADD_WEBHOOKLOGS'; +export const ADD_WEBHOOKLOGS_REQUEST = 'ADD_WEBHOOKLOGS_REQUEST'; +export const RESET_WEBHOOKLOGS = 'RESET_WEBHOOKLOGS'; +export const SET_WEBHOOKLOGS_LOADING = 'SET_WEBHOOKLOGS_LOADING'; \ No newline at end of file From fa3f77d6510fea0ea087777d6c76b681ad2e03a6 Mon Sep 17 00:00:00 2001 From: surajmn1 Date: Tue, 4 Oct 2022 11:49:57 +0530 Subject: [PATCH 05/10] added actions for webhooklogs --- studio/src/actions/webhooklogs.js | 55 +++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 studio/src/actions/webhooklogs.js diff --git a/studio/src/actions/webhooklogs.js b/studio/src/actions/webhooklogs.js new file mode 100644 index 000000000..017050346 --- /dev/null +++ b/studio/src/actions/webhooklogs.js @@ -0,0 +1,55 @@ +import axios from 'axios'; +import { + ADD_WEBHOOKLOGS, + ADD_WEBHOOKLOGS_REQUEST, + SET_WEBHOOKLOGS_LOADING, + RESET_WEBHOOKLOGS, +} from '../constants/webhooklogs'; +import { addErrorNotification, addSuccessNotification } from './notifications'; +import { addEvents } from './events'; +import getError from '../utils/getError'; +import { WEBHOOKS_API } from '../constants/webhooks'; + +export const getWebhooklogs = (id, query) => { + return (dispatch) => { + dispatch(loadingWebhookLogs()); + return axios + .get(WEBHOOKS_API + '/' + id + '/logs', { + params: query, + }) + .then((response) => { + dispatch(addWebhooklogList(response.data.nodes)); + dispatch( + addWebhookRequest({ + data: response.data.nodes.map((item) => item.id), + query: query, + total: response.data.total, + }), + ); + }) + .catch((error) => { + dispatch(addErrorNotification(getError(error))); + }) + .finally(() => dispatch(stopWebhookLogsLoading())); + }; +}; + +export const loadingWebhookLogs = () => ({ + type: SET_WEBHOOKLOGS_LOADING, + payload: true, +}); +export const stopWebhookLogsLoading = () => ({ + type: SET_WEBHOOKLOGS_LOADING, + payload: false, +}); +export const addWebhooklogList = (data) => ({ + type: ADD_WEBHOOKLOGS, + payload: data, +}); +export const addWebhookRequest = (data) => ({ + type: ADD_WEBHOOKLOGS_REQUEST, + payload: data, +}); +export const resetWebhooks = () => ({ + type: RESET_WEBHOOKLOGS, +}); \ No newline at end of file From 7eec9d25febcae2ad56f392a8654f16adafa84ad Mon Sep 17 00:00:00 2001 From: surajmn1 Date: Tue, 4 Oct 2022 11:53:34 +0530 Subject: [PATCH 06/10] added components for webhook logs --- .../webhooklogs/components/WebhookLogsList.js | 39 +++++++++++++++ .../src/pages/webhooks/webhooklogs/index.js | 48 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 studio/src/pages/webhooks/webhooklogs/components/WebhookLogsList.js create mode 100644 studio/src/pages/webhooks/webhooklogs/index.js diff --git a/studio/src/pages/webhooks/webhooklogs/components/WebhookLogsList.js b/studio/src/pages/webhooks/webhooklogs/components/WebhookLogsList.js new file mode 100644 index 000000000..3e5c1ba65 --- /dev/null +++ b/studio/src/pages/webhooks/webhooklogs/components/WebhookLogsList.js @@ -0,0 +1,39 @@ +import React from 'react'; +import { Table } from 'antd'; +import { getEventName } from '../../../../utils/event'; +import { getDateAndTimeFromString } from '../../../../utils/date'; +function WebhookLogsList({data, filters, setFilters}) { + const columns = [ + { + title: 'Event', + dataIndex: 'event', + key: 'event', + render: (_, record) => getEventName(record.event) + }, + { + title: 'Time', + dataIndex: 'created_at', + key: 'created_at', + render: (_, record) => getDateAndTimeFromString(record.created_at) + } + ]; + + return ( + setFilters({ page: pageNumber, limit: pageSize }), + pageSizeOptions: ['10', '15', '20'], + }} + /> + ); +} + +export default WebhookLogsList; diff --git a/studio/src/pages/webhooks/webhooklogs/index.js b/studio/src/pages/webhooks/webhooklogs/index.js new file mode 100644 index 000000000..186ec00f5 --- /dev/null +++ b/studio/src/pages/webhooks/webhooklogs/index.js @@ -0,0 +1,48 @@ +import React from 'react'; +import { Space } from 'antd'; +import { useDispatch, useSelector } from 'react-redux'; +import deepEqual from 'deep-equal'; +import { getWebhooklogs } from '../../../actions/webhooklogs'; +import WebhookLogsList from './components/WebhookLogsList'; + +function Webhooklogs({WebhookId}) { + const spaces = useSelector(({ spaces }) => spaces); + const dispatch = useDispatch(); + const [filters, setFilters] = React.useState({ + page: 1, + limit: 20, + }); + const { webhooklogs, total, loading } = useSelector((state) => { + const node = state.webhooklogs.req.find((item) => { + return deepEqual(item.query, filters); + }); + if (node) + return { + webhooklogs: node.data.map((element) => state.webhooklogs.details[element]), + total: node.total, + loading: state.webhooks.loading, + }; + return { webhooklogs: [], total: 0, loading: state.webhooklogs.loading }; + }); + React.useEffect(() => { + fetchWebhooklogs(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [filters]); + + const fetchWebhooklogs = () => { + dispatch(getWebhooklogs(WebhookId,filters)); + }; + + return ( + + + + ); +} + +export default Webhooklogs; From 056e3ed8faa49a496b853b06ac8d4fa879447717 Mon Sep 17 00:00:00 2001 From: surajmn1 Date: Tue, 4 Oct 2022 11:54:17 +0530 Subject: [PATCH 07/10] added webhook logs list --- studio/src/pages/webhooks/EditWebhook.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/studio/src/pages/webhooks/EditWebhook.js b/studio/src/pages/webhooks/EditWebhook.js index 96a4412d8..47dccf78d 100644 --- a/studio/src/pages/webhooks/EditWebhook.js +++ b/studio/src/pages/webhooks/EditWebhook.js @@ -4,9 +4,10 @@ import { useDispatch, useSelector } from 'react-redux'; import { updateWebhook, getWebhook } from '../../actions/webhooks'; import { useHistory } from 'react-router-dom'; import { useParams } from 'react-router-dom'; -import { Skeleton } from 'antd'; +import { Skeleton , Row , Col } from 'antd'; import RecordNotFound from '../../components/ErrorsAndImage/RecordNotFound'; import { Helmet } from 'react-helmet'; +import Webhooklogs from './webhooklogs'; function EditWebhook() { const history = useHistory(); @@ -37,7 +38,10 @@ function EditWebhook() { return ( <> - + + + + ); } From beac7d79ae09027dcad7af6100750c644f8ed97c Mon Sep 17 00:00:00 2001 From: surajmn1 Date: Tue, 4 Oct 2022 11:55:17 +0530 Subject: [PATCH 08/10] css changes to include webhook logs and refactor --- .../pages/webhooks/components/WebhookForm.js | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/studio/src/pages/webhooks/components/WebhookForm.js b/studio/src/pages/webhooks/components/WebhookForm.js index f3c810564..2a559ecd4 100644 --- a/studio/src/pages/webhooks/components/WebhookForm.js +++ b/studio/src/pages/webhooks/components/WebhookForm.js @@ -3,15 +3,8 @@ import { Button, Form, Input, Space, Switch, Checkbox, Row, Col } from 'antd'; import { useDispatch, useSelector } from 'react-redux'; import { getEvents } from '../../../actions/events'; import deepEqual from 'deep-equal'; +import { getEventName } from '../../../utils/event'; -const layout = { - labelCol: { - span: 8, - }, - wrapperCol: { - span: 10, - }, -}; const tailLayout = { wrapperCol: { offset: 10, @@ -19,13 +12,21 @@ const tailLayout = { }, }; -const buttonLayout = { - wrapperCol: { - offset: 2, - span: 10, - }, -}; const WebhookForm = ({ onCreate, data = {} }) => { + const layout = { + labelCol: { + span: data?.id ? 5 : 8, + }, + wrapperCol: { + span: 10, + }, + }; + const buttonLayout = { + wrapperCol: { + offset: data?.id ? 1 : 2, + span: 10, + }, + }; const [form] = Form.useForm(); const [valueChange, setValueChange] = React.useState(false); const dispatch = useDispatch(); @@ -62,13 +63,6 @@ const WebhookForm = ({ onCreate, data = {} }) => { const fetchEvents = () => { dispatch(getEvents(filters)); }; - const getEventName = (eventLabel) => { - var labelArr = eventLabel.split('.'); - for (var i = 0; i < labelArr.length; i++) { - labelArr[i] = labelArr[i][0].toUpperCase() + labelArr[i].slice(1); - } - return labelArr.join(' '); - }; if (events) { return (
{ {...buttonLayout} style={{ display: 'flex', - justifyContent: 'center', + justifyContent: 'space-around', alignItems: 'center', }} > From 87cc9d24fbb0c65620517f8eeca48988c9373b70 Mon Sep 17 00:00:00 2001 From: surajmn1 Date: Tue, 4 Oct 2022 11:56:58 +0530 Subject: [PATCH 09/10] add webhook logs reducer --- studio/src/reducers/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/studio/src/reducers/index.js b/studio/src/reducers/index.js index 2bf0e435a..eed63fe93 100644 --- a/studio/src/reducers/index.js +++ b/studio/src/reducers/index.js @@ -34,6 +34,7 @@ import profile from './profileReducer'; import search from './searchReducer'; import sachFactChecks from './sachFactChecksReducer'; import roles from './rolesReducer'; +import webhooklogs from './webhooklogsReducer'; const appReducer = combineReducers({ admin, @@ -66,6 +67,7 @@ const appReducer = combineReducers({ sidebar, events, webhooks, + webhooklogs, profile, search, sachFactChecks, From 8785c9c6bc268da40c1203a641f3fde2a9c553ed Mon Sep 17 00:00:00 2001 From: surajmn1 Date: Tue, 4 Oct 2022 11:57:41 +0530 Subject: [PATCH 10/10] add util functions --- studio/src/utils/date.js | 2 ++ studio/src/utils/event.js | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 studio/src/utils/event.js diff --git a/studio/src/utils/date.js b/studio/src/utils/date.js index 71ea06c52..c2fba7cb8 100644 --- a/studio/src/utils/date.js +++ b/studio/src/utils/date.js @@ -9,3 +9,5 @@ export const getDatefromStringWithoutDay = (dateString) => { const dateObj = new Date(Date.parse(dateString)); return `${listOfMonths[dateObj.getMonth()]} ${dateObj.getDate()} ${dateObj.getFullYear()}`; }; + +export const getDateAndTimeFromString = (dateString) => new Date(dateString).toLocaleString().replaceAll(",","").replaceAll("/","-") \ No newline at end of file diff --git a/studio/src/utils/event.js b/studio/src/utils/event.js new file mode 100644 index 000000000..393b08429 --- /dev/null +++ b/studio/src/utils/event.js @@ -0,0 +1,7 @@ +export const getEventName = (eventLabel) => { + var labelArr = eventLabel.split('.'); + for (var i = 0; i < labelArr.length; i++) { + labelArr[i] = labelArr[i][0].toUpperCase() + labelArr[i].slice(1); + } + return labelArr.join(' '); + }; \ No newline at end of file