Compare commits

...

1 commit

Author SHA1 Message Date
Krzysztof Wolski
60e673c07b WIP 2023-04-06 20:42:37 +02:00
4 changed files with 151 additions and 35 deletions

View file

@ -0,0 +1,119 @@
import { SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next";
import { Client, gql } from "urql";
import {
AppWebhooksDocument,
WebhookCreateDocument,
WebhookDeleteDocument,
} from "../../generated/graphql";
import { invoiceSentWebhook } from "../pages/api/webhooks/invoice-sent";
const WebhookDetails = gql`
fragment WebhookDetails on Webhook {
id
isActive
name
}
`;
const WebhookCreateMutation = gql`
${WebhookDetails}
mutation WebhookCreate($input: WebhookCreateInput!) {
webhookCreate(input: $input) {
webhook {
...WebhookDetails
}
errors {
field
message
}
}
}
`;
const AppWebhooksQuery = gql`
query AppWebhooks {
app {
webhooks {
id
name
}
}
}
`;
const WebhookDeleteMutation = gql`
mutation WebhookDelete($id: ID!) {
webhookDelete(id: $id) {
errors {
field
message
}
}
}
`;
export const setupWebhooks = async (client: Client, configurationID: string) => {
const eventName = "INVOICE_SENT";
const newWebhook = await createWebhookMutate(client, {});
};
export const createWebhookMutate = async (client: Client, webhook: SaleorAsyncWebhook) => {
// TODO: The base URL should be configurable
const manifest = invoiceSentWebhook.getWebhookManifest("https://example.com");
const { error, data } = await client
.mutation(WebhookCreateDocument, {
input: {
name: manifest.name,
targetUrl: manifest.targetUrl,
isActive: true,
},
})
.toPromise();
if (error || data?.webhookCreate?.errors?.length) {
throw new Error("Could not create webhook");
}
return data?.webhookCreate?.webhook;
};
export const deleteWebhookMutate = async (client: Client, webhookId: string) => {
const { error, data } = await client
.mutation(WebhookDeleteDocument, {
id: webhookId,
})
.toPromise();
if (error || data?.webhookDelete?.errors?.length) {
throw new Error("Could not delete webhook");
}
return;
};
// export const updateWebhook = async (client: Client, webhook: SaleorAsyncWebhook) => {
// const { error, data } = await client
// .mutation(UpdateWebhookDocument, {
// id: webhook.id,
// input: webhook,
// })
// .toPromise();
// if (error) {
// throw new Error("Could not update webhook");
// }
// return data?.webhookUpdate?.webhook;
// };
export const getAllWebhooks = async (client: Client) => {
const { error, data } = await client.query(AppWebhooksDocument, {}).toPromise();
if (error) {
throw new Error("Could not fetch webhooks");
}
return data?.app?.webhooks;
};

View file

@ -12,6 +12,7 @@ import { SendgridConfigurationService } from "./get-sendgrid-configuration.servi
import { router } from "../../trpc/trpc-server";
import { protectedClientProcedure } from "../../trpc/protected-client-procedure";
import { TRPCError } from "@trpc/server";
import { createWebhookMutate, deleteWebhookMutate, getAllWebhooks } from "../../../lib/webhooks";
// Allow access only for the dashboard users and attaches the
// configuration service to the context
@ -57,6 +58,21 @@ export const sendgridConfigurationRouter = router({
logger.debug(input, "sendgridConfigurationRouter.create called");
return await ctx.configurationService.createConfiguration(input);
}),
createWebhook: protectedWithConfigurationService
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
// .input(sendgridCreateConfigurationSchema)
.mutation(async ({ ctx, input }) => {
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "create webhook called");
const r = await getAllWebhooks(ctx.apiClient);
if (!r?.length) {
console.log("None found");
return;
}
const lastHook = r[r.length - 1];
const r2 = await deleteWebhookMutate(ctx.apiClient, lastHook.id);
return;
}),
deleteConfiguration: protectedWithConfigurationService
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(sendgridDeleteConfigurationInputSchema)

View file

@ -303,40 +303,6 @@ export const SendgridConfigurationForm = (props: Props) => {
</Typography>
)}
</FormControl>
<Controller
name="senderName"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
label="Sender name"
disabled={true}
error={!!error}
helperText={error?.message}
value={value}
onChange={onChange}
{...CommonFieldProps}
/>
)}
/>
<Controller
name="senderEmail"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<>
<TextField
label="Sender email"
value={value}
disabled={true}
helperText={error?.message}
error={!!error}
onChange={onChange}
{...CommonFieldProps}
/>
</>
)}
/>
</>
)}
<Button type="submit" fullWidth variant="primary">

View file

@ -1,6 +1,8 @@
import { Link, Paper, Typography } from "@material-ui/core";
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
import { makeStyles } from "@saleor/macaw-ui";
import { Button, makeStyles } from "@saleor/macaw-ui";
import { useQuery } from "@tanstack/react-query";
import { trpcClient } from "../../../trpc/trpc-client";
const useStyles = makeStyles((theme) => {
return {
@ -10,6 +12,18 @@ const useStyles = makeStyles((theme) => {
};
});
const TestButton = () => {
const { mutate } = trpcClient.sendgridConfiguration.createWebhook.useMutation({
onSuccess: () => {
console.log("success");
},
onError: (err) => {
console.log("error", err);
},
});
return <button onClick={() => mutate()}>Test</button>;
};
export const SendgridInstructions = () => {
const styles = useStyles();
@ -17,6 +31,7 @@ export const SendgridInstructions = () => {
return (
<Paper elevation={0} className={styles.instructionsContainer}>
<TestButton />
<Typography paragraph variant="h4">
Sendgrid Provider
</Typography>