From 6b063dba3d9edc15622819da0539052b2e531cdb Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Mon, 29 Nov 2021 14:37:36 +1100 Subject: [PATCH 01/10] fix webhooks, extensions styling --- package.json | 1 - .../Extensions/AddExtensionButton.tsx | 83 ++++ .../TableHeader/Extensions/ExtensionList.tsx | 323 ++++++--------- .../TableHeader/Extensions/index.tsx | 60 ++- .../TableHeader/Webhooks/AddWebhookButton.tsx | 83 ++++ .../TableHeader/Webhooks/WebhookList.tsx | 375 +++++++----------- src/components/TableHeader/Webhooks/index.tsx | 59 +-- src/contexts/ProjectContext.tsx | 11 +- 8 files changed, 483 insertions(+), 512 deletions(-) create mode 100644 src/components/TableHeader/Extensions/AddExtensionButton.tsx create mode 100644 src/components/TableHeader/Webhooks/AddWebhookButton.tsx diff --git a/package.json b/package.json index 7c61dd52..7161e2e9 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,6 @@ "react-router-hash-link": "^2.4.3", "react-scripts": "^4.0.3", "react-usestateref": "^1.0.5", - "semver": "^7.3.5", "serve": "^11.3.2", "swr": "^1.0.1", "tinymce": "^5.9.2", diff --git a/src/components/TableHeader/Extensions/AddExtensionButton.tsx b/src/components/TableHeader/Extensions/AddExtensionButton.tsx new file mode 100644 index 00000000..6d4f43e7 --- /dev/null +++ b/src/components/TableHeader/Extensions/AddExtensionButton.tsx @@ -0,0 +1,83 @@ +import { useRef, useState } from "react"; + +import { + Button, + ButtonProps, + Menu, + MenuItem, + Divider, + ListItemIcon, +} from "@mui/material"; +import AddIcon from "@mui/icons-material/Add"; +import EmailIcon from "@mui/icons-material/EmailOutlined"; + +import { extensionTypes, extensionNames, ExtensionType } from "./utils"; +import { EMAIL_REQUEST } from "@src/constants/externalLinks"; + +export interface IAddExtensionButtonProps extends Partial { + handleAddExtension: (type: ExtensionType) => void; +} + +export default function AddExtensionButton({ + handleAddExtension, + ...props +}: IAddExtensionButtonProps) { + const addButtonRef = useRef(null); + const [open, setOpen] = useState(false); + + const handleChooseAddType = (type: ExtensionType) => { + setOpen(false); + handleAddExtension(type); + }; + + return ( + <> + + + setOpen(false)} + anchorOrigin={{ vertical: "bottom", horizontal: "right" }} + transformOrigin={{ vertical: "top", horizontal: "right" }} + > + {extensionTypes.map((type) => ( + handleChooseAddType(type)}> + {extensionNames[type]} + + ))} + + + + + + + + Request new Extension… + + + + ); +} diff --git a/src/components/TableHeader/Extensions/ExtensionList.tsx b/src/components/TableHeader/Extensions/ExtensionList.tsx index e85c04fd..8dd858b2 100644 --- a/src/components/TableHeader/Extensions/ExtensionList.tsx +++ b/src/components/TableHeader/Extensions/ExtensionList.tsx @@ -1,43 +1,27 @@ -import { useState, useRef } from "react"; import { format, formatRelative } from "date-fns"; import { Stack, - ButtonBase, List, ListItem, ListItemText, Avatar, - Button, IconButton, - Menu, - MenuItem, - Divider, - ListItemIcon, Switch, Tooltip, Typography, } from "@mui/material"; -import AddIcon from "@mui/icons-material/Add"; import ExtensionIcon from "@src/assets/icons/Extension"; import DuplicateIcon from "@src/assets/icons/Copy"; import EditIcon from "@mui/icons-material/EditOutlined"; import DeleteIcon from "@mui/icons-material/DeleteOutlined"; -import EmailIcon from "@mui/icons-material/EmailOutlined"; import EmptyState from "@src/components/EmptyState"; -import { - extensionTypes, - extensionNames, - IExtension, - ExtensionType, -} from "./utils"; +import { extensionNames, IExtension } from "./utils"; import { DATE_TIME_FORMAT } from "@src/constants/dates"; -import { EMAIL_REQUEST } from "@src/constants/externalLinks"; export interface IExtensionListProps { extensions: IExtension[]; - handleAddExtension: (type: ExtensionType) => void; handleUpdateActive: (index: number, active: boolean) => void; handleDuplicate: (index: number) => void; handleEdit: (index: number) => void; @@ -46,204 +30,127 @@ export interface IExtensionListProps { export default function ExtensionList({ extensions, - handleAddExtension, handleUpdateActive, handleDuplicate, handleEdit, handleDelete, }: IExtensionListProps) { - const [anchorEl, setAnchorEl] = useState(null); - const addButtonRef = useRef(null); - - const activeExtensionCount = extensions.filter( - (extension) => extension.active - ).length; - - const handleAddButton = () => { - setAnchorEl(addButtonRef.current); - }; - - const handleChooseAddType = (type: ExtensionType) => { - handleClose(); - handleAddExtension(type); - }; - - const handleClose = () => { - setAnchorEl(null); - }; + if (extensions.length === 0) + return ( + + ); return ( - <> - - - Extensions ({activeExtensionCount} / {extensions.length}) - - - - - {extensionTypes.map((type) => ( - handleChooseAddType(type)}> - {extensionNames[type]} - - ))} - - - - - - - - Request new Extension… - - - - - {extensions.length === 0 ? ( - - - - ) : ( - - {extensions.map((extensionObject, index) => ( - - } - secondaryAction={ - - - - - handleUpdateActive(index, !extensionObject.active) - } - inputProps={{ "aria-label": "Activate" }} - sx={{ mr: 1 }} - /> - - - - handleDuplicate(index)} - > - - - - - handleEdit(index)} - > - - - - - handleDelete(index)} - sx={{ "&&": { mr: -1.5 } }} - > - - - - - - - Last updated -
- by {extensionObject.lastEditor.displayName} -
- at{" "} - {format( - extensionObject.lastEditor.lastUpdate, - DATE_TIME_FORMAT - )} - - } - > - - - {formatRelative( - extensionObject.lastEditor.lastUpdate, - new Date() - )} - - - -
-
- } + + {extensions.map((extensionObject, index) => ( + - ))} - - )} - + } + secondaryAction={ + + + + + handleUpdateActive(index, !extensionObject.active) + } + inputProps={{ "aria-label": "Activate" }} + sx={{ mr: 1 }} + /> + + + + handleDuplicate(index)} + > + + + + + handleEdit(index)} + > + + + + + handleDelete(index)} + sx={{ "&&": { mr: -1.5 } }} + > + + + + + + + Last updated +
+ by {extensionObject.lastEditor.displayName} +
+ at{" "} + {format( + extensionObject.lastEditor.lastUpdate, + DATE_TIME_FORMAT + )} + + } + > + + + {formatRelative( + extensionObject.lastEditor.lastUpdate, + new Date() + )} + + + +
+
+ } + sx={{ + flexWrap: { xs: "wrap", sm: "nowrap" }, + "& .MuiListItemSecondaryAction-root": { + position: { xs: "static", sm: "absolute" }, + width: { xs: "100%", sm: "auto" }, + transform: { xs: "none", sm: "translateY(-50%)" }, + }, + pr: { xs: 0, sm: 216 / 8 }, + }} + /> + ))} +
); } diff --git a/src/components/TableHeader/Extensions/index.tsx b/src/components/TableHeader/Extensions/index.tsx index 91349884..86a9cb6d 100644 --- a/src/components/TableHeader/Extensions/index.tsx +++ b/src/components/TableHeader/Extensions/index.tsx @@ -1,11 +1,10 @@ import { useState } from "react"; import _isEqual from "lodash/isEqual"; -import { Breadcrumbs } from "@mui/material"; - import TableHeaderButton from "../TableHeaderButton"; import ExtensionIcon from "@src/assets/icons/Extension"; import Modal from "@src/components/Modal"; +import AddExtensionButton from "./AddExtensionButton"; import ExtensionList from "./ExtensionList"; import ExtensionModal from "./ExtensionModal"; import ExtensionMigration from "./ExtensionMigration"; @@ -40,12 +39,6 @@ export default function Extensions() { const snackLogContext = useSnackLogContext(); const edited = !_isEqual(currentExtensionObjects, localExtensionsObjects); - const tablePathTokens = - tableState?.tablePath?.split("/").filter(function (_, i) { - // replace IDs with dash that appears at even indexes - return i % 2 === 0; - }) ?? []; - const handleOpen = () => { if (tableState?.config.sparks) { // migration is required @@ -180,6 +173,10 @@ export default function Extensions() { lastUpdate: Date.now(), }); + const activeExtensionCount = localExtensionsObjects.filter( + (extension) => extension.active + ).length; + return ( <> { + setExtensionModal({ + mode: "add", + extensionObject: emptyExtensionObject(type, currentEditor()), + }); + }} + variant={ + localExtensionsObjects.length === 0 ? "contained" : "outlined" + } + /> + } children={ - <> - - {tablePathTokens.map((pathToken) => ( - {pathToken} - ))} - - { - setExtensionModal({ - mode: "add", - extensionObject: emptyExtensionObject( - type, - currentEditor() - ), - }); - }} - handleUpdateActive={handleUpdateActive} - handleEdit={handleEdit} - handleDuplicate={handleDuplicate} - handleDelete={handleDelete} - /> - + } actions={{ primary: { diff --git a/src/components/TableHeader/Webhooks/AddWebhookButton.tsx b/src/components/TableHeader/Webhooks/AddWebhookButton.tsx new file mode 100644 index 00000000..234d9264 --- /dev/null +++ b/src/components/TableHeader/Webhooks/AddWebhookButton.tsx @@ -0,0 +1,83 @@ +import { useRef, useState } from "react"; + +import { + Button, + ButtonProps, + Menu, + MenuItem, + Divider, + ListItemIcon, +} from "@mui/material"; +import AddIcon from "@mui/icons-material/Add"; +import EmailIcon from "@mui/icons-material/EmailOutlined"; + +import { webhookTypes, webhookNames, WebhookType } from "./utils"; +import { EMAIL_REQUEST } from "@src/constants/externalLinks"; + +export interface IAddWebhookButtonProps extends Partial { + handleAddWebhook: (type: WebhookType) => void; +} + +export default function AddWebhookButton({ + handleAddWebhook, + ...props +}: IAddWebhookButtonProps) { + const addButtonRef = useRef(null); + const [open, setOpen] = useState(false); + + const handleChooseAddType = (type: WebhookType) => { + setOpen(false); + handleAddWebhook(type); + }; + + return ( + <> + + + setOpen(false)} + anchorOrigin={{ vertical: "bottom", horizontal: "right" }} + transformOrigin={{ vertical: "top", horizontal: "right" }} + > + {webhookTypes.map((type) => ( + handleChooseAddType(type)}> + {webhookNames[type]} + + ))} + + + + + + + + Request new webhook… + + + + ); +} diff --git a/src/components/TableHeader/Webhooks/WebhookList.tsx b/src/components/TableHeader/Webhooks/WebhookList.tsx index 20ee6af0..0954fb8b 100644 --- a/src/components/TableHeader/Webhooks/WebhookList.tsx +++ b/src/components/TableHeader/Webhooks/WebhookList.tsx @@ -1,37 +1,27 @@ -import { useState, useRef } from "react"; import { useAtom } from "jotai"; import { format, formatRelative } from "date-fns"; import { Stack, - ButtonBase, List, ListItem, ListItemText, Avatar, - Button, IconButton, - Menu, - MenuItem, - Divider, - ListItemIcon, Switch, Tooltip, Typography, } from "@mui/material"; -import AddIcon from "@mui/icons-material/Add"; import WebhookIcon from "@src/assets/icons/Webhook"; import LogsIcon from "@src/assets/icons/CloudLogs"; import EditIcon from "@mui/icons-material/EditOutlined"; import DeleteIcon from "@mui/icons-material/DeleteOutlined"; -import CopyIcon from "@src/assets/icons/Copy"; -import EmailIcon from "@mui/icons-material/EmailOutlined"; +import LinkIcon from "@mui/icons-material/Link"; import EmptyState from "@src/components/EmptyState"; -import { webhookTypes, webhookNames, IWebhook, WebhookType } from "./utils"; +import { webhookNames, IWebhook } from "./utils"; import { DATE_TIME_FORMAT } from "@src/constants/dates"; import { useProjectContext } from "@src/contexts/ProjectContext"; -import { EMAIL_REQUEST } from "@src/constants/externalLinks"; import { modalAtom, cloudLogFiltersAtom, @@ -39,7 +29,6 @@ import { export interface IWebhookListProps { webhooks: IWebhook[]; - handleAddWebhook: (type: WebhookType) => void; handleUpdateActive: (index: number, active: boolean) => void; handleEdit: (index: number) => void; handleDelete: (index: number) => void; @@ -47,243 +36,157 @@ export interface IWebhookListProps { export default function WebhookList({ webhooks, - handleAddWebhook, handleUpdateActive, handleEdit, handleDelete, }: IWebhookListProps) { const { settings, tableState } = useProjectContext(); - const [anchorEl, setAnchorEl] = useState(null); - const addButtonRef = useRef(null); const [, setModal] = useAtom(modalAtom); const [, setCloudLogFilters] = useAtom(cloudLogFiltersAtom); - const activeWebhookCount = webhooks.filter( - (webhook) => webhook.active - ).length; - const handleAddButton = () => { - setAnchorEl(addButtonRef.current); - }; - - const handleChooseAddType = (type: WebhookType) => { - handleClose(); - handleAddWebhook(type); - }; - - const handleClose = () => { - setAnchorEl(null); - }; const baseUrl = `${settings?.services?.hooks}/wh/${tableState?.tablePath}/`; + + if (webhooks.length === 0) + return ( + + ); + return ( - <> - - - Webhooks ({activeWebhookCount} / {webhooks.length}) - - - - - {webhookTypes.map((type) => ( - handleChooseAddType(type)}> - {webhookNames[type]} - - ))} - - - - - - - - Request new webhook… - - - - - {webhooks.length === 0 ? ( - - - - ) : ( - - {webhooks.map((webhook, index) => ( - - {webhook.name} {webhookNames[webhook.type]} - - } - secondary={ -
-
- - - {baseUrl} - {webhook.endpoint} - - -
- - - navigator.clipboard.writeText( - `${baseUrl}${webhook.endpoint}` - ) - } - > - - - -
- } - primaryTypographyProps={{ - style: { - minHeight: 40, - display: "flex", - alignItems: "center", - }, - }} - /> - } - secondaryAction={ - - - - - handleUpdateActive(index, !webhook.active) - } - inputProps={{ "aria-label": "Activate" }} - sx={{ mr: 1 }} - /> - - - - { - setModal("cloudLogs"); - setCloudLogFilters({ - type: "webhook", - timeRange: { type: "days", value: 7 }, - webhook: [webhook.endpoint], - }); - }} - > - - - - - handleEdit(index)} - > - - - - - handleDelete(index)} - sx={{ "&&": { mr: -1.5 } }} - > - - - - - - - Last updated -
- by {webhook.lastEditor.displayName} -
- at{" "} - {format( - webhook.lastEditor.lastUpdate, - DATE_TIME_FORMAT - )} - - } + + {webhooks.map((webhook, index) => ( + + {webhookNames[webhook.type]}{" "} + - - + {webhook.endpoint} +
+ + + navigator.clipboard.writeText( + baseUrl + webhook.endpoint + ) + } + size="small" + color="secondary" + sx={{ my: (20 - 32) / 2 / 8 }} > - {formatRelative( - webhook.lastEditor.lastUpdate, - new Date() - )} - - -
- - + + + + + } + primaryTypographyProps={{ + style: { + minHeight: 40, + display: "flex", + alignItems: "center", + }, + }} /> - ))} -
- )} - + } + secondaryAction={ + + + + handleUpdateActive(index, !webhook.active)} + inputProps={{ "aria-label": "Activate" }} + sx={{ mr: 1 }} + /> + + + + { + setModal("cloudLogs"); + setCloudLogFilters({ + type: "webhook", + timeRange: { type: "days", value: 7 }, + webhook: [webhook.endpoint], + }); + }} + > + + + + + handleEdit(index)} + > + + + + + handleDelete(index)} + sx={{ "&&": { mr: -1.5 } }} + > + + + + + + + Last updated +
+ by {webhook.lastEditor.displayName} +
+ at {format(webhook.lastEditor.lastUpdate, DATE_TIME_FORMAT)} + + } + > + + + {formatRelative(webhook.lastEditor.lastUpdate, new Date())} + + + +
+
+ } + sx={{ + flexWrap: { xs: "wrap", sm: "nowrap" }, + "& .MuiListItemSecondaryAction-root": { + position: { xs: "static", sm: "absolute" }, + width: { xs: "100%", sm: "auto" }, + transform: { xs: "none", sm: "translateY(-50%)" }, + }, + pr: { xs: 0, sm: 216 / 8 }, + }} + /> + ))} + ); } diff --git a/src/components/TableHeader/Webhooks/index.tsx b/src/components/TableHeader/Webhooks/index.tsx index 5c23de41..f5ec9530 100644 --- a/src/components/TableHeader/Webhooks/index.tsx +++ b/src/components/TableHeader/Webhooks/index.tsx @@ -1,11 +1,10 @@ import { useState } from "react"; import _isEqual from "lodash/isEqual"; -import { Breadcrumbs } from "@mui/material"; - import TableHeaderButton from "../TableHeaderButton"; import WebhookIcon from "@src/assets/icons/Webhook"; import Modal from "@src/components/Modal"; +import AddWebhookButton from "./AddWebhookButton"; import WebhookList from "./WebhookList"; import WebhookModal from "./WebhookModal"; @@ -34,14 +33,10 @@ export default function Webhooks() { webhookObject: IWebhook; index?: number; } | null>(null); - if (!compatibleRowyRunVersion?.({ minVersion: "1.2.0" })) return <>; - const edited = !_isEqual(currentWebhooks, localWebhooksObjects); - const tablePathTokens = - tableState?.tablePath?.split("/").filter(function (_, i) { - // replace IDs with dash that appears at even indexes - return i % 2 === 0; - }) ?? []; + if (!compatibleRowyRunVersion?.({ minVersion: "1.2.0" })) return null; + + const edited = !_isEqual(currentWebhooks, localWebhooksObjects); const handleOpen = () => { setOpenWebhookList(true); @@ -159,6 +154,10 @@ export default function Webhooks() { lastUpdate: Date.now(), }); + const activeWebhookCount = localWebhooksObjects.filter( + (webhook) => webhook.active + ).length; + return ( <> { + setWebhookModal({ + mode: "add", + webhookObject: emptyWebhookObject(type, currentEditor()), + }); + }} + variant={ + localWebhooksObjects.length === 0 ? "contained" : "outlined" + } + /> + } children={ - <> - - {tablePathTokens.map((pathToken) => ( - {pathToken} - ))} - - { - setWebhookModal({ - mode: "add", - webhookObject: emptyWebhookObject(type, currentEditor()), - }); - }} - handleUpdateActive={handleUpdateActive} - handleEdit={handleEdit} - handleDelete={handleDelete} - /> - + } actions={{ primary: { diff --git a/src/contexts/ProjectContext.tsx b/src/contexts/ProjectContext.tsx index e025ccdf..ec00eeac 100644 --- a/src/contexts/ProjectContext.tsx +++ b/src/contexts/ProjectContext.tsx @@ -4,6 +4,7 @@ import { DataGridHandle } from "react-data-grid"; import _sortBy from "lodash/sortBy"; import _find from "lodash/find"; import firebase from "firebase/app"; +import { compare } from "compare-versions"; import { Button } from "@mui/material"; import InlineOpenInNewIcon from "@src/components/InlineOpenInNewIcon"; @@ -19,7 +20,6 @@ import { rowyRun, IRowyRunRequestProps } from "@src/utils/rowyRun"; import { rowyUser } from "@src/utils/fns"; import { WIKI_LINKS } from "@src/constants/externalLinks"; import { runRoutes } from "@src/constants/runRoutes"; -import semver from "semver"; export type Table = { id: string; @@ -375,13 +375,12 @@ export const ProjectContextProvider: React.FC = ({ children }) => { minVersion?: string; maxVersion?: string; }) => { - // example: "1.0.0", "1.0.0-beta.1", "1.0.0-rc.1+1" - const version = rowyRunVersion.split("-")[0]; - if (!version) return false; - if (minVersion && semver.lt(version, minVersion)) return false; - if (maxVersion && semver.gt(version, maxVersion)) return false; + if (!rowyRunVersion) return false; + if (minVersion && compare(rowyRunVersion, minVersion, "<")) return false; + if (maxVersion && compare(rowyRunVersion, maxVersion, ">")) return false; return true; }; + // A ref to the data grid. Contains data grid functions const dataGridRef = useRef(null); const sideDrawerRef = useRef(); From de81217662c98a576b6bd69ecdeda16a47e51ddc Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Mon, 29 Nov 2021 15:48:31 +1100 Subject: [PATCH 02/10] update webhooks copy --- .../TableHeader/Extensions/ExtensionModal.tsx | 2 +- .../TableHeader/Webhooks/Schemas/basic.tsx | 14 +++- .../TableHeader/Webhooks/Schemas/sendgrid.tsx | 30 ++++---- .../TableHeader/Webhooks/Schemas/typeform.tsx | 28 ++++---- .../TableHeader/Webhooks/Step1Auth.tsx | 43 ++++++------ .../TableHeader/Webhooks/Step3Parser.tsx | 4 +- .../TableHeader/Webhooks/WebhookModal.tsx | 70 +++++++++++-------- src/components/TableHeader/Webhooks/utils.tsx | 5 +- 8 files changed, 112 insertions(+), 84 deletions(-) diff --git a/src/components/TableHeader/Extensions/ExtensionModal.tsx b/src/components/TableHeader/Extensions/ExtensionModal.tsx index b112c339..d9bc2e18 100644 --- a/src/components/TableHeader/Extensions/ExtensionModal.tsx +++ b/src/components/TableHeader/Extensions/ExtensionModal.tsx @@ -162,7 +162,7 @@ export default function ExtensionModal({ onClick: () => { let warningMessage; if (!validation.condition && !validation.extensionBody) { - warningMessage = "Condition and extension body are not valid"; + warningMessage = "Condition and Extension body are not valid"; } else if (!validation.condition) { warningMessage = "Condition is not valid"; } else if (!validation.extensionBody) { diff --git a/src/components/TableHeader/Webhooks/Schemas/basic.tsx b/src/components/TableHeader/Webhooks/Schemas/basic.tsx index b59e9c71..105ed038 100644 --- a/src/components/TableHeader/Webhooks/Schemas/basic.tsx +++ b/src/components/TableHeader/Webhooks/Schemas/basic.tsx @@ -1,3 +1,6 @@ +import { Typography } from "@mui/material"; +import WarningIcon from "@mui/icons-material/WarningAmber"; + export const webhookTypes = [ "basic", "typeform", @@ -36,7 +39,7 @@ const additionalVariables = [ }, ]; -export default { +export const webhookBasic = { name: "Basic", parser: { additionalVariables, @@ -60,6 +63,13 @@ export default { }`, }, auth: (webhookObject, setWebhookObject) => { - return <>no auth option for basic atm; + return ( + + +   Verification is not currently available for basic webhooks + + ); }, }; + +export default webhookBasic; diff --git a/src/components/TableHeader/Webhooks/Schemas/sendgrid.tsx b/src/components/TableHeader/Webhooks/Schemas/sendgrid.tsx index 62a15e6f..e91e804c 100644 --- a/src/components/TableHeader/Webhooks/Schemas/sendgrid.tsx +++ b/src/components/TableHeader/Webhooks/Schemas/sendgrid.tsx @@ -1,7 +1,8 @@ import { Typography, Link, TextField } from "@mui/material"; +import InlineOpenInNewIcon from "@src/components/InlineOpenInNewIcon"; -export default { - name: "Sendgrid", +export const webhookSendgrid = { + name: "SendGrid", parser: { additionalVariables: null, extraLibs: null, @@ -32,24 +33,25 @@ export default { return ( <> - To verify the webhook call is sent from Sendgrid, You can enable - signed event webhooks + Enable Signed Event Webhooks on SendGrid by following{" "} - here - {" "} - to set the secret, then add it below + these instructions + + +
+ Then add the secret below.
{ setWebhookObject({ @@ -62,3 +64,5 @@ export default { ); }, }; + +export default webhookSendgrid; diff --git a/src/components/TableHeader/Webhooks/Schemas/typeform.tsx b/src/components/TableHeader/Webhooks/Schemas/typeform.tsx index b345ec06..9d97d2c8 100644 --- a/src/components/TableHeader/Webhooks/Schemas/typeform.tsx +++ b/src/components/TableHeader/Webhooks/Schemas/typeform.tsx @@ -1,6 +1,7 @@ import { Typography, Link, TextField } from "@mui/material"; +import InlineOpenInNewIcon from "@src/components/InlineOpenInNewIcon"; -export default { +export const webhookTypeform = { name: "Typeform", parser: { additionalVariables: null, @@ -55,23 +56,24 @@ export default { return ( <> - To verify the webhook call is sent from typeform, you need to add - secret on your webhook config on be follow the instructions{" "} + Add a secret to your Typeform webhook config by following{" "} - here - {" "} - to set the secret, then add it below + these instructions + + +
+ Then add the secret below.
{ setWebhookObject({ @@ -84,3 +86,5 @@ export default { ); }, }; + +export default webhookTypeform; diff --git a/src/components/TableHeader/Webhooks/Step1Auth.tsx b/src/components/TableHeader/Webhooks/Step1Auth.tsx index bc8369c7..e252e979 100644 --- a/src/components/TableHeader/Webhooks/Step1Auth.tsx +++ b/src/components/TableHeader/Webhooks/Step1Auth.tsx @@ -1,25 +1,23 @@ import { IWebhookModalStepProps } from "./WebhookModal"; -import { - FormControl, - FormLabel, - FormControlLabel, - Switch, - Typography, -} from "@mui/material"; + +import { FormControlLabel, Checkbox, Typography } from "@mui/material"; + import { webhookSchemas } from "./utils"; + export default function Step1Endpoint({ webhookObject, setWebhookObject, }: IWebhookModalStepProps) { return ( - - - Verification - + <> + + Verification prevents malicious requests from being sent to this webhook + endpoint + + setWebhookObject({ @@ -32,17 +30,16 @@ export default function Step1Endpoint({ } /> } - label="Enable Verification" + label="Enable verification for this webhook" + sx={{ mb: 2 }} /> - {webhookObject.auth?.enabled ? ( - webhookSchemas[webhookObject.type].auth(webhookObject, setWebhookObject) - ) : ( - - Verification of webhooks is optional however it prevents malicious - actors from spoofing the original sender - - )} + + {webhookObject.auth?.enabled && + webhookSchemas[webhookObject.type].auth( + webhookObject, + setWebhookObject + )} {} - + ); } diff --git a/src/components/TableHeader/Webhooks/Step3Parser.tsx b/src/components/TableHeader/Webhooks/Step3Parser.tsx index 789dd031..62b169e0 100644 --- a/src/components/TableHeader/Webhooks/Step3Parser.tsx +++ b/src/components/TableHeader/Webhooks/Step3Parser.tsx @@ -34,8 +34,8 @@ export default function Step4Body({ return ( <> - Write the webhook parsed function. The returned object of the parser - will be added as new row{" "} + Write a function to parse webhook requests. Return an object, which will + be added as a new row.{" "} ; + export interface IWebhookModalStepProps { webhookObject: IWebhook; setWebhookObject: React.Dispatch>; @@ -128,36 +136,39 @@ export default function WebhookModal({ }activated`} /> -
- URL: -
- - - {baseUrl} - {webhookObject.endpoint} - - -
- - - navigator.clipboard.writeText( - `${baseUrl}${webhookObject.endpoint}` - ) - } - > - - - -
+ + + Endpoint URL: + +   + + + {baseUrl} + {webhookObject.endpoint} + + + + + navigator.clipboard.writeText( + `${baseUrl}${webhookObject.endpoint}` + ) + } + sx={{ flexShrink: 0, mr: -0.75 }} + > + + + + + , }, ]} + style={{ marginTop: "var(--dialog-contents-spacing)" }} /> } diff --git a/src/components/TableHeader/Webhooks/utils.tsx b/src/components/TableHeader/Webhooks/utils.tsx index 1d93adc5..5701f875 100644 --- a/src/components/TableHeader/Webhooks/utils.tsx +++ b/src/components/TableHeader/Webhooks/utils.tsx @@ -40,9 +40,9 @@ const additionalVariables = [ export type WebhookType = typeof webhookTypes[number]; export const webhookNames: Record = { - sendgrid: "Sendgrid", + sendgrid: "SendGrid", typeform: "Typeform", - //github:"Github", + //github:"GitHub", // shopify: "Shopify", // twitter: "Twitter", // stripe: "Stripe", @@ -73,6 +73,7 @@ export const webhookSchemas = { typeform, sendgrid, }; + export function emptyWebhookObject( type: WebhookType, user: IWebhookEditor From 6d9d3d4fcea115119e77e49cb5a8fd47d67b2176 Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Mon, 29 Nov 2021 16:06:16 +1100 Subject: [PATCH 03/10] fix row hover icon button background --- src/components/Table/TableContainer.tsx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/components/Table/TableContainer.tsx b/src/components/Table/TableContainer.tsx index 3667eec1..d6c80e21 100644 --- a/src/components/Table/TableContainer.tsx +++ b/src/components/Table/TableContainer.tsx @@ -136,14 +136,13 @@ export const TableContainer = styled("div", { ".row-hover-iconButton": { color: theme.palette.text.disabled, transitionDuration: "0s", - - ".rdg-row:hover &": { - color: theme.palette.text.primary, - backgroundColor: alpha( - theme.palette.action.hover, - theme.palette.action.hoverOpacity * 1.5 - ), - }, + }, + ".rdg-row:hover .row-hover-iconButton": { + color: theme.palette.text.primary, + backgroundColor: alpha( + theme.palette.action.hover, + theme.palette.action.hoverOpacity * 1.5 + ), }, ".cell-collapse-padding": { From d20e98e60034e38bbaeec232769800e04f1d6d4a Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Mon, 29 Nov 2021 19:40:13 +1100 Subject: [PATCH 04/10] fix build log snackbar not appearing for derivative function deploy --- src/components/Table/ColumnMenu/FieldSettings/index.tsx | 3 +++ .../TableHeader/CloudLogs/BuildLogs/BuildLogsSnack.tsx | 9 ++++++++- src/components/TableHeader/Extensions/index.tsx | 7 ++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/components/Table/ColumnMenu/FieldSettings/index.tsx b/src/components/Table/ColumnMenu/FieldSettings/index.tsx index 85939f4f..34121f10 100644 --- a/src/components/Table/ColumnMenu/FieldSettings/index.tsx +++ b/src/components/Table/ColumnMenu/FieldSettings/index.tsx @@ -12,6 +12,7 @@ import Loading from "@src/components/Loading"; import { useProjectContext } from "@src/contexts/ProjectContext"; import { useConfirmation } from "@src/components/ConfirmationDialog"; +import { useSnackLogContext } from "@src/contexts/SnackLogContext"; import { FieldType } from "@src/constants/fields"; import { runRoutes } from "@src/constants/runRoutes"; @@ -27,6 +28,7 @@ export default function FieldSettings(props: IMenuModalProps) { const { requestConfirmation } = useConfirmation(); const { tableState, rowyRun } = useProjectContext(); + const snackLogContext = useSnackLogContext(); const rendedFieldSettings = useMemo( () => @@ -164,6 +166,7 @@ export default function FieldSettings(props: IMenuModalProps) { cancel: "Later", handleConfirm: async () => { if (!rowyRun) return; + snackLogContext.requestSnackLog(); rowyRun({ route: runRoutes.buildFunction, body: { diff --git a/src/components/TableHeader/CloudLogs/BuildLogs/BuildLogsSnack.tsx b/src/components/TableHeader/CloudLogs/BuildLogs/BuildLogsSnack.tsx index ed342f2b..e48321f0 100644 --- a/src/components/TableHeader/CloudLogs/BuildLogs/BuildLogsSnack.tsx +++ b/src/components/TableHeader/CloudLogs/BuildLogs/BuildLogsSnack.tsx @@ -118,6 +118,7 @@ export default function BuildLogsSnack({ onClose, onOpenPanel }) { aria-label="Expand" size="small" onClick={() => setExpanded(!expanded)} + style={{ color: "white" }} > {expanded ? : } @@ -135,13 +136,19 @@ export default function BuildLogsSnack({ onClose, onOpenPanel }) { buildLogExpanded: 0, }); }} + style={{ color: "white" }} > - + diff --git a/src/components/TableHeader/Extensions/index.tsx b/src/components/TableHeader/Extensions/index.tsx index 86a9cb6d..53f1ec05 100644 --- a/src/components/TableHeader/Extensions/index.tsx +++ b/src/components/TableHeader/Extensions/index.tsx @@ -76,8 +76,8 @@ export default function Extensions() { const handleSaveDeploy = async () => { handleSaveExtensions(); try { - snackLogContext.requestSnackLog(); - if (rowyRun) + if (rowyRun) { + snackLogContext.requestSnackLog(); rowyRun({ route: runRoutes.buildFunction, body: { @@ -86,7 +86,8 @@ export default function Extensions() { tableConfigPath: tableState?.config.tableConfig.path, }, }); - analytics.logEvent("deployed_extensions"); + analytics.logEvent("deployed_extensions"); + } } catch (e) { console.error(e); } From 24f2082b72f8108d624b6cf392240963ad11be11 Mon Sep 17 00:00:00 2001 From: Sidney Alcantara Date: Tue, 30 Nov 2021 12:27:28 +1100 Subject: [PATCH 05/10] upgrade mui --- package.json | 10 +- src/assets/icons/UpdatedAt.tsx | 3 +- src/components/CodeEditor/DiffEditor.tsx | 9 +- src/components/CodeEditor/index.tsx | 9 +- .../CodeEditor/useMonacoCustomizations.ts | 4 +- src/components/HelperText.tsx | 2 +- .../Modal/ScrollableDialogContent.tsx | 18 +- src/components/Table/BulkActions/index.tsx | 6 +- src/components/Table/TableContainer.tsx | 2 +- src/components/TableHeader/AddRow.tsx | 4 + .../CloudLogs/BuildLogs/BuildLogRow.tsx | 2 +- .../TableHeader/CloudLogs/BuildLogs/index.tsx | 2 +- .../TableHeader/CloudLogs/CloudLogItem.tsx | 2 +- .../CloudLogs/CloudLogSubheader.tsx | 2 +- src/components/Wizards/ScrollableList.tsx | 22 +- .../ConnectServiceSelect/index.tsx | 2 +- .../fields/Json/SideDrawerField.tsx | 7 +- src/theme/components.tsx | 14 +- yarn.lock | 305 ++++++++++-------- 19 files changed, 251 insertions(+), 174 deletions(-) diff --git a/package.json b/package.json index 7161e2e9..5e4a1714 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,12 @@ "@emotion/react": "^11.4.0", "@emotion/styled": "^11.3.0", "@hookform/resolvers": "^2.8.1", - "@mdi/js": "^6.2.95", + "@mdi/js": "^6.5.95", "@monaco-editor/react": "^4.3.1", - "@mui/icons-material": "^5.0.0", - "@mui/lab": "^5.0.0-alpha.50", - "@mui/material": "^5.0.0", - "@mui/styles": "^5.0.0", + "@mui/icons-material": "^5.2.0", + "@mui/lab": "^5.0.0-alpha.58", + "@mui/material": "^5.2.2", + "@mui/styles": "^5.2.2", "@rowy/form-builder": "^0.4.2", "@rowy/multiselect": "^0.2.3", "@tinymce/tinymce-react": "^3.12.6", diff --git a/src/assets/icons/UpdatedAt.tsx b/src/assets/icons/UpdatedAt.tsx index 754a89ca..2652282e 100644 --- a/src/assets/icons/UpdatedAt.tsx +++ b/src/assets/icons/UpdatedAt.tsx @@ -1,9 +1,10 @@ import SvgIcon, { SvgIconProps } from "@mui/material/SvgIcon"; +import { mdiClockEditOutline } from "@mdi/js"; export default function UpdatedAt(props: SvgIconProps) { return ( - + ); } diff --git a/src/components/CodeEditor/DiffEditor.tsx b/src/components/CodeEditor/DiffEditor.tsx index 0293a16b..4eb32688 100644 --- a/src/components/CodeEditor/DiffEditor.tsx +++ b/src/components/CodeEditor/DiffEditor.tsx @@ -63,7 +63,14 @@ export default function DiffEditor({ return ( = { + let boxSx: SystemStyleObject = { minWidth: 400, minHeight, height: minHeight, diff --git a/src/components/HelperText.tsx b/src/components/HelperText.tsx index dab222ac..714e0255 100644 --- a/src/components/HelperText.tsx +++ b/src/components/HelperText.tsx @@ -13,7 +13,7 @@ export default function HelperText(props: IHelperTextProps) { style={{ marginTop: theme.spacing(-3), padding: theme.spacing(0, 1.5), - ...theme.typography.body2, + ...(theme.typography.body2 as any), color: theme.palette.text.secondary, }} /> diff --git a/src/components/Modal/ScrollableDialogContent.tsx b/src/components/Modal/ScrollableDialogContent.tsx index 4a58edf3..f041f099 100644 --- a/src/components/Modal/ScrollableDialogContent.tsx +++ b/src/components/Modal/ScrollableDialogContent.tsx @@ -26,9 +26,9 @@ export interface IScrollableDialogContentProps extends DialogContentProps { export default function ScrollableDialogContent({ disableTopDivider = false, disableBottomDivider = false, - dividerSx, - topDividerSx, - bottomDividerSx, + dividerSx = [], + topDividerSx = [], + bottomDividerSx = [], ...props }: IScrollableDialogContentProps) { const [scrollInfo, setRef] = useScrollInfo(); @@ -40,7 +40,10 @@ export default function ScrollableDialogContent({ style={{ visibility: scrollInfo.y.percentage > 0 ? "visible" : "hidden", }} - sx={{ ...dividerSx, ...topDividerSx }} + sx={[ + ...(Array.isArray(dividerSx) ? dividerSx : [dividerSx]), + ...(Array.isArray(topDividerSx) ? topDividerSx : [topDividerSx]), + ]} /> )} @@ -51,7 +54,12 @@ export default function ScrollableDialogContent({ style={{ visibility: scrollInfo.y.percentage < 1 ? "visible" : "hidden", }} - sx={{ ...dividerSx, ...bottomDividerSx }} + sx={[ + ...(Array.isArray(dividerSx) ? dividerSx : [dividerSx]), + ...(Array.isArray(bottomDividerSx) + ? bottomDividerSx + : [bottomDividerSx]), + ]} /> )} diff --git a/src/components/Table/BulkActions/index.tsx b/src/components/Table/BulkActions/index.tsx index dbde5e83..cbea8cab 100644 --- a/src/components/Table/BulkActions/index.tsx +++ b/src/components/Table/BulkActions/index.tsx @@ -25,9 +25,9 @@ import ArrowDropUpIcon from "@mui/icons-material/ArrowDropUp"; import { useConfirmation } from "@src/components/ConfirmationDialog/Context"; import { useProjectContext } from "@src/contexts/ProjectContext"; import { formatPath, asyncForEach } from "@src/utils/fns"; -import routes from "@src/constants/routes"; +// import routes from "@src/constants/routes"; import { runRoutes } from "@src/constants/runRoutes"; -import { config } from "process"; +// import { config } from "process"; import { WIKI_LINKS } from "@src/constants/externalLinks"; const useStyles = makeStyles((theme) => @@ -266,7 +266,7 @@ export default function BulkActions({ selectedRows, columns, clearSelection }) { }, }} SelectProps={{ - classes: { root: classes.select }, + classes: { select: classes.select }, displayEmpty: true, MenuProps: { anchorOrigin: { vertical: "top", horizontal: "left" }, diff --git a/src/components/Table/TableContainer.tsx b/src/components/Table/TableContainer.tsx index d6c80e21..be070644 100644 --- a/src/components/Table/TableContainer.tsx +++ b/src/components/Table/TableContainer.tsx @@ -58,7 +58,7 @@ export const TableContainer = styled("div", { border: "none", backgroundColor: "transparent", - ...theme.typography.caption, + ...(theme.typography.caption as any), // fontSize: "0.8125rem", lineHeight: "inherit !important", diff --git a/src/components/TableHeader/AddRow.tsx b/src/components/TableHeader/AddRow.tsx index a05de5a1..1c632477 100644 --- a/src/components/TableHeader/AddRow.tsx +++ b/src/components/TableHeader/AddRow.tsx @@ -47,6 +47,8 @@ export default function AddRow() { ref={anchorEl} >