-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathWebhookList.component.tsx
174 lines (159 loc) · 4.19 KB
/
WebhookList.component.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import React, { useContext, useEffect, useMemo } from "react";
import { gql, useQuery } from "@apollo/client";
import Emptystate from "./EmptyState.component";
import { WebhookPage } from "./WebhookPage.component";
import {
Column,
usePagination,
UsePaginationState,
useTable,
} from "react-table";
import { forwardWebhookToLocalhost } from "../forward-to-localhost";
import posthog from "posthog-js";
import { WebhookContext } from "../NavBar/WebhookContext/WebhookContext";
import { UpdateQueryFn } from "@apollo/client/core/watchQueryOptions";
const largePayloadCellStyle: React.CSSProperties = {
minWidth: 200,
maxWidth: 300,
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
};
export type Webhook = {
id: string;
path: string;
body: string;
headers: string;
receivedAt: string;
};
const QUERY_WEBHOOKS = gql`
query Webhooks($first: Int!, $path: String) {
webhooks(first: $first, path: $path) {
id
path
body
headers
receivedAt
}
}
`;
type QueryWebhook = {
webhooks: Array<Webhook> | null;
};
const useBuildColumns = (data: QueryWebhook | undefined) =>
React.useMemo<Column<Webhook>[]>(
() => [
{
Header: "Id",
accessor: (webhook: Webhook) => webhook.id.substring(0, 11),
title: "Id",
style: { minWidth: "140px" },
},
{
Header: "Path",
accessor: (webhook: Webhook) => webhook.path,
title: "Path",
style: largePayloadCellStyle,
},
{
Header: "Body",
accessor: (webhook: Webhook) => webhook.body,
title: "Body",
style: largePayloadCellStyle,
},
{
Header: "Received at",
accessor: (webhook: Webhook) =>
new Date(webhook.receivedAt).toLocaleString(),
title: "Received at",
style: { minWidth: "180px" },
},
],
[data]
);
const useBuildTable = (data: QueryWebhook | undefined) => {
const columns = useBuildColumns(data);
const orderedWebhooks = useMemo(() => {
return (
data?.webhooks?.slice().sort((a, b) => {
return Number(b.id) - Number(a.id);
}) || []
);
}, [data]);
const initialState: UsePaginationState<Webhook> = {
pageSize: 15,
pageIndex: 0,
};
const table = useTable(
{
columns,
data: orderedWebhooks,
// @ts-ignore
initialState,
},
usePagination
);
return { table, orderedWebhooks };
};
const subscribeToMoreUpdateQuery =
(path: string | undefined): UpdateQueryFn =>
(prev, { subscriptionData }): QueryWebhook => {
const baseUrl = "http://localhost:8010/proxy";
if (!subscriptionData.data) {
return prev;
}
if (path && subscriptionData.data.webhookAdded.path != path) {
return prev;
}
const newWebhook = subscriptionData.data.webhookAdded;
try {
void forwardWebhookToLocalhost(baseUrl, newWebhook);
} catch (err) {
console.error(err);
}
posthog.capture("New webhook received", { webhookId: newWebhook.id });
return Object.assign({}, prev, {
webhooks: [newWebhook, ...(prev.webhooks || [])],
});
};
const COMMENTS_SUBSCRIPTION = gql`
subscription WebhookAdded {
webhookAdded {
id
path
body
headers
receivedAt
}
}
`;
type SubscriptionWebhook = {
webhookAdded: Webhook;
};
const WebhookList: React.FC = () => {
const path = useMemo(
() =>
window.location.pathname === "/" ? undefined : window.location.pathname,
[window.location.pathname]
);
const { data, subscribeToMore } = useQuery<QueryWebhook>(QUERY_WEBHOOKS, {
variables: { first: 100, path },
});
const { webhookStoreUrl } = useContext(WebhookContext);
useEffect(() => {
const unsuscribe = subscribeToMore<SubscriptionWebhook>({
document: COMMENTS_SUBSCRIPTION,
updateQuery: subscribeToMoreUpdateQuery(path),
});
return () => {
unsuscribe();
};
}, [subscribeToMore]);
const { table, orderedWebhooks } = useBuildTable(data);
return orderedWebhooks && orderedWebhooks.length > 0 ? (
<WebhookPage webhooks={orderedWebhooks} table={table} />
) : (
<Emptystate webhookStoreUrl={webhookStoreUrl} />
);
};
export default WebhookList;