diff --git a/apps/console/src/pages/organizations/access-reviews/dialogs/AddAccessSourceDialog.tsx b/apps/console/src/pages/organizations/access-reviews/dialogs/AddAccessSourceDialog.tsx index b76283a23..636ec2f90 100644 --- a/apps/console/src/pages/organizations/access-reviews/dialogs/AddAccessSourceDialog.tsx +++ b/apps/console/src/pages/organizations/access-reviews/dialogs/AddAccessSourceDialog.tsx @@ -171,6 +171,17 @@ function hasRequiredExtraSettings( .every(s => values[s.key]?.trim()); } +// Accepts either a bare subdomain ("acme") or a pasted host +// ("https://acme.zendesk.com/") and reduces it to the bare subdomain the +// backend expects as the `site` query param. +function cleanZendeskSubdomain(raw: string): string { + let value = raw.trim(); + value = value.replace(/^https?:\/\//i, ""); + value = value.replace(/\/+$/, ""); + value = value.replace(/\.zendesk\.com$/i, ""); + return value.trim(); +} + export function AddAccessSourceDialog({ children, organizationId, @@ -184,6 +195,7 @@ export function AddAccessSourceDialog({ const apiKeyDialogRef = useDialogRef(); const clientCredentialsDialogRef = useDialogRef(); const datadogDialogRef = useDialogRef(); + const zendeskDialogRef = useDialogRef(); const [searchQuery, setSearchQuery] = useState(""); const [activeProvider, setActiveProvider] = useState(null); @@ -191,6 +203,9 @@ export function AddAccessSourceDialog({ const [datadogSite, setDatadogSite] = useState("US1"); const [datadogProvider, setDatadogProvider] = useState(null); + const [zendeskSubdomain, setZendeskSubdomain] = useState(""); + const [zendeskProvider, setZendeskProvider] = useState(null); + const [apiKeyValue, setApiKeyValue] = useState(""); const [extraSettingValues, setExtraSettingValues] = useState>({}); const [isConnectingAPIKey, setIsConnectingAPIKey] = useState(false); @@ -277,6 +292,12 @@ export function AddAccessSourceDialog({ datadogDialogRef.current?.open(); }; + const openZendeskDialog = (info: ProviderInfo) => { + setZendeskProvider(info); + setZendeskSubdomain(""); + zendeskDialogRef.current?.open(); + }; + const createSourceAfterConnector = ( connectorId: string, displayName: string, @@ -470,10 +491,15 @@ export function AddAccessSourceDialog({ return ( @@ -808,6 +834,44 @@ export function AddAccessSourceDialog({ + + +
{ + e.preventDefault(); + if (zendeskProvider) { + const site = cleanZendeskSubdomain(zendeskSubdomain); + if (site) { + connectOAuthProvider(zendeskProvider, { site }); + } + } + }} + > + +

+ {__("Enter your Zendesk subdomain, then continue to authorize access.")} +

+ ) => + setZendeskSubdomain(e.target.value)} + help={__("The part of .zendesk.com")} + required + autoFocus + /> +
+ + + +
+
); } diff --git a/packages/ui/src/Atoms/ThirdParties/ThirdPartyLogo.tsx b/packages/ui/src/Atoms/ThirdParties/ThirdPartyLogo.tsx index 892562cdc..761dc82e4 100644 --- a/packages/ui/src/Atoms/ThirdParties/ThirdPartyLogo.tsx +++ b/packages/ui/src/Atoms/ThirdParties/ThirdPartyLogo.tsx @@ -51,6 +51,7 @@ import { Supabase } from "./Supabase"; import { Tailscale } from "./Tailscale"; import { Tally } from "./Tally"; import { Vercel } from "./Vercel"; +import { Zendesk } from "./Zendesk"; const thirdParties: Record>> = { ANTHROPIC: Anthropic, @@ -93,6 +94,7 @@ const thirdParties: Record>> = { TAILSCALE: Tailscale, TALLY: Tally, VERCEL: Vercel, + ZENDESK: Zendesk, }; type ThirdPartyLogoProps = ComponentProps<"svg"> & { diff --git a/packages/ui/src/Atoms/ThirdParties/Zendesk.tsx b/packages/ui/src/Atoms/ThirdParties/Zendesk.tsx new file mode 100644 index 000000000..e5448b13b --- /dev/null +++ b/packages/ui/src/Atoms/ThirdParties/Zendesk.tsx @@ -0,0 +1,12 @@ +import type { ComponentProps } from "react"; + +export function Zendesk(props: ComponentProps<"svg">) { + return ( + + + + ); +} diff --git a/packages/ui/src/Atoms/ThirdParties/index.ts b/packages/ui/src/Atoms/ThirdParties/index.ts index e535fe28f..a88dc1a61 100644 --- a/packages/ui/src/Atoms/ThirdParties/index.ts +++ b/packages/ui/src/Atoms/ThirdParties/index.ts @@ -36,3 +36,4 @@ export { Tally } from "./Tally"; export { Tailscale } from "./Tailscale"; export { ThirdPartyLogo } from "./ThirdPartyLogo"; export { Vercel } from "./Vercel"; +export { Zendesk } from "./Zendesk";