@workos-inc/widgets 1.20.0-next.1791237372282 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -1
- package/README.md +44 -0
- package/dist/cjs/api/claims.cjs +4 -0
- package/dist/cjs/api/claims.cjs.map +1 -1
- package/dist/cjs/api/claims.d.cts +6 -1
- package/dist/cjs/lib/pipes-credential-attribution.cjs +33 -0
- package/dist/cjs/lib/pipes-credential-attribution.cjs.map +1 -0
- package/dist/cjs/lib/pipes-credential-attribution.d.cts +8 -0
- package/dist/cjs/lib/pipes.cjs +26 -10
- package/dist/cjs/lib/pipes.cjs.map +1 -1
- package/dist/cjs/pipes-admin.client.cjs +8 -4
- package/dist/cjs/pipes-admin.client.cjs.map +1 -1
- package/dist/cjs/pipes-admin.client.d.cts +8 -0
- package/dist/esm/api/claims.d.ts +6 -1
- package/dist/esm/api/claims.js +4 -1
- package/dist/esm/api/claims.js.map +1 -1
- package/dist/esm/lib/pipes-credential-attribution.d.ts +8 -0
- package/dist/esm/lib/pipes-credential-attribution.js +31 -0
- package/dist/esm/lib/pipes-credential-attribution.js.map +1 -0
- package/dist/esm/lib/pipes.js +26 -10
- package/dist/esm/lib/pipes.js.map +1 -1
- package/dist/esm/pipes-admin.client.d.ts +8 -0
- package/dist/esm/pipes-admin.client.js +8 -4
- package/dist/esm/pipes-admin.client.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipes.js","names":["TextField","Dialog.Title","Dialog.Root","Dialog.Content","Dialog.Close","Button","Dialog.Description","DropdownMenu.Item","DropdownMenu.Root","DropdownMenu.Trigger","DropdownMenu.Content","DropdownMenu.Sub","DropdownMenu.SubTrigger","DropdownMenu.SubContent","IconButton","AlertDialog.Root","AlertDialog.Content","AlertDialog.Title","AlertDialog.Description","AlertDialog.Cancel","CardList.Item","Skeleton","CardList.Root"],"sources":["../../../src/lib/pipes.tsx"],"sourcesContent":["\"use client\";\nimport { Callout, Card, Flex, Text } from \"@radix-ui/themes\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport * as CardList from \"./card-list.js\";\nimport { DataIntegrationIcon } from \"./data-integration-icon.js\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport {\n DotsHorizontalIcon,\n ExternalLinkIcon,\n GlobeIcon,\n LockClosedIcon,\n} from \"@radix-ui/react-icons\";\nimport {\n AlertDialog,\n Button,\n Dialog,\n DropdownMenu,\n IconButton,\n Label,\n PasswordField,\n Skeleton,\n TextField,\n} from \"./elements.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { Status } from \"./status.js\";\nimport type {\n DataInstallation,\n DataIntegration,\n DataIntegrationConfigField,\n SharedDataConnection,\n} from \"./api/types.js\";\nimport {\n ADD_CONNECTION,\n createAddConnectionTarget,\n AddConnectionButtonLabel,\n ConnectAnotherAccountMenuLabel,\n ConnectionCountStatus,\n type ConnectionTarget,\n getConnectionLabel,\n canRenameConnections,\n getConnectionTarget,\n RenameConnectionDialog,\n RenameMenuLabel,\n ConnectionNameField,\n toAccountDisplayNameInput,\n toConnectionTargetInput,\n toCreationTargetInput,\n} from \"./pipes-connections.js\";\nimport {\n type AddConnectionCapabilities,\n type DataIntegrationWithCapabilities,\n myDataIntegrationsQueryKeys,\n useInvalidateConnections,\n} from \"./api/pipes.js\";\nimport { useClientGraphql } from \"../api/client-graphql/client.js\";\nimport {\n clientGraphqlQueryKey,\n useClientGraphqlMutation,\n useClientGraphqlQuery,\n} from \"../api/client-graphql/hooks.js\";\nimport type {\n ConnectDataProviderWithClientCredentialsMutation,\n ConnectOrganizationDataProviderWithClientCredentialsInput,\n ConnectOrganizationDataProviderWithClientCredentialsMutation,\n CreateDataProviderAuthorizationMutation,\n ConnectDataProviderWithClientCredentialsInput,\n CreateDataProviderConnectionInput,\n CreateOrganizationDataProviderConnectionInput,\n CreateOrganizationDataProviderAuthorizationMutation,\n DataProviderConfigEntryInput,\n} from \"../api/client-graphql/generated.js\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { GenericError } from \"./generic-error.js\";\nimport { getWidgetDomProps } from \"./utils/widget-dom-props.js\";\nimport { WidgetRootDomProps, WidgetRootState } from \"./widget-types.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\nimport { ApiError } from \"../api/errors.js\";\nimport { buildRedactedSecret, isRedactedSecret } from \"./redacted-secret.js\";\n\ninterface PipesProps extends WidgetRootDomProps {\n integrations: DataIntegration[];\n /**\n * Whether the endpoint returned any connections before the host's `filter`\n * ran, which is what tells an organization with nothing enabled yet apart\n * from a filter that matched nothing. Defaults to whatever survived, the\n * reading for an unfiltered list.\n */\n hasUnfilteredIntegrations?: boolean;\n}\n\ninterface PipesSectionsProps extends Omit<PipesProps, \"integrations\"> {\n /**\n * The member's providers, each with every connection they own to it and\n * whether they can add another.\n */\n integrations: DataIntegrationWithCapabilities[];\n /**\n * Organization-owned connections, as returned by the shared-connections\n * endpoint. Empty both when the organization shares nothing and when the\n * request failed, since neither is something a member can act on.\n */\n sharedConnections: SharedDataConnection[];\n /**\n * {@link PipesProps.hasUnfilteredIntegrations} for the shared section. The\n * section is dropped entirely unless the organization shares something, so\n * this only ever decides whether a filtered-out lane says so.\n */\n hasUnfilteredSharedConnections?: boolean;\n /** Renders the shared section as skeleton rows while it resolves. */\n isSharedLoading?: boolean;\n /** Names the owning organization in the shared section's description. */\n organizationName?: string;\n}\n\nconst HANDOFF_INTERVAL_MS = 100;\nconst HANDOFF_MAX_ATTEMPTS = 100; // 10 seconds worth of attempts\n\ntype DataIntegrationAuthMethod = NonNullable<\n DataIntegration[\"authMethods\"]\n>[number];\n\n/** Supported connect methods, in the order they're offered to the user. */\nconst CONNECT_AUTH_METHODS: DataIntegrationAuthMethod[] = [\n \"oauth\",\n \"client_credentials\",\n \"api_key\",\n];\n\n/**\n * Who will own the resulting installation. Members connect their own account\n * through the personal authorize endpoint; administrators connect an account\n * on the organization's behalf through the organization one.\n */\ntype ConnectionOwner = \"user\" | \"organization\";\n\ntype AuthorizationResult =\n | CreateDataProviderAuthorizationMutation[\"createDataProviderAuthorization\"]\n | CreateOrganizationDataProviderAuthorizationMutation[\"createOrganizationDataProviderAuthorization\"];\n\ntype DataProviderAuthorization = Extract<\n AuthorizationResult,\n { __typename: \"DataProviderAuthorization\" }\n>;\n\ntype AuthorizeConnection = (\n dataProviderId: string,\n config?: Record<string, string>,\n target?: ConnectionTarget,\n accountDisplayName?: string,\n) => Promise<DataProviderAuthorization>;\n\n/**\n * Starts an OAuth authorization from a connect dialog: the config values it\n * collected and, when adding a connection, the name it collected for it.\n */\ntype ConnectHandler = (\n config?: Record<string, string>,\n accountDisplayName?: string,\n) => Promise<void>;\n\n/**\n * Config values as the GraphQL input expects them. Only string values can\n * travel; anything else the stored config carries is left untouched.\n */\nfunction toConfigEntries(\n config: Record<string, unknown> | undefined,\n): DataProviderConfigEntryInput[] | undefined {\n if (!config) {\n return undefined;\n }\n const entries: DataProviderConfigEntryInput[] = [];\n for (const [name, value] of Object.entries(config)) {\n if (typeof value === \"string\") {\n entries.push({ name, value });\n }\n }\n return entries;\n}\n\n/**\n * Failure members of a mutation result union, raised the way the REST client\n * raised the equivalent 4xx so the dialogs' `ApiError` handling still applies.\n */\nfunction resultError(\n message: string,\n status: number,\n context?: unknown,\n): ApiError {\n return new ApiError({ message, status, queryType: \"mutation\", context });\n}\n\ntype ClientCredentialsConnectionResult =\n | ConnectDataProviderWithClientCredentialsMutation[\"connectDataProviderWithClientCredentials\"]\n | ConnectOrganizationDataProviderWithClientCredentialsMutation[\"connectOrganizationDataProviderWithClientCredentials\"];\n\n/**\n * Members without a server-supplied `message` are raised with an empty one so\n * the dialog falls back to its translated generic banner.\n */\nfunction unwrapClientCredentialsConnection(\n result: ClientCredentialsConnectionResult,\n): Extract<\n ClientCredentialsConnectionResult,\n { __typename: \"DataProviderConnected\" }\n> {\n switch (result.__typename) {\n case \"DataProviderConnected\":\n return result;\n case \"DataProviderConfigInvalid\":\n throw resultError(result.message, 400);\n case \"DataProviderAuthMethodUnsupported\":\n throw resultError(\"\", 400, result);\n case \"DataProviderConnectionAuthMethodConflict\":\n throw resultError(\"\", 409, result);\n }\n}\n\nfunction unwrapAuthorization(\n result: AuthorizationResult,\n): DataProviderAuthorization {\n switch (result.__typename) {\n case \"DataProviderAuthorization\":\n return result;\n case \"DataProviderConfigInvalid\":\n throw resultError(result.message, 400);\n case \"DataProviderAuthorizationUnavailable\":\n throw resultError(result.message, 409);\n }\n}\n\n/**\n * Resolves the authorize call for an owner. Both mutations hand off to the\n * popup the same way; the organization one always requires a handoff so it\n * takes no `requireHandoff` flag.\n */\nconst useAuthorizeConnection = (\n owner: ConnectionOwner,\n): AuthorizeConnection => {\n const sdk = useClientGraphql();\n\n return useCallback(\n async (\n dataProviderId: string,\n config?: Record<string, string>,\n target?: ConnectionTarget,\n accountDisplayName?: string,\n ) => {\n const configEntries = toConfigEntries(config);\n const targetInput = toConnectionTargetInput(target);\n // The API holds the name until the callback creates the connection.\n const nameInput = toAccountDisplayNameInput(accountDisplayName);\n if (owner === \"organization\") {\n const { createOrganizationDataProviderAuthorization } =\n await sdk.CreateOrganizationDataProviderAuthorization({\n input: {\n dataProviderId,\n config: configEntries,\n ...targetInput,\n ...nameInput,\n },\n });\n return unwrapAuthorization(createOrganizationDataProviderAuthorization);\n }\n const { createDataProviderAuthorization } =\n await sdk.CreateDataProviderAuthorization({\n input: {\n dataProviderId,\n config: configEntries,\n requireHandoff: true,\n ...targetInput,\n ...nameInput,\n },\n });\n return unwrapAuthorization(createDataProviderAuthorization);\n },\n [owner, sdk],\n );\n};\n\nfunction useAuthKitOrigin(): string {\n const settings = useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"AuthKitSettings\"),\n queryFn: (sdk) => sdk.AuthKitSettings(),\n });\n return settings.data?.authkitSettings.origin ?? \"\";\n}\n\ninterface ConnectionError {\n errorCode?: string;\n errorDescription?: string;\n}\n\n/**\n * Runs the OAuth handoff for one connection target and tracks how it ended,\n * so the row that owns it can show \"Connection failed\". `target` picks the\n * connection the authorization writes (see {@link getConnectionTarget});\n * unset keeps the compatibility behavior.\n */\nconst useOpenDataIntegrationAuthorizeUrl = (\n integration: DataIntegration,\n owner: ConnectionOwner = \"user\",\n target?: ConnectionTarget,\n) => {\n // Keyed by value so a target rebuilt on every render keeps the callback stable.\n const targetIntent = target?.intent;\n const targetAccountId =\n target?.intent === \"Reauthorize\" ? target.connectedAccountId : undefined;\n const authorizeDataIntegration = useAuthorizeConnection(owner);\n const baseUrl = useAuthKitOrigin();\n const intervalRef = useRef<ReturnType<typeof setInterval> | undefined>(\n undefined,\n );\n const messageHandlerRef = useRef<((event: MessageEvent) => void) | undefined>(\n undefined,\n );\n // Tracks whether the popup sent any message (handoff ack or error) before it\n // closed, so a popup that closes without a result can be reported distinctly.\n const receivedMessageRef = useRef(false);\n const [connectionError, setConnectionError] =\n useState<ConnectionError | null>(null);\n\n // Stops watching the popup from the current attempt, if any.\n const stopHandoff = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = undefined;\n }\n if (messageHandlerRef.current) {\n window.removeEventListener(\"message\", messageHandlerRef.current);\n messageHandlerRef.current = undefined;\n }\n }, []);\n\n useEffect(() => stopHandoff, [stopHandoff]);\n\n // Also abandons a still-pending attempt, so a popup left open while another\n // auth method connects can't report a failure afterwards.\n const clearConnectionError = useCallback(() => {\n stopHandoff();\n setConnectionError(null);\n }, [stopHandoff]);\n\n const openAuthorizeUrl = useCallback(\n async (config?: Record<string, string>, accountDisplayName?: string) => {\n // Stop watching any popup from a previous invocation\n stopHandoff();\n // Reset state for this attempt\n receivedMessageRef.current = false;\n setConnectionError(null);\n\n // need to do this synchronously in the event handler to avoid popup blocker notifications\n const win = window.open(`${baseUrl}/pipes/redirecting`, \"_blank\");\n // A blocked popup yields null; fail loudly (caller catches) instead of\n // authorizing and then discarding the redirect into a phantom success.\n if (!win) {\n throw new Error(\"Unable to open the authorization window.\");\n }\n\n // caller will catch. Close the popup on failure so a network/permission/\n // config error doesn't strand a blank /pipes/redirecting tab.\n let authorization;\n try {\n authorization = await authorizeDataIntegration(\n integration.id,\n config,\n targetIntent === \"Add\"\n ? ADD_CONNECTION\n : targetIntent === \"Reauthorize\" && targetAccountId\n ? { intent: \"Reauthorize\", connectedAccountId: targetAccountId }\n : undefined,\n accountDisplayName,\n );\n } catch (error) {\n win.close();\n throw error;\n }\n const { url, handoffToken, redirectToken } = authorization;\n if (win) {\n win.location = url;\n const parsedUrl = new URL(url);\n const payload = {\n handoffToken: handoffToken ?? undefined,\n redirectToken,\n };\n\n messageHandlerRef.current = (event: MessageEvent) => {\n if (\n event.origin === parsedUrl.origin &&\n event.data?.redirectToken === redirectToken\n ) {\n receivedMessageRef.current = true;\n if (event.data.error === true) {\n setConnectionError({\n errorCode: event.data.errorCode,\n errorDescription: event.data.errorDescription,\n });\n }\n stopHandoff();\n }\n };\n window.addEventListener(\"message\", messageHandlerRef.current);\n\n let attempts = 0;\n intervalRef.current = setInterval(() => {\n attempts += 1;\n\n if (attempts >= HANDOFF_MAX_ATTEMPTS) {\n stopHandoff();\n return;\n }\n\n if (win && !win.closed) {\n win.postMessage(payload, parsedUrl.origin);\n } else {\n // Popup closed without sending any message: surface a generic failure.\n if (!receivedMessageRef.current) {\n setConnectionError({ errorCode: \"connection_failed\" });\n }\n stopHandoff();\n }\n }, HANDOFF_INTERVAL_MS);\n }\n },\n [\n authorizeDataIntegration,\n integration.id,\n baseUrl,\n stopHandoff,\n targetIntent,\n targetAccountId,\n ],\n );\n\n return { openAuthorizeUrl, connectionError, clearConnectionError };\n};\n\n/** Row status after the OAuth handoff reported a failure. */\nfunction ConnectionFailedStatus() {\n return (\n <Status state=\"error\">\n <Translation\n defaultMessage=\"Connection failed\"\n id=\"iPsR87\"\n description=\"Status text shown when a connection attempt fails\"\n />\n </Status>\n );\n}\n\n/**\n * Returns the provider-declared `installation`-scope config fields that the\n * integration has not pinned a value for, sorted by descriptor `order`. These\n * are the fields the connect flow must prompt for (pin / prompt-if-unset).\n */\nfunction getUnpinnedInstallationFields(\n integration: DataIntegration,\n): DataIntegrationConfigField[] {\n return (integration.configFields ?? [])\n .filter(\n (field) =>\n field.scope === \"installation\" && !integration.config?.[field.key],\n )\n .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n}\n\n/**\n * Seed values for the descriptors from a stored `config` object, stringifying\n * the scalar values the inputs can round-trip and skipping anything else.\n */\nfunction getInitialConfigValues(\n fields: DataIntegrationConfigField[],\n storedConfig: Record<string, unknown>,\n): Record<string, string> {\n const values: Record<string, string> = {};\n for (const field of fields) {\n const stored = storedConfig[field.key];\n if (\n typeof stored === \"string\" ||\n typeof stored === \"number\" ||\n typeof stored === \"boolean\"\n ) {\n values[field.key] = String(stored);\n }\n }\n return values;\n}\n\n/**\n * Compile a descriptor `pattern` (+ optional flags), returning undefined when\n * it isn't valid regex syntax so the server's validation remains the backstop.\n *\n * Anchored as `^(?:…)$` to match the server, so an unanchored descriptor\n * pattern surfaces the same inline error here instead of passing client\n * validation and being rejected on submit.\n */\nfunction compileConfigFieldPattern(\n pattern: string,\n flags: string | undefined,\n): RegExp | undefined {\n try {\n return new RegExp(`^(?:${pattern})$`, flags);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Form state for a set of provider-declared config-field descriptors: the\n * collected values, inline validation against `required` / `pattern`, and the\n * `config` payload the connect endpoints accept. Shared by every connect\n * surface so descriptors are rendered and validated in exactly one place.\n *\n * `initialValues` prefills the inputs (e.g. from an existing installation's\n * stored config); `isDirty` reports whether the user actually changed any of\n * them, which callers use to decide whether to send `config` at all.\n */\nfunction useConfigFieldsForm(\n fields: DataIntegrationConfigField[],\n initialValues: Record<string, string> = {},\n) {\n const [values, setValues] = useState<Record<string, string>>(initialValues);\n const [errors, setErrors] = useState<Record<string, string | null>>({});\n const translate = useTranslation();\n\n const requiredMessage = translate({\n defaultMessage: \"This field is required\",\n id: \"B2HvfC\",\n description:\n \"Validation error shown when a required configuration field is left empty\",\n });\n const patternMessage = translate({\n defaultMessage: \"Enter a valid value.\",\n id: \"2XWaGz\",\n description:\n \"Validation error shown when a configuration field value does not match the expected format\",\n });\n\n const setValue = (key: string, value: string) => {\n setValues((prev) => ({ ...prev, [key]: value }));\n setErrors((prev) => (prev[key] ? { ...prev, [key]: null } : prev));\n };\n\n const reset = () => {\n setValues(initialValues);\n setErrors({});\n };\n\n const validate = () => {\n const nextErrors: Record<string, string | null> = {};\n let valid = true;\n for (const field of fields) {\n const value = (values[field.key] ?? \"\").trim();\n if (field.required && !value) {\n nextErrors[field.key] = requiredMessage;\n valid = false;\n continue;\n }\n if (value && field.pattern) {\n const patternRegExp = compileConfigFieldPattern(\n field.pattern,\n field.patternFlags,\n );\n if (patternRegExp && !patternRegExp.test(value)) {\n nextErrors[field.key] = patternMessage;\n valid = false;\n continue;\n }\n }\n nextErrors[field.key] = null;\n }\n setErrors(nextErrors);\n return valid;\n };\n\n const buildConfig = () => {\n const config: Record<string, string> = {};\n for (const field of fields) {\n const value = (values[field.key] ?? \"\").trim();\n if (value) {\n config[field.key] = value;\n }\n }\n return config;\n };\n\n /**\n * The full `config` object to write, given the config the API returned for\n * the installation. The write is a wholesale replace, so keys the widget\n * never rendered (pinned at the integration level, or unknown to these\n * descriptors) are preserved as received rather than dropped.\n */\n const buildConfigPayload = (storedConfig: Record<string, unknown>) => {\n const payload: Record<string, unknown> = { ...storedConfig };\n for (const field of fields) {\n const value = (values[field.key] ?? \"\").trim();\n if (value) {\n payload[field.key] = value;\n } else {\n delete payload[field.key];\n }\n }\n return payload;\n };\n\n const hasMissingRequired = fields.some(\n (field) => field.required && !(values[field.key] ?? \"\").trim(),\n );\n\n const isDirty = fields.some(\n (field) => (values[field.key] ?? \"\") !== (initialValues[field.key] ?? \"\"),\n );\n\n return {\n values,\n errors,\n setValue,\n reset,\n validate,\n buildConfig,\n buildConfigPayload,\n hasMissingRequired,\n isDirty,\n };\n}\n\n/**\n * Renders config-field descriptors as labelled inputs (secret descriptors get a\n * password field), with inline validation errors wired up via `aria-invalid` /\n * `aria-describedby`.\n *\n * Stacks as label → description → input → hint, so the description is read\n * before the field is filled and the `default` hint sits with the value it\n * describes. (The dashboard's config form instead merges both into one help\n * line below the input; the copy matches, the placement follows the widget's\n * existing description-above-input layout.)\n *\n * The `default` — falling back to the display-only `example` — is the\n * placeholder, and is never filled in as a value: submitting it would pin it and\n * freeze it, while leaving the field empty lets the API resolve the default on\n * read, so a later change to it reaches existing installations.\n */\nfunction ConfigFieldInputs({\n idPrefix,\n fields,\n values,\n errors,\n onChange,\n}: {\n idPrefix: string;\n fields: DataIntegrationConfigField[];\n values: Record<string, string>;\n errors: Record<string, string | null>;\n onChange: (key: string, value: string) => void;\n}) {\n return fields.map((field) => {\n const fieldId = `${idPrefix}-${field.key}`;\n const errorId = `${fieldId}-error`;\n const descriptionId = `${fieldId}-description`;\n const error = errors[field.key];\n const Control = field.secret ? PasswordField : TextField;\n const defaultHint =\n field.default !== undefined ? (\n <Translation\n defaultMessage=\"Defaults to {value} when left blank.\"\n id=\"MTNqSC\"\n description=\"Hint naming the value used when a configuration field is left blank\"\n values={{ value: field.default }}\n />\n ) : null;\n // The hint and the error share the slot under the input; the error wins.\n const hintId = `${fieldId}-hint`;\n const showHint = !error && defaultHint;\n const describedBy =\n [\n field.description ? descriptionId : null,\n showHint ? hintId : null,\n error ? errorId : null,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n return (\n <Flex key={field.key} direction=\"column\" gap=\"1\">\n <Label htmlFor={fieldId}>{field.label}</Label>\n {field.description ? (\n <Text color=\"gray\" size=\"2\" id={descriptionId} mb=\"1\">\n {field.description}\n </Text>\n ) : null}\n <Control\n id={fieldId}\n value={values[field.key] ?? \"\"}\n placeholder={field.default ?? field.example}\n autoComplete=\"off\"\n required={field.required || undefined}\n aria-invalid={!!error || undefined}\n aria-describedby={describedBy}\n onChange={(event) => onChange(field.key, event.target.value)}\n />\n {showHint ? (\n <Text color=\"gray\" size=\"2\" id={hintId}>\n {defaultHint}\n </Text>\n ) : null}\n {error ? (\n <Text color=\"red\" size=\"2\" id={errorId}>\n {error}\n </Text>\n ) : null}\n </Flex>\n );\n });\n}\n\n/** Gray dot separator shown between the logos in the connect-dialog header. */\nfunction LogoSeparator() {\n return (\n <DotsHorizontalIcon\n width=\"20\"\n height=\"20\"\n style={{ color: \"var(--gray-8)\" }}\n />\n );\n}\n\n/**\n * Shared connect-dialog header: the WorkOS → provider icon row and the\n * \"{app} uses WorkOS to connect to {provider}\" title.\n */\nfunction ConnectDialogHeader({\n integration,\n}: {\n integration: DataIntegration;\n}) {\n const branding = useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"Branding\"),\n queryFn: (sdk) => sdk.Branding(),\n });\n const logo =\n branding.data?.branding.logoDarkPath ??\n branding.data?.branding.logoLightPath;\n const appName = branding.data?.branding.displayName ?? \"This application\";\n\n return (\n <>\n <Flex justify=\"center\" align=\"center\" gap=\"2\" mt=\"2\">\n {logo && (\n <>\n <IconPanel color=\"panel\" style={{ width: \"48px\", height: \"48px\" }}>\n <ProviderIcon\n size=\"2\"\n provider=\"workos\"\n style={{ backgroundImage: `url(${logo})` }}\n />\n </IconPanel>\n <LogoSeparator />\n </>\n )}\n <IconPanel\n color=\"panel\"\n style={{\n ...(logo ? { borderWidth: 0 } : undefined),\n width: \"48px\",\n height: \"48px\",\n }}\n >\n <ProviderIcon size=\"2\" provider=\"workos\" />\n </IconPanel>\n <LogoSeparator />\n <IconPanel color=\"panel\" style={{ width: \"48px\", height: \"48px\" }}>\n <DataIntegrationIcon size=\"2\" integration={integration} />\n </IconPanel>\n </Flex>\n <Dialog.Title size=\"2\" mt=\"5\" mb=\"5\" weight={\"bold\"} align=\"center\">\n <Translation\n defaultMessage=\"{appName} uses WorkOS to connect to {integrationName}.\"\n id=\"ujRDBH\"\n description=\"Dialog title explaining the app connection flow\"\n values={{ appName, integrationName: integration.name }}\n />\n </Dialog.Title>\n </>\n );\n}\n\n/**\n * Shared connect-dialog explainer card: \"you'll be redirected to sign in\" +\n * \"your credentials remain secure\".\n */\nfunction ConnectExplainerCard({\n integration,\n}: {\n integration: DataIntegration;\n}) {\n return (\n <Card>\n <Flex direction=\"column\" gap=\"4\">\n <Flex gap=\"2\" align=\"center\">\n <IconPanel color=\"gray\" style={{ width: \"32px\", height: \"32px\" }}>\n <GlobeIcon />\n </IconPanel>\n <Flex direction=\"column\">\n <Text size=\"1\" weight=\"bold\">\n <Translation\n defaultMessage=\"You'll be redirected to sign in with {integrationName}.\"\n id=\"g+n4aY\"\n description=\"Instruction about redirect to sign in\"\n values={{ integrationName: integration.name }}\n />\n </Text>\n <Text size=\"1\">\n <Translation\n defaultMessage=\"Authorize access to connect your account.\"\n id=\"fxVS34\"\n description=\"Instruction to authorize access\"\n />\n </Text>\n </Flex>\n </Flex>\n <Flex gap=\"2\" align=\"center\">\n <IconPanel color=\"gray\" style={{ width: \"32px\", height: \"32px\" }}>\n <LockClosedIcon />\n </IconPanel>\n <Flex direction=\"column\">\n <Text size=\"1\" weight=\"bold\">\n <Translation\n defaultMessage=\"Your credentials remain secure.\"\n id=\"gM3bot\"\n description=\"Security message about credentials\"\n />\n </Text>\n <Text size=\"1\">\n <Translation\n defaultMessage=\"WorkOS never sees your credentials.\"\n id=\"kC9Fwe\"\n description=\"Security message about WorkOS not seeing credentials\"\n />\n </Text>\n </Flex>\n </Flex>\n </Flex>\n </Card>\n );\n}\n\n/**\n * The single connect dialog for all non-API (OAuth) providers. When the\n * provider declares unpinned `installation`-scope config fields (e.g. a Zendesk\n * subdomain), it opens on a field-collection step (values validated against the\n * descriptor `required` / `pattern`) before the redirect explainer; otherwise\n * it opens directly on the explainer. Collected values are submitted as\n * `config` on the POST authorize call. Controlled so it backs the initial\n * connect flow, the dual-method OAuth option, and reauthorization.\n */\nfunction ConnectDialog({\n integration,\n fields,\n open,\n onOpenChange,\n onConnect,\n collectName = false,\n}: {\n integration: DataIntegration;\n fields: DataIntegrationConfigField[];\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /**\n * Starts the authorization, from the row that owns its result (and so the\n * connection it targets): `openAuthorizeUrl` of\n * {@link useOpenDataIntegrationAuthorizeUrl}.\n */\n onConnect: ConnectHandler;\n /**\n * Asks for an optional name for the connection the authorization creates.\n * Only set when adding a connection; a first connect leaves naming to\n * Rename.\n */\n collectName?: boolean;\n}) {\n // Providers without fields to collect skip straight to the explainer.\n const initialStep = fields.length > 0 ? \"fields\" : \"review\";\n const [step, setStep] = useState<\"fields\" | \"review\">(initialStep);\n const [submitError, setSubmitError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [name, setName] = useState(\"\");\n const configForm = useConfigFieldsForm(fields);\n const translate = useTranslation();\n const nameField = collectName && (\n <ConnectionNameField\n id={`pipes-connect-name-${integration.id}`}\n value={name}\n onChange={setName}\n />\n );\n\n const genericConnectError = translate({\n defaultMessage: \"We couldn't start the connection. Please try again.\",\n id: \"zGw1ma\",\n description:\n \"Fallback error shown when starting the connection fails for a non-specific reason\",\n });\n\n const reset = () => {\n setStep(initialStep);\n configForm.reset();\n setName(\"\");\n setSubmitError(null);\n setIsSubmitting(false);\n };\n\n const handleConnect = async () => {\n setSubmitError(null);\n setIsSubmitting(true);\n try {\n // Opens the popup synchronously within this click before awaiting.\n await onConnect(configForm.buildConfig(), collectName ? name : undefined);\n onOpenChange(false);\n } catch (error) {\n // Surface a message for every failure mode (ApiError, network, blocked\n // popup, etc.) so the dialog never fails silently.\n setSubmitError(\n error instanceof ApiError && error.message\n ? error.message\n : genericConnectError,\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <Dialog.Root\n open={open}\n onOpenChange={(next) => {\n onOpenChange(next);\n if (!next) {\n reset();\n }\n }}\n >\n <Dialog.Content maxWidth=\"430px\">\n <ConnectDialogHeader integration={integration} />\n\n {step === \"fields\" ? (\n <>\n <Card>\n <Flex direction=\"column\" gap=\"4\">\n {nameField}\n <ConfigFieldInputs\n idPrefix=\"pipes-config\"\n fields={fields}\n values={configForm.values}\n errors={configForm.errors}\n onChange={configForm.setValue}\n />\n </Flex>\n </Card>\n <Flex justify=\"end\" gap=\"3\" mt=\"5\">\n <Dialog.Close>\n <Button variant=\"secondary\">\n <Translation\n defaultMessage=\"Cancel\"\n id=\"hHNj31\"\n description=\"Cancel button text\"\n />\n </Button>\n </Dialog.Close>\n <Button\n type=\"button\"\n disabled={configForm.hasMissingRequired}\n onClick={() => {\n if (configForm.validate()) {\n setStep(\"review\");\n }\n }}\n >\n <Translation\n defaultMessage=\"Next\"\n id=\"L2fmxK\"\n description=\"Button to advance to the next step of the connect flow\"\n />\n </Button>\n </Flex>\n </>\n ) : (\n <>\n {submitError && (\n <Callout.Root mb=\"3\" color=\"red\" role=\"alert\">\n <Callout.Text>{submitError}</Callout.Text>\n </Callout.Root>\n )}\n {/* With config fields, the name was asked for on the first step. */}\n {fields.length === 0 && nameField && (\n <Card mb=\"3\">{nameField}</Card>\n )}\n <ConnectExplainerCard integration={integration} />\n <Flex justify=\"end\" gap=\"3\" mt=\"5\">\n {fields.length > 0 ? (\n <Button\n variant=\"secondary\"\n type=\"button\"\n onClick={() => setStep(\"fields\")}\n >\n <Translation\n defaultMessage=\"Back\"\n id=\"J9MvVP\"\n description=\"Button to return to the previous step of the connect flow\"\n />\n </Button>\n ) : (\n <Dialog.Close>\n <Button variant=\"secondary\">\n <Translation\n defaultMessage=\"Cancel\"\n id=\"hHNj31\"\n description=\"Cancel button text\"\n />\n </Button>\n </Dialog.Close>\n )}\n <Button\n type=\"button\"\n loading={isSubmitting}\n disabled={isSubmitting}\n onClick={handleConnect}\n >\n <Translation\n defaultMessage=\"Connect\"\n id=\"16WmG0\"\n description=\"Connect button with external link\"\n trailingSpace\n />\n <ExternalLinkIcon aria-hidden />\n </Button>\n </Flex>\n </>\n )}\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/**\n * Connect button for a not-yet-connected OAuth provider. Opens the unified\n * {@link ConnectDialog}, which prompts for any unpinned `installation`-scope\n * config fields before the redirect explainer.\n */\nfunction ConnectIntegrationButton({\n integration,\n onConnect,\n}: {\n integration: DataIntegration;\n onConnect: ConnectHandler;\n}) {\n const [open, setOpen] = useState(false);\n const fields = getUnpinnedInstallationFields(integration);\n\n return (\n <>\n <ConnectDialog\n integration={integration}\n fields={fields}\n open={open}\n onOpenChange={setOpen}\n onConnect={onConnect}\n />\n <Button variant=\"secondary\" onClick={() => setOpen(true)}>\n <Translation\n defaultMessage=\"Connect\"\n id=\"quvdFp\"\n description=\"Button to connect an integration\"\n />\n </Button>\n </>\n );\n}\n\nconst API_KEY_REDACTED_PREFIX = \"••••\";\n\n/**\n * Stores an API key for the integration: the member's own installation, or,\n * with `owner=\"organization\"`, the one the organization shares with everyone\n * (`installation` then names that shared account).\n *\n * The write lands on `installation` (see {@link getConnectionTarget}) unless a\n * `target` says otherwise — `ADD_CONNECTION` with a null `installation` stores\n * the key as another connection.\n */\nfunction ApiKeyDialog({\n integration,\n installation = integration.installation,\n owner = \"user\",\n target = getConnectionTarget(installation),\n open,\n onOpenChange,\n onSuccess,\n collectName = false,\n}: {\n integration: DataIntegration;\n installation?: DataInstallation | null;\n owner?: ConnectionOwner;\n target?: ConnectionTarget;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Called after the key is saved. */\n onSuccess?: () => void;\n /**\n * Asks for an optional name for the connection the key creates. Only set\n * when adding a connection; a first connect leaves naming to Rename.\n */\n collectName?: boolean;\n}) {\n const invalidateConnections = useInvalidateConnections(owner);\n const [name, setName] = useState(\"\");\n const isRotation =\n installation?.auth_method === \"api_key\" &&\n installation.state === \"connected\";\n const last4 = installation?.api_key_last_4;\n const maskedKey = last4 ? `${API_KEY_REDACTED_PREFIX}${last4}` : \"\";\n\n const [secret, setSecret] = useState(\"\");\n const translate = useTranslation();\n\n const apiKeyPlaceholder = translate({\n defaultMessage: \"Enter your API key\",\n id: \"MzSxEF\",\n description: \"Placeholder for the API key input field\",\n });\n\n const onUpserted = () => {\n onOpenChange(false);\n invalidateConnections();\n onSuccess?.();\n };\n const userUpsert = useClientGraphqlMutation({\n mutationFn: (sdk, input: CreateDataProviderConnectionInput) =>\n sdk.CreateDataProviderConnection({ input }),\n onSuccess: onUpserted,\n });\n const organizationUpsert = useClientGraphqlMutation({\n mutationFn: (sdk, input: CreateOrganizationDataProviderConnectionInput) =>\n sdk.CreateOrganizationDataProviderConnection({ input }),\n onSuccess: onUpserted,\n });\n const { error, reset, isPending } =\n owner === \"organization\" ? organizationUpsert : userUpsert;\n const upsertApiKey = (apiKey: string) => {\n const input = {\n dataProviderId: integration.id,\n apiKey,\n ...toCreationTargetInput(target),\n ...(collectName ? toAccountDisplayNameInput(name) : {}),\n };\n if (owner === \"organization\") {\n organizationUpsert.mutate(input);\n } else {\n userUpsert.mutate(input);\n }\n };\n\n // The component is only mounted while open (conditional rendering in\n // ApiKeyConnectButton / ProviderStatus), so state resets on mount.\n // We only need to reset the mutation state when the dialog opens in\n // case the same instance was reused.\n useEffect(() => {\n reset();\n }, [reset]);\n\n const errorMessage = (() => {\n if (!error) return null;\n if (error instanceof ApiError && error.message) {\n return error.message;\n }\n return null;\n })();\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content maxWidth=\"430px\">\n <Dialog.Title size=\"3\" weight=\"bold\">\n {isRotation ? (\n <Translation\n defaultMessage=\"Rotate API key for {integrationName}\"\n id=\"8+NN3t\"\n description=\"Dialog title for rotating an API key\"\n values={{ integrationName: integration.name }}\n />\n ) : (\n <Translation\n defaultMessage=\"Connect {integrationName} with API key\"\n id=\"EyItbA\"\n description=\"Dialog title for connecting with an API key\"\n values={{ integrationName: integration.name }}\n />\n )}\n </Dialog.Title>\n\n {/*\n * The provider's own description. Built-in providers are self-evident,\n * but a custom provider's definition copy is the only thing telling the\n * tenant which key to paste and where to mint it. Rendered as the\n * dialog's description so it's announced with the dialog rather than\n * being an unassociated paragraph.\n */}\n {integration.description && (\n <Dialog.Description color=\"gray\" mt=\"1\">\n {integration.description}\n </Dialog.Description>\n )}\n\n {error && (\n <Callout.Root my=\"3\" color=\"red\" role=\"alert\">\n <Callout.Text>\n {errorMessage ?? (\n <Translation\n defaultMessage=\"An error occurred. Please check the value and try again.\"\n id=\"bYLbLL\"\n description=\"Generic error message for API key submission failure\"\n />\n )}\n </Callout.Text>\n </Callout.Root>\n )}\n\n <Flex direction=\"column\" gap=\"4\" mt=\"2\">\n {collectName && (\n <ConnectionNameField\n id={`pipes-api-key-name-${integration.id}`}\n value={name}\n onChange={setName}\n />\n )}\n {isRotation && last4 && (\n <Flex direction=\"column\" gap=\"1\">\n <Label>\n <Translation\n defaultMessage=\"Current API key\"\n id=\"+odk8g\"\n description=\"Label for the current masked API key\"\n />\n </Label>\n <Text size=\"2\" color=\"gray\">\n {maskedKey}\n </Text>\n </Flex>\n )}\n\n <Flex direction=\"column\" gap=\"1\">\n <Label>\n {isRotation ? (\n <Translation\n defaultMessage=\"New API key\"\n id=\"L3AmMK\"\n description=\"Label for the new API key input when rotating\"\n />\n ) : (\n <Translation\n defaultMessage=\"API key\"\n id=\"Xnkv+J\"\n description=\"Label for the API key input\"\n />\n )}\n </Label>\n <PasswordField\n value={secret}\n autoComplete=\"off\"\n placeholder={apiKeyPlaceholder}\n onChange={(event) => setSecret(event.target.value)}\n />\n </Flex>\n </Flex>\n\n <Flex justify=\"end\" gap=\"3\" mt=\"5\">\n <Dialog.Close>\n <Button variant=\"secondary\">\n <Translation\n defaultMessage=\"Cancel\"\n id=\"hHNj31\"\n description=\"Cancel button text\"\n />\n </Button>\n </Dialog.Close>\n <Button\n type=\"button\"\n disabled={isPending || !secret.trim()}\n loading={isPending}\n onClick={() => upsertApiKey(secret.trim())}\n >\n {isRotation ? (\n <Translation\n defaultMessage=\"Rotate\"\n id=\"LAh+p5\"\n description=\"Button to rotate an API key\"\n />\n ) : (\n <Translation\n defaultMessage=\"Connect\"\n id=\"quvdFp\"\n description=\"Button to connect an integration\"\n />\n )}\n </Button>\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\nfunction ApiKeyConnectButton({\n integration,\n}: {\n integration: DataIntegration;\n}) {\n const [open, setOpen] = useState(false);\n\n return (\n <>\n {open && (\n <ApiKeyDialog\n integration={integration}\n open={open}\n onOpenChange={setOpen}\n />\n )}\n <Button variant=\"secondary\" onClick={() => setOpen(true)}>\n <Translation\n defaultMessage=\"Connect\"\n id=\"quvdFp\"\n description=\"Button to connect an integration\"\n />\n </Button>\n </>\n );\n}\n\n/**\n * Connect form for the `client_credentials` auth method: the provider's client\n * id and secret plus any unpinned `installation`-scope config fields, rendered\n * generically from the descriptors via {@link ConfigFieldInputs}. Submits to\n * PUT `/DataIntegrations/:slug/client-credentials`, which also handles\n * replacing the credentials of an existing client-credentials installation.\n *\n * For an existing installation the form is prefilled from it: the client id as\n * received, the stored secret as a redacted mask that clears on focus (the\n * real value is never sent to the widget, so a new secret must be re-entered\n * to save), and the config fields from `installation.config`. `config` is only\n * included in the payload when the user edits a config field, since the API\n * keeps the stored config when the key is absent; when it is included it is\n * the full round-tripped object, because the write replaces config wholesale.\n */\nfunction ClientCredentialsDialog({\n integration,\n installation = integration.installation,\n owner = \"user\",\n target = getConnectionTarget(installation),\n fields,\n open,\n onOpenChange,\n onSuccess,\n collectName = false,\n}: {\n integration: DataIntegration;\n installation?: DataInstallation | null;\n owner?: ConnectionOwner;\n /** As on {@link ApiKeyDialog}: defaults to `installation` itself. */\n target?: ConnectionTarget;\n fields: DataIntegrationConfigField[];\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Called after the credentials are saved. */\n onSuccess?: () => void;\n /** As on {@link ApiKeyDialog}. */\n collectName?: boolean;\n}) {\n const invalidateConnections = useInvalidateConnections(owner);\n const [name, setName] = useState(\"\");\n const isUpdate = installation?.auth_method === \"client_credentials\";\n const storedConfig = useMemo(\n () => (isUpdate ? (installation?.config ?? {}) : {}),\n [isUpdate, installation?.config],\n );\n const initialConfigValues = useMemo(\n () => getInitialConfigValues(fields, storedConfig),\n [fields, storedConfig],\n );\n const redactedSecret = buildRedactedSecret(\n isUpdate ? installation?.client_secret_last_4 : null,\n );\n\n const [clientId, setClientId] = useState(\n (isUpdate ? installation?.client_id : null) ?? \"\",\n );\n const [clientSecret, setClientSecret] = useState(redactedSecret);\n const configForm = useConfigFieldsForm(fields, initialConfigValues);\n const translate = useTranslation();\n\n const clientIdPlaceholder = translate({\n defaultMessage: \"Enter your client ID\",\n id: \"5YTAFo\",\n description: \"Placeholder for the client credentials client ID input\",\n });\n const clientSecretPlaceholder = translate({\n defaultMessage: \"Enter your client secret\",\n id: \"53f0B7\",\n description: \"Placeholder for the client credentials client secret input\",\n });\n\n // The widget never holds the real secret, so the prefilled mask can't be\n // submitted: the PUT requires a client secret and re-entry is the only way\n // to supply one.\n const secretMissing = !clientSecret.trim() || isRedactedSecret(clientSecret);\n\n const onUpserted = () => {\n onOpenChange(false);\n invalidateConnections();\n onSuccess?.();\n };\n const userUpsert = useClientGraphqlMutation({\n mutationFn: async (\n sdk,\n input: ConnectDataProviderWithClientCredentialsInput,\n ) => {\n const { connectDataProviderWithClientCredentials: result } =\n await sdk.ConnectDataProviderWithClientCredentials({ input });\n return unwrapClientCredentialsConnection(result);\n },\n onSuccess: onUpserted,\n });\n const organizationUpsert = useClientGraphqlMutation({\n mutationFn: async (\n sdk,\n input: ConnectOrganizationDataProviderWithClientCredentialsInput,\n ) => {\n const { connectOrganizationDataProviderWithClientCredentials: result } =\n await sdk.ConnectOrganizationDataProviderWithClientCredentials({\n input,\n });\n return unwrapClientCredentialsConnection(result);\n },\n onSuccess: onUpserted,\n });\n const { error, isPending } =\n owner === \"organization\" ? organizationUpsert : userUpsert;\n\n // Server errors — including the 409 raised when an installation already\n // exists with a different auth method — are surfaced in the banner.\n const errorMessage =\n error instanceof ApiError && error.message ? error.message : null;\n\n const handleSubmit = () => {\n if (!configForm.validate()) {\n return;\n }\n // Untouched config fields mean no `config` key at all: the API preserves\n // the stored config when it's absent, and sending the prefilled object\n // back would make every credential update a config write too.\n const config = configForm.isDirty\n ? configForm.buildConfigPayload(storedConfig)\n : undefined;\n const input = {\n dataProviderId: integration.id,\n clientId: clientId.trim(),\n clientSecret: clientSecret.trim(),\n config: toConfigEntries(config),\n ...toCreationTargetInput(target),\n ...(collectName ? toAccountDisplayNameInput(name) : {}),\n };\n if (owner === \"organization\") {\n organizationUpsert.mutate(input);\n } else {\n userUpsert.mutate(input);\n }\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content maxWidth=\"430px\">\n <Dialog.Title size=\"3\" weight=\"bold\">\n {isUpdate ? (\n <Translation\n defaultMessage=\"Update client credentials for {integrationName}\"\n id=\"/D85zF\"\n description=\"Dialog title for updating stored client credentials\"\n values={{ integrationName: integration.name }}\n />\n ) : (\n <Translation\n defaultMessage=\"Connect {integrationName} with client credentials\"\n id=\"x+7tw3\"\n description=\"Dialog title for connecting with client credentials\"\n values={{ integrationName: integration.name }}\n />\n )}\n </Dialog.Title>\n\n {error && (\n <Callout.Root my=\"3\" color=\"red\" role=\"alert\">\n <Callout.Text>\n {errorMessage ?? (\n <Translation\n defaultMessage=\"An error occurred. Please check the value and try again.\"\n id=\"bYLbLL\"\n description=\"Generic error message for API key submission failure\"\n />\n )}\n </Callout.Text>\n </Callout.Root>\n )}\n\n <Flex direction=\"column\" gap=\"4\" mt=\"2\">\n {collectName && (\n <ConnectionNameField\n id={`pipes-client-credentials-name-${integration.id}`}\n value={name}\n onChange={setName}\n />\n )}\n <Flex direction=\"column\" gap=\"1\">\n <Label htmlFor=\"pipes-client-credentials-client-id\">\n <Translation\n defaultMessage=\"Client ID\"\n id=\"/Cv5P1\"\n description=\"Label for the client credentials client ID input\"\n />\n </Label>\n <TextField\n id=\"pipes-client-credentials-client-id\"\n value={clientId}\n autoComplete=\"off\"\n placeholder={clientIdPlaceholder}\n onChange={(event) => setClientId(event.target.value)}\n />\n </Flex>\n\n <Flex direction=\"column\" gap=\"1\">\n <Label htmlFor=\"pipes-client-credentials-client-secret\">\n <Translation\n defaultMessage=\"Client secret\"\n id=\"uScBDj\"\n description=\"Label for the client credentials client secret input\"\n />\n </Label>\n {isUpdate && (\n <Text\n color=\"gray\"\n size=\"2\"\n id=\"pipes-client-credentials-client-secret-description\"\n mb=\"1\"\n >\n <Translation\n defaultMessage=\"Enter the client secret again to save any changes.\"\n id=\"ZrNPCF\"\n description=\"Help text explaining the client secret must be re-entered to save an update\"\n />\n </Text>\n )}\n <PasswordField\n id=\"pipes-client-credentials-client-secret\"\n value={clientSecret}\n autoComplete=\"off\"\n // The mask is what's shown, so render it as text: a password\n // input would re-bullet its last four digits away.\n type={isRedactedSecret(clientSecret) ? \"text\" : undefined}\n placeholder={clientSecretPlaceholder}\n aria-describedby={\n isUpdate\n ? \"pipes-client-credentials-client-secret-description\"\n : undefined\n }\n onChange={(event) => setClientSecret(event.target.value)}\n onFocus={() => {\n if (isRedactedSecret(clientSecret)) {\n setClientSecret(\"\");\n }\n }}\n onBlur={() => {\n if (clientSecret === \"\") {\n setClientSecret(redactedSecret);\n }\n }}\n />\n </Flex>\n\n <ConfigFieldInputs\n idPrefix=\"pipes-client-credentials-config\"\n fields={fields}\n values={configForm.values}\n errors={configForm.errors}\n onChange={configForm.setValue}\n />\n </Flex>\n\n <Flex justify=\"end\" gap=\"3\" mt=\"5\">\n <Dialog.Close>\n <Button variant=\"secondary\">\n <Translation\n defaultMessage=\"Cancel\"\n id=\"hHNj31\"\n description=\"Cancel button text\"\n />\n </Button>\n </Dialog.Close>\n <Button\n type=\"button\"\n disabled={\n isPending ||\n !clientId.trim() ||\n secretMissing ||\n configForm.hasMissingRequired\n }\n loading={isPending}\n onClick={handleSubmit}\n >\n {isUpdate ? (\n <Translation\n defaultMessage=\"Save\"\n id=\"RT8KNi\"\n description=\"Save button text\"\n />\n ) : (\n <Translation\n defaultMessage=\"Connect\"\n id=\"quvdFp\"\n description=\"Button to connect an integration\"\n />\n )}\n </Button>\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\nfunction ClientCredentialsConnectButton({\n integration,\n}: {\n integration: DataIntegration;\n}) {\n const [open, setOpen] = useState(false);\n const fields = getUnpinnedInstallationFields(integration);\n\n return (\n <>\n {open && (\n <ClientCredentialsDialog\n integration={integration}\n fields={fields}\n open={open}\n onOpenChange={setOpen}\n />\n )}\n <Button variant=\"secondary\" onClick={() => setOpen(true)}>\n <Translation\n defaultMessage=\"Connect\"\n id=\"quvdFp\"\n description=\"Button to connect an integration\"\n />\n </Button>\n </>\n );\n}\n\n/**\n * The methods another connection can be added with right now, in the order\n * the Connect menus offer them. Empty when the server reports no add available\n * (at the cap, multiple connections off, or no method currently usable).\n */\nfunction getAddConnectionMethods(\n capabilities: AddConnectionCapabilities,\n): DataIntegrationAuthMethod[] {\n if (!capabilities.canAddConnection) {\n return [];\n }\n return CONNECT_AUTH_METHODS.filter((method) =>\n capabilities.addConnectionMethods.includes(method),\n );\n}\n\n/** One menu item per connect method, as the Connect menus list them. */\nfunction ConnectMethodItems({\n methods,\n onSelect,\n}: {\n methods: DataIntegrationAuthMethod[];\n onSelect: (method: DataIntegrationAuthMethod) => void;\n}) {\n return (\n <>\n {methods.includes(\"oauth\") && (\n <DropdownMenu.Item onClick={() => onSelect(\"oauth\")}>\n <Flex gap=\"4\" width=\"100%\" justify=\"between\" align=\"center\">\n <Translation\n defaultMessage=\"Sign in with OAuth\"\n id=\"ssNz+0\"\n description=\"Menu option to connect via OAuth\"\n trailingSpace\n />\n <ExternalLinkIcon aria-hidden />\n </Flex>\n </DropdownMenu.Item>\n )}\n {methods.includes(\"client_credentials\") && (\n <DropdownMenu.Item onClick={() => onSelect(\"client_credentials\")}>\n <Translation\n defaultMessage=\"Enter client credentials\"\n id=\"Y/87Vt\"\n description=\"Menu option to connect via client credentials\"\n />\n </DropdownMenu.Item>\n )}\n {methods.includes(\"api_key\") && (\n <DropdownMenu.Item onClick={() => onSelect(\"api_key\")}>\n <Translation\n defaultMessage=\"Enter API key\"\n id=\"8mq2DA\"\n description=\"Menu option to connect via API key\"\n />\n </DropdownMenu.Item>\n )}\n </>\n );\n}\n\n/**\n * Connect entry point for a provider that supports more than one auth method:\n * a menu with one item per method, each opening that method's dialog.\n */\nfunction MultiMethodConnectButton({\n integration,\n methods,\n onConnect,\n onConnected,\n}: {\n integration: DataIntegration;\n methods: DataIntegrationAuthMethod[];\n onConnect: ConnectHandler;\n /** Called after an API key or client credentials connection succeeds. */\n onConnected?: () => void;\n}) {\n const [apiKeyOpen, setApiKeyOpen] = useState(false);\n const [oauthOpen, setOauthOpen] = useState(false);\n const [clientCredentialsOpen, setClientCredentialsOpen] = useState(false);\n const fields = getUnpinnedInstallationFields(integration);\n\n return (\n <>\n {apiKeyOpen && (\n <ApiKeyDialog\n integration={integration}\n open={apiKeyOpen}\n onOpenChange={setApiKeyOpen}\n onSuccess={onConnected}\n />\n )}\n {clientCredentialsOpen && (\n <ClientCredentialsDialog\n integration={integration}\n fields={fields}\n open={clientCredentialsOpen}\n onOpenChange={setClientCredentialsOpen}\n onSuccess={onConnected}\n />\n )}\n {methods.includes(\"oauth\") && (\n <ConnectDialog\n integration={integration}\n fields={fields}\n open={oauthOpen}\n onOpenChange={setOauthOpen}\n onConnect={onConnect}\n />\n )}\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <Button variant=\"secondary\">\n <Translation\n defaultMessage=\"Connect\"\n id=\"quvdFp\"\n description=\"Button to connect an integration\"\n />\n </Button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n <ConnectMethodItems\n methods={methods}\n onSelect={(method) =>\n method === \"oauth\"\n ? setOauthOpen(true)\n : method === \"client_credentials\"\n ? setClientCredentialsOpen(true)\n : setApiKeyOpen(true)\n }\n />\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n </>\n );\n}\n\n/**\n * Connecting another account to a provider the owner is already connected to:\n * `start(method, ADD_CONNECTION)` opens that method's connect dialog with the\n * `Add` intent, so the result is a new connection rather than a replacement\n * for the existing one.\n *\n * `start(method, undefined)` runs the same dialog untargeted instead, which\n * fills an empty compatibility slot — how an organization at the cap still\n * connects when only standard connections remain (`canConnect`). The target\n * is required rather than defaulted so that an explicit `undefined` can't be\n * mistaken for an `Add`.\n *\n * Owned by the provider's row: render `dialogs` there, and show\n * `connectionError` (an OAuth add that failed after its dialog closed) in that\n * row's status rather than on any one connection's.\n */\nfunction useAddConnectionFlow(\n integration: DataIntegration,\n owner: ConnectionOwner = \"user\",\n) {\n const [flow, setFlow] = useState<{\n method: DataIntegrationAuthMethod;\n target: ConnectionTarget | undefined;\n } | null>(null);\n const { openAuthorizeUrl, connectionError, clearConnectionError } =\n useOpenDataIntegrationAuthorizeUrl(integration, owner, flow?.target);\n const start = useCallback(\n (method: DataIntegrationAuthMethod, target: ConnectionTarget | undefined) =>\n setFlow({\n method,\n // Each start is one logical Add: it gets a fresh idempotency key that\n // every resubmit from this dialog reuses, so retrying an ambiguous\n // failure can't create a second connection.\n target: target?.intent === \"Add\" ? createAddConnectionTarget() : target,\n }),\n [],\n );\n const onOpenChange = (open: boolean) => {\n if (!open) {\n setFlow(null);\n }\n };\n\n // Only the sectioned experiences add connections, and every add creates\n // one, so each dialog asks for its name.\n const dialogs =\n flow?.method === \"api_key\" ? (\n <ApiKeyDialog\n integration={integration}\n installation={null}\n owner={owner}\n target={flow.target}\n open\n onOpenChange={onOpenChange}\n onSuccess={clearConnectionError}\n collectName\n />\n ) : flow?.method === \"client_credentials\" ? (\n <ClientCredentialsDialog\n integration={integration}\n installation={null}\n owner={owner}\n target={flow.target}\n fields={getUnpinnedInstallationFields(integration)}\n open\n onOpenChange={onOpenChange}\n onSuccess={clearConnectionError}\n collectName\n />\n ) : flow?.method === \"oauth\" ? (\n <ConnectDialog\n integration={integration}\n fields={getUnpinnedInstallationFields(integration)}\n open\n onOpenChange={onOpenChange}\n onConnect={openAuthorizeUrl}\n collectName\n />\n ) : null;\n\n return { start, dialogs, connectionError, clearConnectionError };\n}\n\n/**\n * The grouped provider row's Add connection button: a menu of the methods the\n * server says can add when there are several, otherwise straight into the one.\n * Renders nothing when no add is available. The row owns the flow it starts\n * ({@link useAddConnectionFlow}).\n */\nfunction AddConnectionButton({\n capabilities,\n onSelect,\n}: {\n capabilities: AddConnectionCapabilities;\n onSelect: (method: DataIntegrationAuthMethod) => void;\n}) {\n const methods = getAddConnectionMethods(capabilities);\n\n if (methods.length === 0) {\n return null;\n }\n\n return methods.length > 1 ? (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <Button variant=\"secondary\">\n <AddConnectionButtonLabel />\n </Button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n <ConnectMethodItems methods={methods} onSelect={onSelect} />\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n ) : (\n <Button variant=\"secondary\" onClick={() => onSelect(methods[0])}>\n <AddConnectionButtonLabel />\n </Button>\n );\n}\n\n/**\n * The Connect another account entry of a connection's overflow menu: a\n * submenu of methods when several can add. Renders nothing when no add is\n * available.\n */\nfunction ConnectAnotherAccountItem({\n capabilities,\n onSelect,\n}: {\n capabilities: AddConnectionCapabilities;\n onSelect: (method: DataIntegrationAuthMethod) => void;\n}) {\n const methods = getAddConnectionMethods(capabilities);\n\n if (methods.length === 0) {\n return null;\n }\n\n return methods.length > 1 ? (\n <DropdownMenu.Sub>\n <DropdownMenu.SubTrigger>\n <ConnectAnotherAccountMenuLabel />\n </DropdownMenu.SubTrigger>\n <DropdownMenu.SubContent>\n <ConnectMethodItems methods={methods} onSelect={onSelect} />\n </DropdownMenu.SubContent>\n </DropdownMenu.Sub>\n ) : (\n <DropdownMenu.Item onClick={() => onSelect(methods[0])}>\n <ConnectAnotherAccountMenuLabel />\n </DropdownMenu.Item>\n );\n}\n\nfunction ProviderStatus({ integration }: { integration: DataIntegration }) {\n const [disconnectOpen, setDisconnectOpen] = useState(false);\n const [apiKeyOpen, setApiKeyOpen] = useState(false);\n const [clientCredentialsOpen, setClientCredentialsOpen] = useState(false);\n const [reauthConfigOpen, setReauthConfigOpen] = useState(false);\n const {\n openAuthorizeUrl: authorizeEventHandler,\n connectionError,\n clearConnectionError,\n } = useOpenDataIntegrationAuthorizeUrl(integration);\n const translate = useTranslation();\n\n const pipeActionsTitle = translate({\n defaultMessage: \"Pipe actions\",\n id: \"1uF9ve\",\n description: \"Title for pipe actions dropdown button\",\n });\n\n // Unpinned installation fields must be re-collected on reauthorization too;\n // the authorize endpoint rejects them as missing otherwise.\n const unpinnedFields = getUnpinnedInstallationFields(integration);\n\n if (integration.installation) {\n const connected = integration.installation.state === \"connected\";\n const isApiKeyInstallation =\n integration.installation.auth_method === \"api_key\";\n const isClientCredentialsInstallation =\n integration.installation.auth_method === \"client_credentials\";\n\n return (\n <>\n <DisconnectAccountDialog\n integrationName={integration.name}\n installationId={integration.installation.id}\n open={disconnectOpen}\n onOpenChange={setDisconnectOpen}\n onSuccess={clearConnectionError}\n />\n {apiKeyOpen && (\n <ApiKeyDialog\n integration={integration}\n open={apiKeyOpen}\n onOpenChange={setApiKeyOpen}\n onSuccess={clearConnectionError}\n />\n )}\n {clientCredentialsOpen && (\n <ClientCredentialsDialog\n integration={integration}\n fields={unpinnedFields}\n open={clientCredentialsOpen}\n onOpenChange={setClientCredentialsOpen}\n onSuccess={clearConnectionError}\n />\n )}\n {unpinnedFields.length > 0 && !isClientCredentialsInstallation && (\n <ConnectDialog\n integration={integration}\n fields={unpinnedFields}\n open={reauthConfigOpen}\n onOpenChange={setReauthConfigOpen}\n onConnect={authorizeEventHandler}\n />\n )}\n <Flex align=\"center\" gap=\"4\">\n {connectionError ? (\n <ConnectionFailedStatus />\n ) : (\n <Status state={connected ? \"success\" : \"error\"}>\n {connected ? (\n <Translation\n defaultMessage=\"Connected\"\n id=\"i6Hxoz\"\n description=\"Status text for connected integration\"\n />\n ) : (\n <Translation\n defaultMessage=\"Requires reauthorization\"\n id=\"dqczQS\"\n description=\"Status text for integration needing reauthorization\"\n />\n )}\n </Status>\n )}\n {isClientCredentialsInstallation ? (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <IconButton title={pipeActionsTitle}>\n <DotsHorizontalIcon />\n </IconButton>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n <DropdownMenu.Item\n onClick={() => setClientCredentialsOpen(true)}\n >\n <Translation\n defaultMessage=\"Update client credentials\"\n id=\"daHKWE\"\n description=\"Menu option to update stored client credentials\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item\n variant=\"destructive\"\n onClick={() => setDisconnectOpen(true)}\n >\n <Translation\n defaultMessage=\"Disconnect account\"\n id=\"esZQrd\"\n description=\"Menu option to disconnect an account\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n ) : connected && isApiKeyInstallation ? (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <IconButton title={pipeActionsTitle}>\n <DotsHorizontalIcon />\n </IconButton>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n <DropdownMenu.Item onClick={() => setApiKeyOpen(true)}>\n <Translation\n defaultMessage=\"Rotate API key\"\n id=\"GML+c8\"\n description=\"Menu option to rotate the API key\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item\n variant=\"destructive\"\n onClick={() => setDisconnectOpen(true)}\n >\n <Translation\n defaultMessage=\"Disconnect account\"\n id=\"esZQrd\"\n description=\"Menu option to disconnect an account\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n ) : connected ? (\n <Button variant=\"secondary\" onClick={() => setDisconnectOpen(true)}>\n <Translation\n defaultMessage=\"Disconnect\"\n id=\"vMVXQh\"\n description=\"Button to disconnect an account\"\n />\n </Button>\n ) : isApiKeyInstallation ? (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <IconButton title={pipeActionsTitle}>\n <DotsHorizontalIcon />\n </IconButton>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n <DropdownMenu.Item onClick={() => setApiKeyOpen(true)}>\n <Translation\n defaultMessage=\"Update API key\"\n id=\"E7pMj/\"\n description=\"Menu option to update the API key for a needs-reauthorization installation\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item\n variant=\"destructive\"\n onClick={() => setDisconnectOpen(true)}\n >\n <Translation\n defaultMessage=\"Disconnect account\"\n id=\"esZQrd\"\n description=\"Menu option to disconnect an account\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n ) : (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <IconButton title={pipeActionsTitle}>\n <DotsHorizontalIcon />\n </IconButton>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n <DropdownMenu.Item\n onClick={async () => {\n if (unpinnedFields.length > 0) {\n setReauthConfigOpen(true);\n return;\n }\n try {\n await authorizeEventHandler();\n } catch {\n // pass - error displayed in new tab\n }\n }}\n >\n <Flex gap=\"4\" width=\"100%\" justify=\"between\" align=\"center\">\n <Translation\n defaultMessage=\"Reauthorize\"\n id=\"0E29F1\"\n description=\"Menu option to reauthorize an integration\"\n trailingSpace\n />\n <ExternalLinkIcon aria-hidden />\n </Flex>\n </DropdownMenu.Item>\n <DropdownMenu.Item\n variant=\"destructive\"\n onClick={() => setDisconnectOpen(true)}\n >\n <Translation\n defaultMessage=\"Disconnect account\"\n id=\"esZQrd\"\n description=\"Menu option to disconnect an account\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n )}\n </Flex>\n </>\n );\n }\n\n // Not connected: choose the connect entry point from the supported methods.\n // More than one: a menu of methods; otherwise that method's own button, with\n // OAuth as the default for a provider that declares nothing.\n const authMethods = integration.authMethods ?? [];\n const methods = CONNECT_AUTH_METHODS.filter((method) =>\n authMethods.includes(method),\n );\n\n const notConnectedStatus = connectionError ? (\n <ConnectionFailedStatus />\n ) : (\n <Status state=\"neutral\">\n <Translation\n defaultMessage=\"Not connected\"\n id=\"J7bTZa\"\n description=\"Status text for an integration that is not connected\"\n />\n </Status>\n );\n\n return (\n <Flex align=\"center\" gap=\"4\">\n {notConnectedStatus}\n {methods.length > 1 ? (\n <MultiMethodConnectButton\n integration={integration}\n methods={methods}\n onConnect={authorizeEventHandler}\n onConnected={clearConnectionError}\n />\n ) : methods.length === 1 && methods[0] === \"api_key\" ? (\n <ApiKeyConnectButton integration={integration} />\n ) : methods.length === 1 && methods[0] === \"client_credentials\" ? (\n <ClientCredentialsConnectButton integration={integration} />\n ) : (\n <ConnectIntegrationButton\n integration={integration}\n onConnect={authorizeEventHandler}\n />\n )}\n </Flex>\n );\n}\n\nfunction DisconnectAccountDialog({\n integrationName,\n installationId,\n open,\n onOpenChange,\n onSuccess,\n}: {\n integrationName: string;\n installationId: string;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Called after the connection is removed. */\n onSuccess?: () => void;\n}) {\n const queryClient = useQueryClient();\n const {\n mutate: deleteDataInstallation,\n error,\n reset,\n isPending,\n } = useClientGraphqlMutation({\n mutationFn: (sdk, id: string) => sdk.DeleteDataProviderConnection({ id }),\n onSuccess: () => {\n onOpenChange(false);\n for (const queryKey of myDataIntegrationsQueryKeys) {\n queryClient.invalidateQueries({ queryKey });\n }\n onSuccess?.();\n },\n });\n\n useEffect(() => {\n if (open) {\n reset();\n }\n }, [open, reset]);\n\n return (\n <AlertDialog.Root open={open} onOpenChange={onOpenChange}>\n <AlertDialog.Content style={{ width: \"80vw\", maxWidth: \"520px\" }}>\n <AlertDialog.Title>\n <Translation\n defaultMessage=\"Disconnect account\"\n id=\"9ABlCr\"\n description=\"Dialog title for disconnecting an account\"\n />\n </AlertDialog.Title>\n {error && (\n <Callout.Root my=\"5\" color=\"red\" role=\"alert\">\n <Callout.Text>\n <Translation\n defaultMessage=\"An error occurred while disconnecting your account. Please refresh the page and try again.\"\n id=\"qKBKF7\"\n description=\"Error message when disconnecting an account fails\"\n />\n </Callout.Text>\n </Callout.Root>\n )}\n <AlertDialog.Description>\n <Translation\n defaultMessage=\"Are you sure you want to disconnect your {integrationName} account?\"\n id=\"eEXeqP\"\n description=\"Confirmation message for disconnecting an account\"\n values={{\n integrationName: (\n <Text as=\"span\" weight=\"bold\">\n {integrationName}\n </Text>\n ),\n }}\n />\n </AlertDialog.Description>\n <Flex gap=\"3\" justify=\"end\" mt=\"5\">\n <AlertDialog.Cancel>\n <Button variant=\"secondary\">\n <Translation\n defaultMessage=\"Cancel\"\n id=\"hHNj31\"\n description=\"Cancel button text\"\n />\n </Button>\n </AlertDialog.Cancel>\n <Button\n variant=\"destructive\"\n disabled={isPending}\n loading={isPending}\n onClick={() => deleteDataInstallation(installationId)}\n >\n <Translation\n defaultMessage=\"Disconnect\"\n id=\"vMVXQh\"\n description=\"Button to disconnect an account\"\n />\n </Button>\n </Flex>\n </AlertDialog.Content>\n </AlertDialog.Root>\n );\n}\n\ninterface PipesLoadingProps extends WidgetRootDomProps {\n count: number;\n}\n\n/** The skeleton rows shared by the whole-widget and shared-section loaders. */\nfunction PipesSkeletonItems({ count }: { count: number }) {\n return Array.from({ length: count }).map((_, index) => (\n <CardList.Item key={index}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <Skeleton>\n <IconPanel>\n <ProviderIcon provider=\"google\" size=\"2\" />\n </IconPanel>\n </Skeleton>\n <Skeleton>\n <Text size=\"2\" weight=\"bold\">\n <Translation\n defaultMessage=\"Google Drive\"\n id=\"g11OOu\"\n description=\"Placeholder text for loading state\"\n />\n </Text>\n </Skeleton>\n </Flex>\n <Skeleton>\n <Button variant=\"secondary\" disabled>\n <Translation\n defaultMessage=\"Connect\"\n id=\"8TuDfA\"\n description=\"Placeholder button text for loading state\"\n />\n </Button>\n </Skeleton>\n </Flex>\n </CardList.Item>\n ));\n}\n\nconst PipesLoading: React.FC<PipesLoadingProps> = ({ count, ...domProps }) => {\n return (\n <CardList.Root {...getWidgetRootDomProps(\"loading\", domProps)}>\n <PipesSkeletonItems count={count} />\n </CardList.Root>\n );\n};\n\n/** The member's own connections, each with its credential-management actions. */\nfunction PipesItems({ integrations }: { integrations: DataIntegration[] }) {\n return integrations.map((integration) => (\n <CardList.Item key={integration.id}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <IconPanel color=\"panel\">\n <DataIntegrationIcon integration={integration} size=\"2\" />\n </IconPanel>\n <Text size=\"2\" weight=\"bold\">\n {integration.name}\n </Text>\n </Flex>\n <ProviderStatus integration={integration} />\n </Flex>\n </CardList.Item>\n ));\n}\n\n/**\n * Stands in for the rows a list has none of. Filtering is client-side, so an\n * empty list can say whether nothing is enabled yet or a `filter` emptied it.\n */\nfunction PipesEmptyItem({ isFiltered }: { isFiltered: boolean }) {\n return (\n <CardList.Item>\n <Text size=\"2\" color=\"gray\">\n {isFiltered ? (\n <Translation\n defaultMessage=\"No integrations to show.\"\n id=\"cAs7JC\"\n description=\"Empty state shown when the host's filter leaves no integrations to list\"\n />\n ) : (\n <Translation\n defaultMessage=\"No integrations are available yet.\"\n id=\"oK0Rjh\"\n description=\"Empty state shown when no integrations are enabled at all\"\n />\n )}\n </Text>\n </CardList.Item>\n );\n}\n\nconst Pipes: React.FC<PipesProps> = ({\n integrations,\n hasUnfilteredIntegrations,\n ...domProps\n}) => {\n return (\n <CardList.Root {...getWidgetRootDomProps(\"resolved\", domProps)}>\n {integrations.length > 0 ? (\n <PipesItems integrations={integrations} />\n ) : (\n <PipesEmptyItem isFiltered={hasUnfilteredIntegrations ?? false} />\n )}\n </CardList.Root>\n );\n};\n\n/**\n * A member's view of an organization-owned connection: usable as soon as one of\n * the organization's accounts is available, otherwise waiting on an\n * administrator. Members have no actions either way, so this is text only.\n */\nfunction SharedConnectionStatus({\n connection,\n}: {\n connection: SharedDataConnection;\n}) {\n const isAvailable = connection.connected_accounts.some(\n (account) => account.availability === \"available\",\n );\n\n return isAvailable ? (\n <Status state=\"success\">\n <Translation\n defaultMessage=\"Available\"\n id=\"_jQjSu\"\n description=\"Status text for a shared connection the member can use\"\n />\n </Status>\n ) : (\n <Status state=\"warning\">\n <Translation\n defaultMessage=\"Needs admin attention\"\n id=\"K5YoFj\"\n description=\"Status text for a shared connection an administrator must repair\"\n />\n </Status>\n );\n}\n\n/**\n * The sectioned row shell: the provider name with its state inline, the\n * connector description underneath, and actions confined to the right slot.\n *\n * Without an `icon` the row is one connection nested under its provider's row:\n * indented to the provider's text column and named in regular weight.\n */\nfunction SectionedItem({\n icon,\n name,\n status,\n description,\n actions,\n}: {\n icon?: React.ReactNode;\n name: string;\n status?: React.ReactNode;\n description?: string | null;\n actions?: React.ReactNode;\n}) {\n const nested = !icon;\n return (\n <CardList.Item nested={nested}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"4\">\n <Flex gap=\"4\" align=\"center\">\n {icon && <IconPanel color=\"panel\">{icon}</IconPanel>}\n <Flex direction=\"column\" gap=\"1\">\n <Flex align=\"center\" gap=\"2\" wrap=\"wrap\">\n <Text size=\"2\" weight={nested ? \"regular\" : \"bold\"}>\n {name}\n </Text>\n {status}\n </Flex>\n {description && (\n <Text size=\"2\" color=\"gray\">\n {description}\n </Text>\n )}\n </Flex>\n </Flex>\n {actions}\n </Flex>\n </CardList.Item>\n );\n}\n\n/**\n * A read-only row for an organization-owned connection. Shared connections\n * carry no `integrationType`, so the provider slug drives the icon fallbacks.\n */\nfunction SharedConnectionItem({\n connection,\n}: {\n connection: SharedDataConnection;\n}) {\n return (\n <SectionedItem\n icon={\n <DataIntegrationIcon\n integration={{\n integrationType: connection.slug,\n iconSlug: connection.iconSlug,\n iconUrl: connection.iconUrl,\n iconDarkUrl: connection.iconDarkUrl,\n }}\n size=\"2\"\n />\n }\n name={connection.name}\n status={<SharedConnectionStatus connection={connection} />}\n description={connection.description}\n />\n );\n}\n\n/**\n * One connection's state, inline beside its name. A failed OAuth handoff for\n * the row outranks the stored state until something clears it.\n */\nfunction MemberConnectionStatus({\n installation,\n connectionError,\n}: {\n installation: DataInstallation;\n connectionError: ConnectionError | null;\n}) {\n if (connectionError) {\n return <ConnectionFailedStatus />;\n }\n\n if (installation.state === \"connected\") {\n return (\n <Status state=\"success\">\n {installation.auth_method === \"api_key\" ? (\n <Translation\n defaultMessage=\"Connected via API key\"\n id=\"jQLTNe\"\n description=\"Status text for a connection established with an API key\"\n />\n ) : installation.auth_method === \"client_credentials\" ? (\n <Translation\n defaultMessage=\"Connected via client credentials\"\n id=\"hQKIrx\"\n description=\"Status text for a connection established with client credentials\"\n />\n ) : (\n <Translation\n defaultMessage=\"Connected via OAuth\"\n id=\"pJcK_M\"\n description=\"Status text for a connection established with OAuth\"\n />\n )}\n </Status>\n );\n }\n\n return (\n <Status state=\"warning\">\n {installation.auth_method === \"api_key\" ? (\n <Translation\n defaultMessage=\"Update your API key\"\n id=\"-YLPTk\"\n description=\"Status text for a connection whose API key stopped working\"\n />\n ) : (\n <Translation\n defaultMessage=\"Requires reauthorization\"\n id=\"dqczQS\"\n description=\"Status text for integration needing reauthorization\"\n />\n )}\n </Status>\n );\n}\n\n/** The right slot of a provider row the member has not connected yet. */\nfunction MemberConnectActions({\n integration,\n onConnect,\n onConnected,\n}: {\n integration: DataIntegration;\n onConnect: ConnectHandler;\n /** Called after an API key or client credentials connection succeeds. */\n onConnected: () => void;\n}) {\n const authMethods = integration.authMethods ?? [];\n const methods = CONNECT_AUTH_METHODS.filter((method) =>\n authMethods.includes(method),\n );\n\n return methods.length > 1 ? (\n <MultiMethodConnectButton\n integration={integration}\n methods={methods}\n onConnect={onConnect}\n onConnected={onConnected}\n />\n ) : methods.length === 1 && methods[0] === \"api_key\" ? (\n <ApiKeyConnectButton integration={integration} />\n ) : methods.length === 1 && methods[0] === \"client_credentials\" ? (\n <ClientCredentialsConnectButton integration={integration} />\n ) : (\n <ConnectIntegrationButton integration={integration} onConnect={onConnect} />\n );\n}\n\n/**\n * The right slot of one connection's row: the repair its state calls for,\n * promoted to a button, plus the management the connection supports. The state\n * itself lives beside the name, never here.\n */\nfunction MemberConnectionActions({\n integration,\n installation,\n label,\n onConnect,\n clearConnectionError,\n onAddConnection,\n}: {\n integration: DataIntegrationWithCapabilities;\n installation: DataInstallation;\n /** How the connection is named in its row, and so in the disconnect prompt. */\n label: string;\n /** Reauthorizes this exact connection (the row's authorize hook). */\n onConnect: (config?: Record<string, string>) => Promise<void>;\n /** Called once a connect or disconnect makes a prior OAuth failure moot. */\n clearConnectionError: () => void;\n /** Starts another connection, from the provider row that owns the add. */\n onAddConnection: (method: DataIntegrationAuthMethod) => void;\n}) {\n const [disconnectOpen, setDisconnectOpen] = useState(false);\n const [renameOpen, setRenameOpen] = useState(false);\n const [apiKeyOpen, setApiKeyOpen] = useState(false);\n const [clientCredentialsOpen, setClientCredentialsOpen] = useState(false);\n const [reauthConfigOpen, setReauthConfigOpen] = useState(false);\n const translate = useTranslation();\n\n const pipeActionsTitle = translate({\n defaultMessage: \"Pipe actions\",\n id: \"1uF9ve\",\n description: \"Title for pipe actions dropdown button\",\n });\n\n // Unpinned installation fields must be re-collected on reauthorization too;\n // the authorize endpoint rejects them as missing otherwise.\n const unpinnedFields = getUnpinnedInstallationFields(integration);\n\n const connected = installation.state === \"connected\";\n const isApiKeyInstallation = installation.auth_method === \"api_key\";\n const isClientCredentialsInstallation =\n installation.auth_method === \"client_credentials\";\n\n const openApiKey = () => setApiKeyOpen(true);\n const openClientCredentials = () => setClientCredentialsOpen(true);\n const reauthorize = async () => {\n if (unpinnedFields.length > 0) {\n setReauthConfigOpen(true);\n return;\n }\n try {\n await onConnect();\n } catch {\n // pass - error displayed in new tab\n }\n };\n\n // The API-key and client-credentials dialogs target `installation` itself\n // (see getConnectionTarget), as `onConnect` does for OAuth.\n return (\n <>\n <DisconnectAccountDialog\n integrationName={label}\n installationId={installation.id}\n open={disconnectOpen}\n onOpenChange={setDisconnectOpen}\n onSuccess={clearConnectionError}\n />\n {renameOpen && (\n <RenameConnectionDialog\n integrationName={integration.name}\n installation={installation}\n open={renameOpen}\n onOpenChange={setRenameOpen}\n />\n )}\n {apiKeyOpen && (\n <ApiKeyDialog\n integration={integration}\n installation={installation}\n open={apiKeyOpen}\n onOpenChange={setApiKeyOpen}\n onSuccess={clearConnectionError}\n />\n )}\n {clientCredentialsOpen && (\n <ClientCredentialsDialog\n integration={integration}\n installation={installation}\n fields={unpinnedFields}\n open={clientCredentialsOpen}\n onOpenChange={setClientCredentialsOpen}\n onSuccess={clearConnectionError}\n />\n )}\n {unpinnedFields.length > 0 && !isClientCredentialsInstallation && (\n <ConnectDialog\n integration={integration}\n fields={unpinnedFields}\n open={reauthConfigOpen}\n onOpenChange={setReauthConfigOpen}\n onConnect={onConnect}\n />\n )}\n <Flex align=\"center\" gap=\"4\" flexShrink=\"0\">\n {!connected &&\n (isApiKeyInstallation ? (\n <Button variant=\"secondary\" onClick={openApiKey}>\n <Translation\n defaultMessage=\"Update key\"\n id=\"MP-aOE\"\n description=\"Button to replace the API key of a connection that stopped working\"\n />\n </Button>\n ) : isClientCredentialsInstallation ? (\n <Button variant=\"secondary\" onClick={openClientCredentials}>\n <Translation\n defaultMessage=\"Update credentials\"\n id=\"1inB3Y\"\n description=\"Button to update the client credentials of a connection that stopped working\"\n />\n </Button>\n ) : (\n <Button variant=\"secondary\" onClick={reauthorize}>\n <Translation\n defaultMessage=\"Reauthorize\"\n id=\"3IbiTG\"\n description=\"Button to reauthorize a connection that stopped working\"\n />\n </Button>\n ))}\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <IconButton title={pipeActionsTitle}>\n <DotsHorizontalIcon />\n </IconButton>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n {connected && isApiKeyInstallation && (\n <DropdownMenu.Item onClick={openApiKey}>\n <Translation\n defaultMessage=\"Rotate API key\"\n id=\"GML+c8\"\n description=\"Menu option to rotate the API key\"\n />\n </DropdownMenu.Item>\n )}\n {connected && isClientCredentialsInstallation && (\n <DropdownMenu.Item onClick={openClientCredentials}>\n <Translation\n defaultMessage=\"Update client credentials\"\n id=\"daHKWE\"\n description=\"Menu option to update stored client credentials\"\n />\n </DropdownMenu.Item>\n )}\n {canRenameConnections(integration) && (\n <DropdownMenu.Item onClick={() => setRenameOpen(true)}>\n <RenameMenuLabel />\n </DropdownMenu.Item>\n )}\n <ConnectAnotherAccountItem\n capabilities={integration.capabilities}\n onSelect={onAddConnection}\n />\n <DropdownMenu.Item\n variant=\"destructive\"\n onClick={() => setDisconnectOpen(true)}\n >\n <Translation\n defaultMessage=\"Disconnect account\"\n id=\"esZQrd\"\n description=\"Menu option to disconnect an account\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n </Flex>\n </>\n );\n}\n\n/**\n * A provider row the member has connected at most once. Owns the OAuth flow\n * for its connection (or its first connect) and for adding another, so a\n * handoff failure reported after a dialog closes reaches the row status.\n */\nfunction MemberConnectionItem({\n integration,\n}: {\n integration: DataIntegrationWithCapabilities;\n}) {\n const installation = integration.connected_accounts[0];\n const { openAuthorizeUrl, connectionError, clearConnectionError } =\n useOpenDataIntegrationAuthorizeUrl(\n integration,\n \"user\",\n getConnectionTarget(installation),\n );\n const addConnection = useAddConnectionFlow(integration);\n const failure = connectionError ?? addConnection.connectionError;\n // The row reports its latest attempt: starting a repair (or the first\n // connect) retires a failed add's status, and starting an add retires a\n // failed repair's, so a success never sits under a stale failure.\n const startRepair = (config?: Record<string, string>) => {\n addConnection.clearConnectionError();\n return openAuthorizeUrl(config);\n };\n const startAdd = (method: DataIntegrationAuthMethod) => {\n clearConnectionError();\n addConnection.start(method, ADD_CONNECTION);\n };\n\n return (\n <>\n {addConnection.dialogs}\n <SectionedItem\n icon={<DataIntegrationIcon integration={integration} size=\"2\" />}\n name={integration.name}\n status={\n installation ? (\n <MemberConnectionStatus\n installation={installation}\n connectionError={failure}\n />\n ) : (\n failure && <ConnectionFailedStatus />\n )\n }\n description={integration.description}\n actions={\n installation ? (\n <MemberConnectionActions\n integration={integration}\n installation={installation}\n label={integration.name}\n onConnect={startRepair}\n clearConnectionError={() => {\n clearConnectionError();\n addConnection.clearConnectionError();\n }}\n onAddConnection={startAdd}\n />\n ) : (\n <MemberConnectActions\n integration={integration}\n onConnect={startRepair}\n onConnected={clearConnectionError}\n />\n )\n }\n />\n </>\n );\n}\n\n/**\n * One connection nested under its provider's row. Owns the OAuth flow for\n * repairing this exact connection; adding another goes through the provider\n * row, which shows that flow's result.\n */\nfunction MemberNestedConnectionItem({\n integration,\n installation,\n onAddConnection,\n onRepairStart,\n}: {\n integration: DataIntegrationWithCapabilities;\n installation: DataInstallation;\n onAddConnection: (method: DataIntegrationAuthMethod) => void;\n /** Lets the provider row retire a failed add once a repair starts. */\n onRepairStart: () => void;\n}) {\n const { openAuthorizeUrl, connectionError, clearConnectionError } =\n useOpenDataIntegrationAuthorizeUrl(\n integration,\n \"user\",\n getConnectionTarget(installation),\n );\n const startRepair = (config?: Record<string, string>) => {\n onRepairStart();\n return openAuthorizeUrl(config);\n };\n const label = getConnectionLabel(integration.name, installation);\n\n return (\n <SectionedItem\n name={label}\n status={\n <MemberConnectionStatus\n installation={installation}\n connectionError={connectionError}\n />\n }\n actions={\n <MemberConnectionActions\n integration={integration}\n installation={installation}\n label={label}\n onConnect={startRepair}\n clearConnectionError={clearConnectionError}\n onAddConnection={onAddConnection}\n />\n }\n />\n );\n}\n\n/**\n * A provider the member has connected more than once: the provider row counts\n * the connections and owns adding another (showing that flow's failure), and\n * each connection follows as its own nested row with its own state and actions.\n */\nfunction MemberConnectionGroup({\n integration,\n}: {\n integration: DataIntegrationWithCapabilities;\n}) {\n const addConnection = useAddConnectionFlow(integration);\n const startAdd = (method: DataIntegrationAuthMethod) =>\n addConnection.start(method, ADD_CONNECTION);\n\n return (\n <>\n {addConnection.dialogs}\n <SectionedItem\n icon={<DataIntegrationIcon integration={integration} size=\"2\" />}\n name={integration.name}\n status={\n addConnection.connectionError ? (\n <ConnectionFailedStatus />\n ) : (\n <ConnectionCountStatus\n count={integration.connected_accounts.length}\n />\n )\n }\n description={integration.description}\n actions={\n <AddConnectionButton\n capabilities={integration.capabilities}\n onSelect={startAdd}\n />\n }\n />\n {integration.connected_accounts.map((installation) => (\n <MemberNestedConnectionItem\n key={installation.id}\n integration={integration}\n installation={installation}\n onAddConnection={startAdd}\n onRepairStart={addConnection.clearConnectionError}\n />\n ))}\n </>\n );\n}\n\n/** The member's own connections in the sectioned experience. */\nfunction MemberConnectionItems({\n integrations,\n}: {\n integrations: DataIntegrationWithCapabilities[];\n}) {\n return integrations.map((integration) =>\n integration.connected_accounts.length > 1 ? (\n <MemberConnectionGroup key={integration.id} integration={integration} />\n ) : (\n <MemberConnectionItem key={integration.id} integration={integration} />\n ),\n );\n}\n\nfunction PipesSection({\n title,\n description,\n children,\n}: {\n title: React.ReactNode;\n description: React.ReactNode;\n children: React.ReactNode;\n}) {\n return (\n <Flex direction=\"column\" gap=\"3\">\n <Flex direction=\"column\" gap=\"1\">\n <Text size=\"3\" weight=\"bold\">\n {title}\n </Text>\n <Text size=\"2\" color=\"gray\">\n {description}\n </Text>\n </Flex>\n {children}\n </Flex>\n );\n}\n\n/**\n * The sectioned member experience: the connections the organization shares,\n * then the member's own. The two lanes come from different endpoints and are\n * never merged — the same provider can legitimately appear in both, once as an\n * organization-owned connection and once as the member's own account.\n *\n * The shared section is omitted entirely when the organization shares nothing\n * (or the request failed), leaving the member's own section usable on its own.\n */\nconst PipesSections: React.FC<PipesSectionsProps> = ({\n integrations,\n hasUnfilteredIntegrations,\n sharedConnections,\n hasUnfilteredSharedConnections,\n isSharedLoading,\n organizationName,\n ...domProps\n}) => {\n return (\n <Flex\n direction=\"column\"\n gap=\"5\"\n {...getWidgetRootDomProps(\"resolved\", domProps)}\n >\n {(isSharedLoading ||\n sharedConnections.length > 0 ||\n hasUnfilteredSharedConnections) && (\n <PipesSection\n title={\n <Translation\n defaultMessage=\"Shared connections\"\n id=\"Fcd-bK\"\n description=\"Heading for the section listing connections the organization owns\"\n />\n }\n description={\n organizationName ? (\n <Translation\n defaultMessage=\"Accounts {organizationName} owns and shares with everyone.\"\n id=\"7U8P0v\"\n description=\"Description of the shared connections section, naming the organization\"\n values={{ organizationName }}\n />\n ) : (\n <Translation\n defaultMessage=\"Accounts your organization owns and shares with everyone.\"\n id=\"72FEZi\"\n description=\"Description of the shared connections section when the organization name is unknown\"\n />\n )\n }\n >\n <CardList.Root>\n {isSharedLoading ? (\n <PipesSkeletonItems count={2} />\n ) : sharedConnections.length > 0 ? (\n sharedConnections.map((connection) => (\n <SharedConnectionItem\n key={connection.id}\n connection={connection}\n />\n ))\n ) : (\n <PipesEmptyItem isFiltered />\n )}\n </CardList.Root>\n </PipesSection>\n )}\n <PipesSection\n title={\n <Translation\n defaultMessage=\"Your connections\"\n id=\"-VDI3G\"\n description=\"Heading for the section listing the member's own connections\"\n />\n }\n description={\n <Translation\n defaultMessage=\"Connect your account to access these connections.\"\n id=\"ObXqUu\"\n description=\"Description of the personal connections section\"\n />\n }\n >\n <CardList.Root>\n {integrations.length > 0 ? (\n <MemberConnectionItems integrations={integrations} />\n ) : (\n <PipesEmptyItem isFiltered={hasUnfilteredIntegrations ?? false} />\n )}\n </CardList.Root>\n </PipesSection>\n </Flex>\n );\n};\n\ninterface PipesErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst PipesError: React.FC<PipesErrorProps> = ({ error, ...domProps }) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <GenericError error={error} />\n </Card>\n );\n};\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getWidgetDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"pipes\",\n widgetState: state,\n });\n}\n\nexport type {\n PipesProps,\n PipesSectionsProps,\n PipesLoadingProps,\n PipesErrorProps,\n ConnectionOwner,\n};\nexport {\n Pipes,\n PipesSections,\n PipesLoading,\n PipesError,\n PipesEmptyItem,\n PipesSection,\n ApiKeyDialog,\n ClientCredentialsDialog,\n ConnectDialog,\n ConnectionFailedStatus,\n getUnpinnedInstallationFields,\n useAddConnectionFlow,\n useOpenDataIntegrationAuthorizeUrl,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pipes.js","names":["TextField","Dialog.Title","Dialog.Root","Dialog.Content","Dialog.Close","Button","Dialog.Description","DropdownMenu.Item","DropdownMenu.Root","DropdownMenu.Trigger","DropdownMenu.Content","DropdownMenu.Sub","DropdownMenu.SubTrigger","DropdownMenu.SubContent","IconButton","AlertDialog.Root","AlertDialog.Content","AlertDialog.Title","AlertDialog.Description","AlertDialog.Cancel","CardList.Item","Skeleton","CardList.Root"],"sources":["../../../src/lib/pipes.tsx"],"sourcesContent":["\"use client\";\nimport { Callout, Card, Flex, Text } from \"@radix-ui/themes\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport * as CardList from \"./card-list.js\";\nimport { DataIntegrationIcon } from \"./data-integration-icon.js\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport {\n DotsHorizontalIcon,\n ExternalLinkIcon,\n GlobeIcon,\n LockClosedIcon,\n} from \"@radix-ui/react-icons\";\nimport {\n AlertDialog,\n Button,\n Dialog,\n DropdownMenu,\n IconButton,\n Label,\n PasswordField,\n Skeleton,\n TextField,\n} from \"./elements.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { Status } from \"./status.js\";\nimport type {\n DataInstallation,\n DataIntegration,\n DataIntegrationConfigField,\n SharedDataConnection,\n} from \"./api/types.js\";\nimport {\n ADD_CONNECTION,\n createAddConnectionTarget,\n AddConnectionButtonLabel,\n ConnectAnotherAccountMenuLabel,\n ConnectionCountStatus,\n type ConnectionTarget,\n getConnectionLabel,\n canRenameConnections,\n getConnectionTarget,\n RenameConnectionDialog,\n RenameMenuLabel,\n ConnectionNameField,\n toAccountDisplayNameInput,\n toConnectionTargetInput,\n toCreationTargetInput,\n} from \"./pipes-connections.js\";\nimport {\n type AddConnectionCapabilities,\n type DataIntegrationWithCapabilities,\n myDataIntegrationsQueryKeys,\n useInvalidateConnections,\n} from \"./api/pipes.js\";\nimport { useClientGraphql } from \"../api/client-graphql/client.js\";\nimport {\n clientGraphqlQueryKey,\n useClientGraphqlMutation,\n useClientGraphqlQuery,\n} from \"../api/client-graphql/hooks.js\";\nimport type {\n ConnectDataProviderWithClientCredentialsMutation,\n ConnectOrganizationDataProviderWithClientCredentialsInput,\n ConnectOrganizationDataProviderWithClientCredentialsMutation,\n CreateDataProviderAuthorizationMutation,\n ConnectDataProviderWithClientCredentialsInput,\n CreateDataProviderConnectionInput,\n CreateOrganizationDataProviderConnectionInput,\n CreateOrganizationDataProviderAuthorizationMutation,\n DataProviderConfigEntryInput,\n} from \"../api/client-graphql/generated.js\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { GenericError } from \"./generic-error.js\";\nimport { getWidgetDomProps } from \"./utils/widget-dom-props.js\";\nimport { WidgetRootDomProps, WidgetRootState } from \"./widget-types.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\nimport { ApiError } from \"../api/errors.js\";\nimport { buildRedactedSecret, isRedactedSecret } from \"./redacted-secret.js\";\nimport { usePipesCredentialAttribution } from \"./pipes-credential-attribution.js\";\n\ninterface PipesProps extends WidgetRootDomProps {\n integrations: DataIntegration[];\n /**\n * Whether the endpoint returned any connections before the host's `filter`\n * ran, which is what tells an organization with nothing enabled yet apart\n * from a filter that matched nothing. Defaults to whatever survived, the\n * reading for an unfiltered list.\n */\n hasUnfilteredIntegrations?: boolean;\n}\n\ninterface PipesSectionsProps extends Omit<PipesProps, \"integrations\"> {\n /**\n * The member's providers, each with every connection they own to it and\n * whether they can add another.\n */\n integrations: DataIntegrationWithCapabilities[];\n /**\n * Organization-owned connections, as returned by the shared-connections\n * endpoint. Empty both when the organization shares nothing and when the\n * request failed, since neither is something a member can act on.\n */\n sharedConnections: SharedDataConnection[];\n /**\n * {@link PipesProps.hasUnfilteredIntegrations} for the shared section. The\n * section is dropped entirely unless the organization shares something, so\n * this only ever decides whether a filtered-out lane says so.\n */\n hasUnfilteredSharedConnections?: boolean;\n /** Renders the shared section as skeleton rows while it resolves. */\n isSharedLoading?: boolean;\n /** Names the owning organization in the shared section's description. */\n organizationName?: string;\n}\n\nconst HANDOFF_INTERVAL_MS = 100;\nconst HANDOFF_MAX_ATTEMPTS = 100; // 10 seconds worth of attempts\n\ntype DataIntegrationAuthMethod = NonNullable<\n DataIntegration[\"authMethods\"]\n>[number];\n\n/** Supported connect methods, in the order they're offered to the user. */\nconst CONNECT_AUTH_METHODS: DataIntegrationAuthMethod[] = [\n \"oauth\",\n \"client_credentials\",\n \"api_key\",\n];\n\n/**\n * Who will own the resulting installation. Members connect their own account\n * through the personal authorize endpoint; administrators connect an account\n * on the organization's behalf through the organization one.\n */\ntype ConnectionOwner = \"user\" | \"organization\";\n\ntype AuthorizationResult =\n | CreateDataProviderAuthorizationMutation[\"createDataProviderAuthorization\"]\n | CreateOrganizationDataProviderAuthorizationMutation[\"createOrganizationDataProviderAuthorization\"];\n\ntype DataProviderAuthorization = Extract<\n AuthorizationResult,\n { __typename: \"DataProviderAuthorization\" }\n>;\n\ntype AuthorizeConnection = (\n dataProviderId: string,\n config?: Record<string, string>,\n target?: ConnectionTarget,\n accountDisplayName?: string,\n) => Promise<DataProviderAuthorization>;\n\n/**\n * Starts an OAuth authorization from a connect dialog: the config values it\n * collected and, when adding a connection, the name it collected for it.\n */\ntype ConnectHandler = (\n config?: Record<string, string>,\n accountDisplayName?: string,\n) => Promise<void>;\n\n/**\n * Config values as the GraphQL input expects them. Only string values can\n * travel; anything else the stored config carries is left untouched.\n */\nfunction toConfigEntries(\n config: Record<string, unknown> | undefined,\n): DataProviderConfigEntryInput[] | undefined {\n if (!config) {\n return undefined;\n }\n const entries: DataProviderConfigEntryInput[] = [];\n for (const [name, value] of Object.entries(config)) {\n if (typeof value === \"string\") {\n entries.push({ name, value });\n }\n }\n return entries;\n}\n\n/**\n * Failure members of a mutation result union, raised the way the REST client\n * raised the equivalent 4xx so the dialogs' `ApiError` handling still applies.\n */\nfunction resultError(\n message: string,\n status: number,\n context?: unknown,\n): ApiError {\n return new ApiError({ message, status, queryType: \"mutation\", context });\n}\n\ntype ClientCredentialsConnectionResult =\n | ConnectDataProviderWithClientCredentialsMutation[\"connectDataProviderWithClientCredentials\"]\n | ConnectOrganizationDataProviderWithClientCredentialsMutation[\"connectOrganizationDataProviderWithClientCredentials\"];\n\n/**\n * Members without a server-supplied `message` are raised with an empty one so\n * the dialog falls back to its translated generic banner.\n */\nfunction unwrapClientCredentialsConnection(\n result: ClientCredentialsConnectionResult,\n): Extract<\n ClientCredentialsConnectionResult,\n { __typename: \"DataProviderConnected\" }\n> {\n switch (result.__typename) {\n case \"DataProviderConnected\":\n return result;\n case \"DataProviderConfigInvalid\":\n throw resultError(result.message, 400);\n case \"DataProviderAuthMethodUnsupported\":\n throw resultError(\"\", 400, result);\n case \"DataProviderConnectionAuthMethodConflict\":\n throw resultError(\"\", 409, result);\n }\n}\n\nfunction unwrapAuthorization(\n result: AuthorizationResult,\n): DataProviderAuthorization {\n switch (result.__typename) {\n case \"DataProviderAuthorization\":\n return result;\n case \"DataProviderConfigInvalid\":\n throw resultError(result.message, 400);\n case \"DataProviderAuthorizationUnavailable\":\n throw resultError(result.message, 409);\n }\n}\n\n/**\n * Resolves the authorize call for an owner. Both mutations hand off to the\n * popup the same way; the organization one always requires a handoff so it\n * takes no `requireHandoff` flag.\n */\nconst useAuthorizeConnection = (\n owner: ConnectionOwner,\n): AuthorizeConnection => {\n const sdk = useClientGraphql();\n\n return useCallback(\n async (\n dataProviderId: string,\n config?: Record<string, string>,\n target?: ConnectionTarget,\n accountDisplayName?: string,\n ) => {\n const configEntries = toConfigEntries(config);\n const targetInput = toConnectionTargetInput(target);\n // The API holds the name until the callback creates the connection.\n const nameInput = toAccountDisplayNameInput(accountDisplayName);\n if (owner === \"organization\") {\n const { createOrganizationDataProviderAuthorization } =\n await sdk.CreateOrganizationDataProviderAuthorization({\n input: {\n dataProviderId,\n config: configEntries,\n ...targetInput,\n ...nameInput,\n },\n });\n return unwrapAuthorization(createOrganizationDataProviderAuthorization);\n }\n const { createDataProviderAuthorization } =\n await sdk.CreateDataProviderAuthorization({\n input: {\n dataProviderId,\n config: configEntries,\n requireHandoff: true,\n ...targetInput,\n ...nameInput,\n },\n });\n return unwrapAuthorization(createDataProviderAuthorization);\n },\n [owner, sdk],\n );\n};\n\nfunction useAuthKitOrigin(): string {\n const settings = useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"AuthKitSettings\"),\n queryFn: (sdk) => sdk.AuthKitSettings(),\n });\n return settings.data?.authkitSettings.origin ?? \"\";\n}\n\ninterface ConnectionError {\n errorCode?: string;\n errorDescription?: string;\n}\n\n/**\n * Runs the OAuth handoff for one connection target and tracks how it ended,\n * so the row that owns it can show \"Connection failed\". `target` picks the\n * connection the authorization writes (see {@link getConnectionTarget});\n * unset keeps the compatibility behavior.\n */\nconst useOpenDataIntegrationAuthorizeUrl = (\n integration: DataIntegration,\n owner: ConnectionOwner = \"user\",\n target?: ConnectionTarget,\n) => {\n // Keyed by value so a target rebuilt on every render keeps the callback stable.\n const targetIntent = target?.intent;\n const targetAccountId =\n target?.intent === \"Reauthorize\" ? target.connectedAccountId : undefined;\n const authorizeDataIntegration = useAuthorizeConnection(owner);\n const baseUrl = useAuthKitOrigin();\n const intervalRef = useRef<ReturnType<typeof setInterval> | undefined>(\n undefined,\n );\n const messageHandlerRef = useRef<((event: MessageEvent) => void) | undefined>(\n undefined,\n );\n // Tracks whether the popup sent any message (handoff ack or error) before it\n // closed, so a popup that closes without a result can be reported distinctly.\n const receivedMessageRef = useRef(false);\n const [connectionError, setConnectionError] =\n useState<ConnectionError | null>(null);\n\n // Stops watching the popup from the current attempt, if any.\n const stopHandoff = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = undefined;\n }\n if (messageHandlerRef.current) {\n window.removeEventListener(\"message\", messageHandlerRef.current);\n messageHandlerRef.current = undefined;\n }\n }, []);\n\n useEffect(() => stopHandoff, [stopHandoff]);\n\n // Also abandons a still-pending attempt, so a popup left open while another\n // auth method connects can't report a failure afterwards.\n const clearConnectionError = useCallback(() => {\n stopHandoff();\n setConnectionError(null);\n }, [stopHandoff]);\n\n const openAuthorizeUrl = useCallback(\n async (config?: Record<string, string>, accountDisplayName?: string) => {\n // Stop watching any popup from a previous invocation\n stopHandoff();\n // Reset state for this attempt\n receivedMessageRef.current = false;\n setConnectionError(null);\n\n // need to do this synchronously in the event handler to avoid popup blocker notifications\n const win = window.open(`${baseUrl}/pipes/redirecting`, \"_blank\");\n // A blocked popup yields null; fail loudly (caller catches) instead of\n // authorizing and then discarding the redirect into a phantom success.\n if (!win) {\n throw new Error(\"Unable to open the authorization window.\");\n }\n\n // caller will catch. Close the popup on failure so a network/permission/\n // config error doesn't strand a blank /pipes/redirecting tab.\n let authorization;\n try {\n authorization = await authorizeDataIntegration(\n integration.id,\n config,\n targetIntent === \"Add\"\n ? ADD_CONNECTION\n : targetIntent === \"Reauthorize\" && targetAccountId\n ? { intent: \"Reauthorize\", connectedAccountId: targetAccountId }\n : undefined,\n accountDisplayName,\n );\n } catch (error) {\n win.close();\n throw error;\n }\n const { url, handoffToken, redirectToken } = authorization;\n if (win) {\n win.location = url;\n const parsedUrl = new URL(url);\n const payload = {\n handoffToken: handoffToken ?? undefined,\n redirectToken,\n };\n\n messageHandlerRef.current = (event: MessageEvent) => {\n if (\n event.origin === parsedUrl.origin &&\n event.data?.redirectToken === redirectToken\n ) {\n receivedMessageRef.current = true;\n if (event.data.error === true) {\n setConnectionError({\n errorCode: event.data.errorCode,\n errorDescription: event.data.errorDescription,\n });\n }\n stopHandoff();\n }\n };\n window.addEventListener(\"message\", messageHandlerRef.current);\n\n let attempts = 0;\n intervalRef.current = setInterval(() => {\n attempts += 1;\n\n if (attempts >= HANDOFF_MAX_ATTEMPTS) {\n stopHandoff();\n return;\n }\n\n if (win && !win.closed) {\n win.postMessage(payload, parsedUrl.origin);\n } else {\n // Popup closed without sending any message: surface a generic failure.\n if (!receivedMessageRef.current) {\n setConnectionError({ errorCode: \"connection_failed\" });\n }\n stopHandoff();\n }\n }, HANDOFF_INTERVAL_MS);\n }\n },\n [\n authorizeDataIntegration,\n integration.id,\n baseUrl,\n stopHandoff,\n targetIntent,\n targetAccountId,\n ],\n );\n\n return { openAuthorizeUrl, connectionError, clearConnectionError };\n};\n\n/** Row status after the OAuth handoff reported a failure. */\nfunction ConnectionFailedStatus() {\n return (\n <Status state=\"error\">\n <Translation\n defaultMessage=\"Connection failed\"\n id=\"iPsR87\"\n description=\"Status text shown when a connection attempt fails\"\n />\n </Status>\n );\n}\n\n/**\n * Returns the provider-declared `installation`-scope config fields that the\n * integration has not pinned a value for, sorted by descriptor `order`. These\n * are the fields the connect flow must prompt for (pin / prompt-if-unset).\n */\nfunction getUnpinnedInstallationFields(\n integration: DataIntegration,\n): DataIntegrationConfigField[] {\n return (integration.configFields ?? [])\n .filter(\n (field) =>\n field.scope === \"installation\" && !integration.config?.[field.key],\n )\n .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n}\n\n/**\n * Seed values for the descriptors from a stored `config` object, stringifying\n * the scalar values the inputs can round-trip and skipping anything else.\n */\nfunction getInitialConfigValues(\n fields: DataIntegrationConfigField[],\n storedConfig: Record<string, unknown>,\n): Record<string, string> {\n const values: Record<string, string> = {};\n for (const field of fields) {\n const stored = storedConfig[field.key];\n if (\n typeof stored === \"string\" ||\n typeof stored === \"number\" ||\n typeof stored === \"boolean\"\n ) {\n values[field.key] = String(stored);\n }\n }\n return values;\n}\n\n/**\n * Compile a descriptor `pattern` (+ optional flags), returning undefined when\n * it isn't valid regex syntax so the server's validation remains the backstop.\n *\n * Anchored as `^(?:…)$` to match the server, so an unanchored descriptor\n * pattern surfaces the same inline error here instead of passing client\n * validation and being rejected on submit.\n */\nfunction compileConfigFieldPattern(\n pattern: string,\n flags: string | undefined,\n): RegExp | undefined {\n try {\n return new RegExp(`^(?:${pattern})$`, flags);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Form state for a set of provider-declared config-field descriptors: the\n * collected values, inline validation against `required` / `pattern`, and the\n * `config` payload the connect endpoints accept. Shared by every connect\n * surface so descriptors are rendered and validated in exactly one place.\n *\n * `initialValues` prefills the inputs (e.g. from an existing installation's\n * stored config); `isDirty` reports whether the user actually changed any of\n * them, which callers use to decide whether to send `config` at all.\n */\nfunction useConfigFieldsForm(\n fields: DataIntegrationConfigField[],\n initialValues: Record<string, string> = {},\n) {\n const [values, setValues] = useState<Record<string, string>>(initialValues);\n const [errors, setErrors] = useState<Record<string, string | null>>({});\n const translate = useTranslation();\n\n const requiredMessage = translate({\n defaultMessage: \"This field is required\",\n id: \"B2HvfC\",\n description:\n \"Validation error shown when a required configuration field is left empty\",\n });\n const patternMessage = translate({\n defaultMessage: \"Enter a valid value.\",\n id: \"2XWaGz\",\n description:\n \"Validation error shown when a configuration field value does not match the expected format\",\n });\n\n const setValue = (key: string, value: string) => {\n setValues((prev) => ({ ...prev, [key]: value }));\n setErrors((prev) => (prev[key] ? { ...prev, [key]: null } : prev));\n };\n\n const reset = () => {\n setValues(initialValues);\n setErrors({});\n };\n\n const validate = () => {\n const nextErrors: Record<string, string | null> = {};\n let valid = true;\n for (const field of fields) {\n const value = (values[field.key] ?? \"\").trim();\n if (field.required && !value) {\n nextErrors[field.key] = requiredMessage;\n valid = false;\n continue;\n }\n if (value && field.pattern) {\n const patternRegExp = compileConfigFieldPattern(\n field.pattern,\n field.patternFlags,\n );\n if (patternRegExp && !patternRegExp.test(value)) {\n nextErrors[field.key] = patternMessage;\n valid = false;\n continue;\n }\n }\n nextErrors[field.key] = null;\n }\n setErrors(nextErrors);\n return valid;\n };\n\n const buildConfig = () => {\n const config: Record<string, string> = {};\n for (const field of fields) {\n const value = (values[field.key] ?? \"\").trim();\n if (value) {\n config[field.key] = value;\n }\n }\n return config;\n };\n\n /**\n * The full `config` object to write, given the config the API returned for\n * the installation. The write is a wholesale replace, so keys the widget\n * never rendered (pinned at the integration level, or unknown to these\n * descriptors) are preserved as received rather than dropped.\n */\n const buildConfigPayload = (storedConfig: Record<string, unknown>) => {\n const payload: Record<string, unknown> = { ...storedConfig };\n for (const field of fields) {\n const value = (values[field.key] ?? \"\").trim();\n if (value) {\n payload[field.key] = value;\n } else {\n delete payload[field.key];\n }\n }\n return payload;\n };\n\n const hasMissingRequired = fields.some(\n (field) => field.required && !(values[field.key] ?? \"\").trim(),\n );\n\n const isDirty = fields.some(\n (field) => (values[field.key] ?? \"\") !== (initialValues[field.key] ?? \"\"),\n );\n\n return {\n values,\n errors,\n setValue,\n reset,\n validate,\n buildConfig,\n buildConfigPayload,\n hasMissingRequired,\n isDirty,\n };\n}\n\n/**\n * Renders config-field descriptors as labelled inputs (secret descriptors get a\n * password field), with inline validation errors wired up via `aria-invalid` /\n * `aria-describedby`.\n *\n * Stacks as label → description → input → hint, so the description is read\n * before the field is filled and the `default` hint sits with the value it\n * describes. (The dashboard's config form instead merges both into one help\n * line below the input; the copy matches, the placement follows the widget's\n * existing description-above-input layout.)\n *\n * The `default` — falling back to the display-only `example` — is the\n * placeholder, and is never filled in as a value: submitting it would pin it and\n * freeze it, while leaving the field empty lets the API resolve the default on\n * read, so a later change to it reaches existing installations.\n */\nfunction ConfigFieldInputs({\n idPrefix,\n fields,\n values,\n errors,\n onChange,\n}: {\n idPrefix: string;\n fields: DataIntegrationConfigField[];\n values: Record<string, string>;\n errors: Record<string, string | null>;\n onChange: (key: string, value: string) => void;\n}) {\n return fields.map((field) => {\n const fieldId = `${idPrefix}-${field.key}`;\n const errorId = `${fieldId}-error`;\n const descriptionId = `${fieldId}-description`;\n const error = errors[field.key];\n const Control = field.secret ? PasswordField : TextField;\n const defaultHint =\n field.default !== undefined ? (\n <Translation\n defaultMessage=\"Defaults to {value} when left blank.\"\n id=\"MTNqSC\"\n description=\"Hint naming the value used when a configuration field is left blank\"\n values={{ value: field.default }}\n />\n ) : null;\n // The hint and the error share the slot under the input; the error wins.\n const hintId = `${fieldId}-hint`;\n const showHint = !error && defaultHint;\n const describedBy =\n [\n field.description ? descriptionId : null,\n showHint ? hintId : null,\n error ? errorId : null,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n return (\n <Flex key={field.key} direction=\"column\" gap=\"1\">\n <Label htmlFor={fieldId}>{field.label}</Label>\n {field.description ? (\n <Text color=\"gray\" size=\"2\" id={descriptionId} mb=\"1\">\n {field.description}\n </Text>\n ) : null}\n <Control\n id={fieldId}\n value={values[field.key] ?? \"\"}\n placeholder={field.default ?? field.example}\n autoComplete=\"off\"\n required={field.required || undefined}\n aria-invalid={!!error || undefined}\n aria-describedby={describedBy}\n onChange={(event) => onChange(field.key, event.target.value)}\n />\n {showHint ? (\n <Text color=\"gray\" size=\"2\" id={hintId}>\n {defaultHint}\n </Text>\n ) : null}\n {error ? (\n <Text color=\"red\" size=\"2\" id={errorId}>\n {error}\n </Text>\n ) : null}\n </Flex>\n );\n });\n}\n\n/** Gray dot separator shown between the logos in the connect-dialog header. */\nfunction LogoSeparator() {\n return (\n <DotsHorizontalIcon\n width=\"20\"\n height=\"20\"\n style={{ color: \"var(--gray-8)\" }}\n />\n );\n}\n\n/**\n * Shared connect-dialog header: the WorkOS → provider icon row and the\n * \"{app} uses WorkOS to connect to {provider}\" title.\n */\nfunction ConnectDialogHeader({\n integration,\n}: {\n integration: DataIntegration;\n}) {\n const branding = useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"Branding\"),\n queryFn: (sdk) => sdk.Branding(),\n });\n const logo =\n branding.data?.branding.logoDarkPath ??\n branding.data?.branding.logoLightPath;\n const appName = branding.data?.branding.displayName ?? \"This application\";\n\n return (\n <>\n <Flex justify=\"center\" align=\"center\" gap=\"2\" mt=\"2\">\n {logo && (\n <>\n <IconPanel color=\"panel\" style={{ width: \"48px\", height: \"48px\" }}>\n <ProviderIcon\n size=\"2\"\n provider=\"workos\"\n style={{ backgroundImage: `url(${logo})` }}\n />\n </IconPanel>\n <LogoSeparator />\n </>\n )}\n <IconPanel\n color=\"panel\"\n style={{\n ...(logo ? { borderWidth: 0 } : undefined),\n width: \"48px\",\n height: \"48px\",\n }}\n >\n <ProviderIcon size=\"2\" provider=\"workos\" />\n </IconPanel>\n <LogoSeparator />\n <IconPanel color=\"panel\" style={{ width: \"48px\", height: \"48px\" }}>\n <DataIntegrationIcon size=\"2\" integration={integration} />\n </IconPanel>\n </Flex>\n <Dialog.Title size=\"2\" mt=\"5\" mb=\"5\" weight={\"bold\"} align=\"center\">\n <Translation\n defaultMessage=\"{appName} uses WorkOS to connect to {integrationName}.\"\n id=\"ujRDBH\"\n description=\"Dialog title explaining the app connection flow\"\n values={{ appName, integrationName: integration.name }}\n />\n </Dialog.Title>\n </>\n );\n}\n\n/**\n * Shared connect-dialog explainer card: \"you'll be redirected to sign in\" +\n * \"your credentials remain secure\".\n */\nfunction ConnectExplainerCard({\n integration,\n}: {\n integration: DataIntegration;\n}) {\n return (\n <Card>\n <Flex direction=\"column\" gap=\"4\">\n <Flex gap=\"2\" align=\"center\">\n <IconPanel color=\"gray\" style={{ width: \"32px\", height: \"32px\" }}>\n <GlobeIcon />\n </IconPanel>\n <Flex direction=\"column\">\n <Text size=\"1\" weight=\"bold\">\n <Translation\n defaultMessage=\"You'll be redirected to sign in with {integrationName}.\"\n id=\"g+n4aY\"\n description=\"Instruction about redirect to sign in\"\n values={{ integrationName: integration.name }}\n />\n </Text>\n <Text size=\"1\">\n <Translation\n defaultMessage=\"Authorize access to connect your account.\"\n id=\"fxVS34\"\n description=\"Instruction to authorize access\"\n />\n </Text>\n </Flex>\n </Flex>\n <Flex gap=\"2\" align=\"center\">\n <IconPanel color=\"gray\" style={{ width: \"32px\", height: \"32px\" }}>\n <LockClosedIcon />\n </IconPanel>\n <Flex direction=\"column\">\n <Text size=\"1\" weight=\"bold\">\n <Translation\n defaultMessage=\"Your credentials remain secure.\"\n id=\"gM3bot\"\n description=\"Security message about credentials\"\n />\n </Text>\n <Text size=\"1\">\n <Translation\n defaultMessage=\"WorkOS never sees your credentials.\"\n id=\"kC9Fwe\"\n description=\"Security message about WorkOS not seeing credentials\"\n />\n </Text>\n </Flex>\n </Flex>\n </Flex>\n </Card>\n );\n}\n\n/**\n * The single connect dialog for all non-API (OAuth) providers. When the\n * provider declares unpinned `installation`-scope config fields (e.g. a Zendesk\n * subdomain), it opens on a field-collection step (values validated against the\n * descriptor `required` / `pattern`) before the redirect explainer; otherwise\n * it opens directly on the explainer. Collected values are submitted as\n * `config` on the POST authorize call. Controlled so it backs the initial\n * connect flow, the dual-method OAuth option, and reauthorization.\n */\nfunction ConnectDialog({\n integration,\n fields,\n open,\n onOpenChange,\n onConnect,\n collectName = false,\n}: {\n integration: DataIntegration;\n fields: DataIntegrationConfigField[];\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /**\n * Starts the authorization, from the row that owns its result (and so the\n * connection it targets): `openAuthorizeUrl` of\n * {@link useOpenDataIntegrationAuthorizeUrl}.\n */\n onConnect: ConnectHandler;\n /**\n * Asks for an optional name for the connection the authorization creates.\n * Only set when adding a connection; a first connect leaves naming to\n * Rename.\n */\n collectName?: boolean;\n}) {\n // Providers without fields to collect skip straight to the explainer.\n const initialStep = fields.length > 0 ? \"fields\" : \"review\";\n const [step, setStep] = useState<\"fields\" | \"review\">(initialStep);\n const [submitError, setSubmitError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [name, setName] = useState(\"\");\n const configForm = useConfigFieldsForm(fields);\n const translate = useTranslation();\n const nameField = collectName && (\n <ConnectionNameField\n id={`pipes-connect-name-${integration.id}`}\n value={name}\n onChange={setName}\n />\n );\n\n const genericConnectError = translate({\n defaultMessage: \"We couldn't start the connection. Please try again.\",\n id: \"zGw1ma\",\n description:\n \"Fallback error shown when starting the connection fails for a non-specific reason\",\n });\n\n const reset = () => {\n setStep(initialStep);\n configForm.reset();\n setName(\"\");\n setSubmitError(null);\n setIsSubmitting(false);\n };\n\n const handleConnect = async () => {\n setSubmitError(null);\n setIsSubmitting(true);\n try {\n // Opens the popup synchronously within this click before awaiting.\n await onConnect(configForm.buildConfig(), collectName ? name : undefined);\n onOpenChange(false);\n } catch (error) {\n // Surface a message for every failure mode (ApiError, network, blocked\n // popup, etc.) so the dialog never fails silently.\n setSubmitError(\n error instanceof ApiError && error.message\n ? error.message\n : genericConnectError,\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <Dialog.Root\n open={open}\n onOpenChange={(next) => {\n onOpenChange(next);\n if (!next) {\n reset();\n }\n }}\n >\n <Dialog.Content maxWidth=\"430px\">\n <ConnectDialogHeader integration={integration} />\n\n {step === \"fields\" ? (\n <>\n <Card>\n <Flex direction=\"column\" gap=\"4\">\n {nameField}\n <ConfigFieldInputs\n idPrefix=\"pipes-config\"\n fields={fields}\n values={configForm.values}\n errors={configForm.errors}\n onChange={configForm.setValue}\n />\n </Flex>\n </Card>\n <Flex justify=\"end\" gap=\"3\" mt=\"5\">\n <Dialog.Close>\n <Button variant=\"secondary\">\n <Translation\n defaultMessage=\"Cancel\"\n id=\"hHNj31\"\n description=\"Cancel button text\"\n />\n </Button>\n </Dialog.Close>\n <Button\n type=\"button\"\n disabled={configForm.hasMissingRequired}\n onClick={() => {\n if (configForm.validate()) {\n setStep(\"review\");\n }\n }}\n >\n <Translation\n defaultMessage=\"Next\"\n id=\"L2fmxK\"\n description=\"Button to advance to the next step of the connect flow\"\n />\n </Button>\n </Flex>\n </>\n ) : (\n <>\n {submitError && (\n <Callout.Root mb=\"3\" color=\"red\" role=\"alert\">\n <Callout.Text>{submitError}</Callout.Text>\n </Callout.Root>\n )}\n {/* With config fields, the name was asked for on the first step. */}\n {fields.length === 0 && nameField && (\n <Card mb=\"3\">{nameField}</Card>\n )}\n <ConnectExplainerCard integration={integration} />\n <Flex justify=\"end\" gap=\"3\" mt=\"5\">\n {fields.length > 0 ? (\n <Button\n variant=\"secondary\"\n type=\"button\"\n onClick={() => setStep(\"fields\")}\n >\n <Translation\n defaultMessage=\"Back\"\n id=\"J9MvVP\"\n description=\"Button to return to the previous step of the connect flow\"\n />\n </Button>\n ) : (\n <Dialog.Close>\n <Button variant=\"secondary\">\n <Translation\n defaultMessage=\"Cancel\"\n id=\"hHNj31\"\n description=\"Cancel button text\"\n />\n </Button>\n </Dialog.Close>\n )}\n <Button\n type=\"button\"\n loading={isSubmitting}\n disabled={isSubmitting}\n onClick={handleConnect}\n >\n <Translation\n defaultMessage=\"Connect\"\n id=\"16WmG0\"\n description=\"Connect button with external link\"\n trailingSpace\n />\n <ExternalLinkIcon aria-hidden />\n </Button>\n </Flex>\n </>\n )}\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/**\n * Connect button for a not-yet-connected OAuth provider. Opens the unified\n * {@link ConnectDialog}, which prompts for any unpinned `installation`-scope\n * config fields before the redirect explainer.\n */\nfunction ConnectIntegrationButton({\n integration,\n onConnect,\n}: {\n integration: DataIntegration;\n onConnect: ConnectHandler;\n}) {\n const [open, setOpen] = useState(false);\n const fields = getUnpinnedInstallationFields(integration);\n\n return (\n <>\n <ConnectDialog\n integration={integration}\n fields={fields}\n open={open}\n onOpenChange={setOpen}\n onConnect={onConnect}\n />\n <Button variant=\"secondary\" onClick={() => setOpen(true)}>\n <Translation\n defaultMessage=\"Connect\"\n id=\"quvdFp\"\n description=\"Button to connect an integration\"\n />\n </Button>\n </>\n );\n}\n\nconst API_KEY_REDACTED_PREFIX = \"••••\";\n\n/**\n * Stores an API key for the integration: the member's own installation, or,\n * with `owner=\"organization\"`, the one the organization shares with everyone\n * (`installation` then names that shared account).\n *\n * The write lands on `installation` (see {@link getConnectionTarget}) unless a\n * `target` says otherwise — `ADD_CONNECTION` with a null `installation` stores\n * the key as another connection.\n */\nfunction ApiKeyDialog({\n integration,\n installation = integration.installation,\n owner = \"user\",\n target = getConnectionTarget(installation),\n open,\n onOpenChange,\n onSuccess,\n collectName = false,\n}: {\n integration: DataIntegration;\n installation?: DataInstallation | null;\n owner?: ConnectionOwner;\n target?: ConnectionTarget;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Called after the key is saved. */\n onSuccess?: () => void;\n /**\n * Asks for an optional name for the connection the key creates. Only set\n * when adding a connection; a first connect leaves naming to Rename.\n */\n collectName?: boolean;\n}) {\n const invalidateConnections = useInvalidateConnections(owner);\n const attribution = usePipesCredentialAttribution();\n const attributionError =\n owner === \"organization\" ? attribution.error : undefined;\n const [name, setName] = useState(\"\");\n const isRotation =\n installation?.auth_method === \"api_key\" &&\n installation.state === \"connected\";\n const last4 = installation?.api_key_last_4;\n const maskedKey = last4 ? `${API_KEY_REDACTED_PREFIX}${last4}` : \"\";\n\n const [secret, setSecret] = useState(\"\");\n const translate = useTranslation();\n\n const apiKeyPlaceholder = translate({\n defaultMessage: \"Enter your API key\",\n id: \"MzSxEF\",\n description: \"Placeholder for the API key input field\",\n });\n\n const onUpserted = () => {\n onOpenChange(false);\n invalidateConnections();\n onSuccess?.();\n };\n const userUpsert = useClientGraphqlMutation({\n mutationFn: (sdk, input: CreateDataProviderConnectionInput) =>\n sdk.CreateDataProviderConnection({ input }),\n onSuccess: onUpserted,\n });\n const organizationUpsert = useClientGraphqlMutation({\n mutationFn: (sdk, input: CreateOrganizationDataProviderConnectionInput) =>\n sdk.CreateOrganizationDataProviderConnection({ input }),\n onSuccess: onUpserted,\n });\n const { error, reset, isPending } =\n owner === \"organization\" ? organizationUpsert : userUpsert;\n const upsertApiKey = (apiKey: string) => {\n const input = {\n dataProviderId: integration.id,\n apiKey,\n ...toCreationTargetInput(target),\n ...(collectName ? toAccountDisplayNameInput(name) : {}),\n };\n if (owner === \"organization\") {\n if (attributionError || !attribution.userId) return;\n organizationUpsert.mutate({ ...input, userId: attribution.userId });\n } else {\n userUpsert.mutate(input);\n }\n };\n\n // The component is only mounted while open (conditional rendering in\n // ApiKeyConnectButton / ProviderStatus), so state resets on mount.\n // We only need to reset the mutation state when the dialog opens in\n // case the same instance was reused.\n useEffect(() => {\n reset();\n }, [reset]);\n\n const errorMessage = (() => {\n if (!error) return null;\n if (error instanceof ApiError && error.message) {\n return error.message;\n }\n return null;\n })();\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content maxWidth=\"430px\">\n <Dialog.Title size=\"3\" weight=\"bold\">\n {isRotation ? (\n <Translation\n defaultMessage=\"Rotate API key for {integrationName}\"\n id=\"8+NN3t\"\n description=\"Dialog title for rotating an API key\"\n values={{ integrationName: integration.name }}\n />\n ) : (\n <Translation\n defaultMessage=\"Connect {integrationName} with API key\"\n id=\"EyItbA\"\n description=\"Dialog title for connecting with an API key\"\n values={{ integrationName: integration.name }}\n />\n )}\n </Dialog.Title>\n\n {/*\n * The provider's own description. Built-in providers are self-evident,\n * but a custom provider's definition copy is the only thing telling the\n * tenant which key to paste and where to mint it. Rendered as the\n * dialog's description so it's announced with the dialog rather than\n * being an unassociated paragraph.\n */}\n {integration.description && (\n <Dialog.Description color=\"gray\" mt=\"1\">\n {integration.description}\n </Dialog.Description>\n )}\n\n {(attributionError || error) && (\n <Callout.Root my=\"3\" color=\"red\" role=\"alert\">\n <Callout.Text>\n {attributionError ?? errorMessage ?? (\n <Translation\n defaultMessage=\"An error occurred. Please check the value and try again.\"\n id=\"bYLbLL\"\n description=\"Generic error message for API key submission failure\"\n />\n )}\n </Callout.Text>\n </Callout.Root>\n )}\n\n <Flex direction=\"column\" gap=\"4\" mt=\"2\">\n {collectName && (\n <ConnectionNameField\n id={`pipes-api-key-name-${integration.id}`}\n value={name}\n onChange={setName}\n />\n )}\n {isRotation && last4 && (\n <Flex direction=\"column\" gap=\"1\">\n <Label>\n <Translation\n defaultMessage=\"Current API key\"\n id=\"+odk8g\"\n description=\"Label for the current masked API key\"\n />\n </Label>\n <Text size=\"2\" color=\"gray\">\n {maskedKey}\n </Text>\n </Flex>\n )}\n\n <Flex direction=\"column\" gap=\"1\">\n <Label>\n {isRotation ? (\n <Translation\n defaultMessage=\"New API key\"\n id=\"L3AmMK\"\n description=\"Label for the new API key input when rotating\"\n />\n ) : (\n <Translation\n defaultMessage=\"API key\"\n id=\"Xnkv+J\"\n description=\"Label for the API key input\"\n />\n )}\n </Label>\n <PasswordField\n value={secret}\n autoComplete=\"off\"\n placeholder={apiKeyPlaceholder}\n onChange={(event) => setSecret(event.target.value)}\n />\n </Flex>\n </Flex>\n\n <Flex justify=\"end\" gap=\"3\" mt=\"5\">\n <Dialog.Close>\n <Button variant=\"secondary\">\n <Translation\n defaultMessage=\"Cancel\"\n id=\"hHNj31\"\n description=\"Cancel button text\"\n />\n </Button>\n </Dialog.Close>\n <Button\n type=\"button\"\n disabled={!!attributionError || isPending || !secret.trim()}\n loading={isPending}\n onClick={() => upsertApiKey(secret.trim())}\n >\n {isRotation ? (\n <Translation\n defaultMessage=\"Rotate\"\n id=\"LAh+p5\"\n description=\"Button to rotate an API key\"\n />\n ) : (\n <Translation\n defaultMessage=\"Connect\"\n id=\"quvdFp\"\n description=\"Button to connect an integration\"\n />\n )}\n </Button>\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\nfunction ApiKeyConnectButton({\n integration,\n}: {\n integration: DataIntegration;\n}) {\n const [open, setOpen] = useState(false);\n\n return (\n <>\n {open && (\n <ApiKeyDialog\n integration={integration}\n open={open}\n onOpenChange={setOpen}\n />\n )}\n <Button variant=\"secondary\" onClick={() => setOpen(true)}>\n <Translation\n defaultMessage=\"Connect\"\n id=\"quvdFp\"\n description=\"Button to connect an integration\"\n />\n </Button>\n </>\n );\n}\n\n/**\n * Connect form for the `client_credentials` auth method: the provider's client\n * id and secret plus any unpinned `installation`-scope config fields, rendered\n * generically from the descriptors via {@link ConfigFieldInputs}. Submits to\n * PUT `/DataIntegrations/:slug/client-credentials`, which also handles\n * replacing the credentials of an existing client-credentials installation.\n *\n * For an existing installation the form is prefilled from it: the client id as\n * received, the stored secret as a redacted mask that clears on focus (the\n * real value is never sent to the widget, so a new secret must be re-entered\n * to save), and the config fields from `installation.config`. `config` is only\n * included in the payload when the user edits a config field, since the API\n * keeps the stored config when the key is absent; when it is included it is\n * the full round-tripped object, because the write replaces config wholesale.\n */\nfunction ClientCredentialsDialog({\n integration,\n installation = integration.installation,\n owner = \"user\",\n target = getConnectionTarget(installation),\n fields,\n open,\n onOpenChange,\n onSuccess,\n collectName = false,\n}: {\n integration: DataIntegration;\n installation?: DataInstallation | null;\n owner?: ConnectionOwner;\n /** As on {@link ApiKeyDialog}: defaults to `installation` itself. */\n target?: ConnectionTarget;\n fields: DataIntegrationConfigField[];\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Called after the credentials are saved. */\n onSuccess?: () => void;\n /** As on {@link ApiKeyDialog}. */\n collectName?: boolean;\n}) {\n const invalidateConnections = useInvalidateConnections(owner);\n const attribution = usePipesCredentialAttribution();\n const attributionError =\n owner === \"organization\" ? attribution.error : undefined;\n const [name, setName] = useState(\"\");\n const isUpdate = installation?.auth_method === \"client_credentials\";\n const storedConfig = useMemo(\n () => (isUpdate ? (installation?.config ?? {}) : {}),\n [isUpdate, installation?.config],\n );\n const initialConfigValues = useMemo(\n () => getInitialConfigValues(fields, storedConfig),\n [fields, storedConfig],\n );\n const redactedSecret = buildRedactedSecret(\n isUpdate ? installation?.client_secret_last_4 : null,\n );\n\n const [clientId, setClientId] = useState(\n (isUpdate ? installation?.client_id : null) ?? \"\",\n );\n const [clientSecret, setClientSecret] = useState(redactedSecret);\n const configForm = useConfigFieldsForm(fields, initialConfigValues);\n const translate = useTranslation();\n\n const clientIdPlaceholder = translate({\n defaultMessage: \"Enter your client ID\",\n id: \"5YTAFo\",\n description: \"Placeholder for the client credentials client ID input\",\n });\n const clientSecretPlaceholder = translate({\n defaultMessage: \"Enter your client secret\",\n id: \"53f0B7\",\n description: \"Placeholder for the client credentials client secret input\",\n });\n\n // The widget never holds the real secret, so the prefilled mask can't be\n // submitted: the PUT requires a client secret and re-entry is the only way\n // to supply one.\n const secretMissing = !clientSecret.trim() || isRedactedSecret(clientSecret);\n\n const onUpserted = () => {\n onOpenChange(false);\n invalidateConnections();\n onSuccess?.();\n };\n const userUpsert = useClientGraphqlMutation({\n mutationFn: async (\n sdk,\n input: ConnectDataProviderWithClientCredentialsInput,\n ) => {\n const { connectDataProviderWithClientCredentials: result } =\n await sdk.ConnectDataProviderWithClientCredentials({ input });\n return unwrapClientCredentialsConnection(result);\n },\n onSuccess: onUpserted,\n });\n const organizationUpsert = useClientGraphqlMutation({\n mutationFn: async (\n sdk,\n input: ConnectOrganizationDataProviderWithClientCredentialsInput,\n ) => {\n const { connectOrganizationDataProviderWithClientCredentials: result } =\n await sdk.ConnectOrganizationDataProviderWithClientCredentials({\n input,\n });\n return unwrapClientCredentialsConnection(result);\n },\n onSuccess: onUpserted,\n });\n const { error, isPending } =\n owner === \"organization\" ? organizationUpsert : userUpsert;\n\n // Server errors — including the 409 raised when an installation already\n // exists with a different auth method — are surfaced in the banner.\n const errorMessage =\n error instanceof ApiError && error.message ? error.message : null;\n\n const handleSubmit = () => {\n if (attributionError) return;\n if (!configForm.validate()) {\n return;\n }\n // Untouched config fields mean no `config` key at all: the API preserves\n // the stored config when it's absent, and sending the prefilled object\n // back would make every credential update a config write too.\n const config = configForm.isDirty\n ? configForm.buildConfigPayload(storedConfig)\n : undefined;\n const input = {\n dataProviderId: integration.id,\n clientId: clientId.trim(),\n clientSecret: clientSecret.trim(),\n config: toConfigEntries(config),\n ...toCreationTargetInput(target),\n ...(collectName ? toAccountDisplayNameInput(name) : {}),\n };\n if (owner === \"organization\") {\n if (!attribution.userId) return;\n organizationUpsert.mutate({ ...input, userId: attribution.userId });\n } else {\n userUpsert.mutate(input);\n }\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content maxWidth=\"430px\">\n <Dialog.Title size=\"3\" weight=\"bold\">\n {isUpdate ? (\n <Translation\n defaultMessage=\"Update client credentials for {integrationName}\"\n id=\"/D85zF\"\n description=\"Dialog title for updating stored client credentials\"\n values={{ integrationName: integration.name }}\n />\n ) : (\n <Translation\n defaultMessage=\"Connect {integrationName} with client credentials\"\n id=\"x+7tw3\"\n description=\"Dialog title for connecting with client credentials\"\n values={{ integrationName: integration.name }}\n />\n )}\n </Dialog.Title>\n\n {(attributionError || error) && (\n <Callout.Root my=\"3\" color=\"red\" role=\"alert\">\n <Callout.Text>\n {attributionError ?? errorMessage ?? (\n <Translation\n defaultMessage=\"An error occurred. Please check the value and try again.\"\n id=\"bYLbLL\"\n description=\"Generic error message for API key submission failure\"\n />\n )}\n </Callout.Text>\n </Callout.Root>\n )}\n\n <Flex direction=\"column\" gap=\"4\" mt=\"2\">\n {collectName && (\n <ConnectionNameField\n id={`pipes-client-credentials-name-${integration.id}`}\n value={name}\n onChange={setName}\n />\n )}\n <Flex direction=\"column\" gap=\"1\">\n <Label htmlFor=\"pipes-client-credentials-client-id\">\n <Translation\n defaultMessage=\"Client ID\"\n id=\"/Cv5P1\"\n description=\"Label for the client credentials client ID input\"\n />\n </Label>\n <TextField\n id=\"pipes-client-credentials-client-id\"\n value={clientId}\n autoComplete=\"off\"\n placeholder={clientIdPlaceholder}\n onChange={(event) => setClientId(event.target.value)}\n />\n </Flex>\n\n <Flex direction=\"column\" gap=\"1\">\n <Label htmlFor=\"pipes-client-credentials-client-secret\">\n <Translation\n defaultMessage=\"Client secret\"\n id=\"uScBDj\"\n description=\"Label for the client credentials client secret input\"\n />\n </Label>\n {isUpdate && (\n <Text\n color=\"gray\"\n size=\"2\"\n id=\"pipes-client-credentials-client-secret-description\"\n mb=\"1\"\n >\n <Translation\n defaultMessage=\"Enter the client secret again to save any changes.\"\n id=\"ZrNPCF\"\n description=\"Help text explaining the client secret must be re-entered to save an update\"\n />\n </Text>\n )}\n <PasswordField\n id=\"pipes-client-credentials-client-secret\"\n value={clientSecret}\n autoComplete=\"off\"\n // The mask is what's shown, so render it as text: a password\n // input would re-bullet its last four digits away.\n type={isRedactedSecret(clientSecret) ? \"text\" : undefined}\n placeholder={clientSecretPlaceholder}\n aria-describedby={\n isUpdate\n ? \"pipes-client-credentials-client-secret-description\"\n : undefined\n }\n onChange={(event) => setClientSecret(event.target.value)}\n onFocus={() => {\n if (isRedactedSecret(clientSecret)) {\n setClientSecret(\"\");\n }\n }}\n onBlur={() => {\n if (clientSecret === \"\") {\n setClientSecret(redactedSecret);\n }\n }}\n />\n </Flex>\n\n <ConfigFieldInputs\n idPrefix=\"pipes-client-credentials-config\"\n fields={fields}\n values={configForm.values}\n errors={configForm.errors}\n onChange={configForm.setValue}\n />\n </Flex>\n\n <Flex justify=\"end\" gap=\"3\" mt=\"5\">\n <Dialog.Close>\n <Button variant=\"secondary\">\n <Translation\n defaultMessage=\"Cancel\"\n id=\"hHNj31\"\n description=\"Cancel button text\"\n />\n </Button>\n </Dialog.Close>\n <Button\n type=\"button\"\n disabled={\n !!attributionError ||\n isPending ||\n !clientId.trim() ||\n secretMissing ||\n configForm.hasMissingRequired\n }\n loading={isPending}\n onClick={handleSubmit}\n >\n {isUpdate ? (\n <Translation\n defaultMessage=\"Save\"\n id=\"RT8KNi\"\n description=\"Save button text\"\n />\n ) : (\n <Translation\n defaultMessage=\"Connect\"\n id=\"quvdFp\"\n description=\"Button to connect an integration\"\n />\n )}\n </Button>\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\nfunction ClientCredentialsConnectButton({\n integration,\n}: {\n integration: DataIntegration;\n}) {\n const [open, setOpen] = useState(false);\n const fields = getUnpinnedInstallationFields(integration);\n\n return (\n <>\n {open && (\n <ClientCredentialsDialog\n integration={integration}\n fields={fields}\n open={open}\n onOpenChange={setOpen}\n />\n )}\n <Button variant=\"secondary\" onClick={() => setOpen(true)}>\n <Translation\n defaultMessage=\"Connect\"\n id=\"quvdFp\"\n description=\"Button to connect an integration\"\n />\n </Button>\n </>\n );\n}\n\n/**\n * The methods another connection can be added with right now, in the order\n * the Connect menus offer them. Empty when the server reports no add available\n * (at the cap, multiple connections off, or no method currently usable).\n */\nfunction getAddConnectionMethods(\n capabilities: AddConnectionCapabilities,\n): DataIntegrationAuthMethod[] {\n if (!capabilities.canAddConnection) {\n return [];\n }\n return CONNECT_AUTH_METHODS.filter((method) =>\n capabilities.addConnectionMethods.includes(method),\n );\n}\n\n/** One menu item per connect method, as the Connect menus list them. */\nfunction ConnectMethodItems({\n methods,\n onSelect,\n}: {\n methods: DataIntegrationAuthMethod[];\n onSelect: (method: DataIntegrationAuthMethod) => void;\n}) {\n return (\n <>\n {methods.includes(\"oauth\") && (\n <DropdownMenu.Item onClick={() => onSelect(\"oauth\")}>\n <Flex gap=\"4\" width=\"100%\" justify=\"between\" align=\"center\">\n <Translation\n defaultMessage=\"Sign in with OAuth\"\n id=\"ssNz+0\"\n description=\"Menu option to connect via OAuth\"\n trailingSpace\n />\n <ExternalLinkIcon aria-hidden />\n </Flex>\n </DropdownMenu.Item>\n )}\n {methods.includes(\"client_credentials\") && (\n <DropdownMenu.Item onClick={() => onSelect(\"client_credentials\")}>\n <Translation\n defaultMessage=\"Enter client credentials\"\n id=\"Y/87Vt\"\n description=\"Menu option to connect via client credentials\"\n />\n </DropdownMenu.Item>\n )}\n {methods.includes(\"api_key\") && (\n <DropdownMenu.Item onClick={() => onSelect(\"api_key\")}>\n <Translation\n defaultMessage=\"Enter API key\"\n id=\"8mq2DA\"\n description=\"Menu option to connect via API key\"\n />\n </DropdownMenu.Item>\n )}\n </>\n );\n}\n\n/**\n * Connect entry point for a provider that supports more than one auth method:\n * a menu with one item per method, each opening that method's dialog.\n */\nfunction MultiMethodConnectButton({\n integration,\n methods,\n onConnect,\n onConnected,\n}: {\n integration: DataIntegration;\n methods: DataIntegrationAuthMethod[];\n onConnect: ConnectHandler;\n /** Called after an API key or client credentials connection succeeds. */\n onConnected?: () => void;\n}) {\n const [apiKeyOpen, setApiKeyOpen] = useState(false);\n const [oauthOpen, setOauthOpen] = useState(false);\n const [clientCredentialsOpen, setClientCredentialsOpen] = useState(false);\n const fields = getUnpinnedInstallationFields(integration);\n\n return (\n <>\n {apiKeyOpen && (\n <ApiKeyDialog\n integration={integration}\n open={apiKeyOpen}\n onOpenChange={setApiKeyOpen}\n onSuccess={onConnected}\n />\n )}\n {clientCredentialsOpen && (\n <ClientCredentialsDialog\n integration={integration}\n fields={fields}\n open={clientCredentialsOpen}\n onOpenChange={setClientCredentialsOpen}\n onSuccess={onConnected}\n />\n )}\n {methods.includes(\"oauth\") && (\n <ConnectDialog\n integration={integration}\n fields={fields}\n open={oauthOpen}\n onOpenChange={setOauthOpen}\n onConnect={onConnect}\n />\n )}\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <Button variant=\"secondary\">\n <Translation\n defaultMessage=\"Connect\"\n id=\"quvdFp\"\n description=\"Button to connect an integration\"\n />\n </Button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n <ConnectMethodItems\n methods={methods}\n onSelect={(method) =>\n method === \"oauth\"\n ? setOauthOpen(true)\n : method === \"client_credentials\"\n ? setClientCredentialsOpen(true)\n : setApiKeyOpen(true)\n }\n />\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n </>\n );\n}\n\n/**\n * Connecting another account to a provider the owner is already connected to:\n * `start(method, ADD_CONNECTION)` opens that method's connect dialog with the\n * `Add` intent, so the result is a new connection rather than a replacement\n * for the existing one.\n *\n * `start(method, undefined)` runs the same dialog untargeted instead, which\n * fills an empty compatibility slot — how an organization at the cap still\n * connects when only standard connections remain (`canConnect`). The target\n * is required rather than defaulted so that an explicit `undefined` can't be\n * mistaken for an `Add`.\n *\n * Owned by the provider's row: render `dialogs` there, and show\n * `connectionError` (an OAuth add that failed after its dialog closed) in that\n * row's status rather than on any one connection's.\n */\nfunction useAddConnectionFlow(\n integration: DataIntegration,\n owner: ConnectionOwner = \"user\",\n) {\n const [flow, setFlow] = useState<{\n method: DataIntegrationAuthMethod;\n target: ConnectionTarget | undefined;\n } | null>(null);\n const { openAuthorizeUrl, connectionError, clearConnectionError } =\n useOpenDataIntegrationAuthorizeUrl(integration, owner, flow?.target);\n const start = useCallback(\n (method: DataIntegrationAuthMethod, target: ConnectionTarget | undefined) =>\n setFlow({\n method,\n // Each start is one logical Add: it gets a fresh idempotency key that\n // every resubmit from this dialog reuses, so retrying an ambiguous\n // failure can't create a second connection.\n target: target?.intent === \"Add\" ? createAddConnectionTarget() : target,\n }),\n [],\n );\n const onOpenChange = (open: boolean) => {\n if (!open) {\n setFlow(null);\n }\n };\n\n // Only the sectioned experiences add connections, and every add creates\n // one, so each dialog asks for its name.\n const dialogs =\n flow?.method === \"api_key\" ? (\n <ApiKeyDialog\n integration={integration}\n installation={null}\n owner={owner}\n target={flow.target}\n open\n onOpenChange={onOpenChange}\n onSuccess={clearConnectionError}\n collectName\n />\n ) : flow?.method === \"client_credentials\" ? (\n <ClientCredentialsDialog\n integration={integration}\n installation={null}\n owner={owner}\n target={flow.target}\n fields={getUnpinnedInstallationFields(integration)}\n open\n onOpenChange={onOpenChange}\n onSuccess={clearConnectionError}\n collectName\n />\n ) : flow?.method === \"oauth\" ? (\n <ConnectDialog\n integration={integration}\n fields={getUnpinnedInstallationFields(integration)}\n open\n onOpenChange={onOpenChange}\n onConnect={openAuthorizeUrl}\n collectName\n />\n ) : null;\n\n return { start, dialogs, connectionError, clearConnectionError };\n}\n\n/**\n * The grouped provider row's Add connection button: a menu of the methods the\n * server says can add when there are several, otherwise straight into the one.\n * Renders nothing when no add is available. The row owns the flow it starts\n * ({@link useAddConnectionFlow}).\n */\nfunction AddConnectionButton({\n capabilities,\n onSelect,\n}: {\n capabilities: AddConnectionCapabilities;\n onSelect: (method: DataIntegrationAuthMethod) => void;\n}) {\n const methods = getAddConnectionMethods(capabilities);\n\n if (methods.length === 0) {\n return null;\n }\n\n return methods.length > 1 ? (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <Button variant=\"secondary\">\n <AddConnectionButtonLabel />\n </Button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n <ConnectMethodItems methods={methods} onSelect={onSelect} />\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n ) : (\n <Button variant=\"secondary\" onClick={() => onSelect(methods[0])}>\n <AddConnectionButtonLabel />\n </Button>\n );\n}\n\n/**\n * The Connect another account entry of a connection's overflow menu: a\n * submenu of methods when several can add. Renders nothing when no add is\n * available.\n */\nfunction ConnectAnotherAccountItem({\n capabilities,\n onSelect,\n}: {\n capabilities: AddConnectionCapabilities;\n onSelect: (method: DataIntegrationAuthMethod) => void;\n}) {\n const methods = getAddConnectionMethods(capabilities);\n\n if (methods.length === 0) {\n return null;\n }\n\n return methods.length > 1 ? (\n <DropdownMenu.Sub>\n <DropdownMenu.SubTrigger>\n <ConnectAnotherAccountMenuLabel />\n </DropdownMenu.SubTrigger>\n <DropdownMenu.SubContent>\n <ConnectMethodItems methods={methods} onSelect={onSelect} />\n </DropdownMenu.SubContent>\n </DropdownMenu.Sub>\n ) : (\n <DropdownMenu.Item onClick={() => onSelect(methods[0])}>\n <ConnectAnotherAccountMenuLabel />\n </DropdownMenu.Item>\n );\n}\n\nfunction ProviderStatus({ integration }: { integration: DataIntegration }) {\n const [disconnectOpen, setDisconnectOpen] = useState(false);\n const [apiKeyOpen, setApiKeyOpen] = useState(false);\n const [clientCredentialsOpen, setClientCredentialsOpen] = useState(false);\n const [reauthConfigOpen, setReauthConfigOpen] = useState(false);\n const {\n openAuthorizeUrl: authorizeEventHandler,\n connectionError,\n clearConnectionError,\n } = useOpenDataIntegrationAuthorizeUrl(integration);\n const translate = useTranslation();\n\n const pipeActionsTitle = translate({\n defaultMessage: \"Pipe actions\",\n id: \"1uF9ve\",\n description: \"Title for pipe actions dropdown button\",\n });\n\n // Unpinned installation fields must be re-collected on reauthorization too;\n // the authorize endpoint rejects them as missing otherwise.\n const unpinnedFields = getUnpinnedInstallationFields(integration);\n\n if (integration.installation) {\n const connected = integration.installation.state === \"connected\";\n const isApiKeyInstallation =\n integration.installation.auth_method === \"api_key\";\n const isClientCredentialsInstallation =\n integration.installation.auth_method === \"client_credentials\";\n\n return (\n <>\n <DisconnectAccountDialog\n integrationName={integration.name}\n installationId={integration.installation.id}\n open={disconnectOpen}\n onOpenChange={setDisconnectOpen}\n onSuccess={clearConnectionError}\n />\n {apiKeyOpen && (\n <ApiKeyDialog\n integration={integration}\n open={apiKeyOpen}\n onOpenChange={setApiKeyOpen}\n onSuccess={clearConnectionError}\n />\n )}\n {clientCredentialsOpen && (\n <ClientCredentialsDialog\n integration={integration}\n fields={unpinnedFields}\n open={clientCredentialsOpen}\n onOpenChange={setClientCredentialsOpen}\n onSuccess={clearConnectionError}\n />\n )}\n {unpinnedFields.length > 0 && !isClientCredentialsInstallation && (\n <ConnectDialog\n integration={integration}\n fields={unpinnedFields}\n open={reauthConfigOpen}\n onOpenChange={setReauthConfigOpen}\n onConnect={authorizeEventHandler}\n />\n )}\n <Flex align=\"center\" gap=\"4\">\n {connectionError ? (\n <ConnectionFailedStatus />\n ) : (\n <Status state={connected ? \"success\" : \"error\"}>\n {connected ? (\n <Translation\n defaultMessage=\"Connected\"\n id=\"i6Hxoz\"\n description=\"Status text for connected integration\"\n />\n ) : (\n <Translation\n defaultMessage=\"Requires reauthorization\"\n id=\"dqczQS\"\n description=\"Status text for integration needing reauthorization\"\n />\n )}\n </Status>\n )}\n {isClientCredentialsInstallation ? (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <IconButton title={pipeActionsTitle}>\n <DotsHorizontalIcon />\n </IconButton>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n <DropdownMenu.Item\n onClick={() => setClientCredentialsOpen(true)}\n >\n <Translation\n defaultMessage=\"Update client credentials\"\n id=\"daHKWE\"\n description=\"Menu option to update stored client credentials\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item\n variant=\"destructive\"\n onClick={() => setDisconnectOpen(true)}\n >\n <Translation\n defaultMessage=\"Disconnect account\"\n id=\"esZQrd\"\n description=\"Menu option to disconnect an account\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n ) : connected && isApiKeyInstallation ? (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <IconButton title={pipeActionsTitle}>\n <DotsHorizontalIcon />\n </IconButton>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n <DropdownMenu.Item onClick={() => setApiKeyOpen(true)}>\n <Translation\n defaultMessage=\"Rotate API key\"\n id=\"GML+c8\"\n description=\"Menu option to rotate the API key\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item\n variant=\"destructive\"\n onClick={() => setDisconnectOpen(true)}\n >\n <Translation\n defaultMessage=\"Disconnect account\"\n id=\"esZQrd\"\n description=\"Menu option to disconnect an account\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n ) : connected ? (\n <Button variant=\"secondary\" onClick={() => setDisconnectOpen(true)}>\n <Translation\n defaultMessage=\"Disconnect\"\n id=\"vMVXQh\"\n description=\"Button to disconnect an account\"\n />\n </Button>\n ) : isApiKeyInstallation ? (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <IconButton title={pipeActionsTitle}>\n <DotsHorizontalIcon />\n </IconButton>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n <DropdownMenu.Item onClick={() => setApiKeyOpen(true)}>\n <Translation\n defaultMessage=\"Update API key\"\n id=\"E7pMj/\"\n description=\"Menu option to update the API key for a needs-reauthorization installation\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item\n variant=\"destructive\"\n onClick={() => setDisconnectOpen(true)}\n >\n <Translation\n defaultMessage=\"Disconnect account\"\n id=\"esZQrd\"\n description=\"Menu option to disconnect an account\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n ) : (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <IconButton title={pipeActionsTitle}>\n <DotsHorizontalIcon />\n </IconButton>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n <DropdownMenu.Item\n onClick={async () => {\n if (unpinnedFields.length > 0) {\n setReauthConfigOpen(true);\n return;\n }\n try {\n await authorizeEventHandler();\n } catch {\n // pass - error displayed in new tab\n }\n }}\n >\n <Flex gap=\"4\" width=\"100%\" justify=\"between\" align=\"center\">\n <Translation\n defaultMessage=\"Reauthorize\"\n id=\"0E29F1\"\n description=\"Menu option to reauthorize an integration\"\n trailingSpace\n />\n <ExternalLinkIcon aria-hidden />\n </Flex>\n </DropdownMenu.Item>\n <DropdownMenu.Item\n variant=\"destructive\"\n onClick={() => setDisconnectOpen(true)}\n >\n <Translation\n defaultMessage=\"Disconnect account\"\n id=\"esZQrd\"\n description=\"Menu option to disconnect an account\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n )}\n </Flex>\n </>\n );\n }\n\n // Not connected: choose the connect entry point from the supported methods.\n // More than one: a menu of methods; otherwise that method's own button, with\n // OAuth as the default for a provider that declares nothing.\n const authMethods = integration.authMethods ?? [];\n const methods = CONNECT_AUTH_METHODS.filter((method) =>\n authMethods.includes(method),\n );\n\n const notConnectedStatus = connectionError ? (\n <ConnectionFailedStatus />\n ) : (\n <Status state=\"neutral\">\n <Translation\n defaultMessage=\"Not connected\"\n id=\"J7bTZa\"\n description=\"Status text for an integration that is not connected\"\n />\n </Status>\n );\n\n return (\n <Flex align=\"center\" gap=\"4\">\n {notConnectedStatus}\n {methods.length > 1 ? (\n <MultiMethodConnectButton\n integration={integration}\n methods={methods}\n onConnect={authorizeEventHandler}\n onConnected={clearConnectionError}\n />\n ) : methods.length === 1 && methods[0] === \"api_key\" ? (\n <ApiKeyConnectButton integration={integration} />\n ) : methods.length === 1 && methods[0] === \"client_credentials\" ? (\n <ClientCredentialsConnectButton integration={integration} />\n ) : (\n <ConnectIntegrationButton\n integration={integration}\n onConnect={authorizeEventHandler}\n />\n )}\n </Flex>\n );\n}\n\nfunction DisconnectAccountDialog({\n integrationName,\n installationId,\n open,\n onOpenChange,\n onSuccess,\n}: {\n integrationName: string;\n installationId: string;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Called after the connection is removed. */\n onSuccess?: () => void;\n}) {\n const queryClient = useQueryClient();\n const {\n mutate: deleteDataInstallation,\n error,\n reset,\n isPending,\n } = useClientGraphqlMutation({\n mutationFn: (sdk, id: string) => sdk.DeleteDataProviderConnection({ id }),\n onSuccess: () => {\n onOpenChange(false);\n for (const queryKey of myDataIntegrationsQueryKeys) {\n queryClient.invalidateQueries({ queryKey });\n }\n onSuccess?.();\n },\n });\n\n useEffect(() => {\n if (open) {\n reset();\n }\n }, [open, reset]);\n\n return (\n <AlertDialog.Root open={open} onOpenChange={onOpenChange}>\n <AlertDialog.Content style={{ width: \"80vw\", maxWidth: \"520px\" }}>\n <AlertDialog.Title>\n <Translation\n defaultMessage=\"Disconnect account\"\n id=\"9ABlCr\"\n description=\"Dialog title for disconnecting an account\"\n />\n </AlertDialog.Title>\n {error && (\n <Callout.Root my=\"5\" color=\"red\" role=\"alert\">\n <Callout.Text>\n <Translation\n defaultMessage=\"An error occurred while disconnecting your account. Please refresh the page and try again.\"\n id=\"qKBKF7\"\n description=\"Error message when disconnecting an account fails\"\n />\n </Callout.Text>\n </Callout.Root>\n )}\n <AlertDialog.Description>\n <Translation\n defaultMessage=\"Are you sure you want to disconnect your {integrationName} account?\"\n id=\"eEXeqP\"\n description=\"Confirmation message for disconnecting an account\"\n values={{\n integrationName: (\n <Text as=\"span\" weight=\"bold\">\n {integrationName}\n </Text>\n ),\n }}\n />\n </AlertDialog.Description>\n <Flex gap=\"3\" justify=\"end\" mt=\"5\">\n <AlertDialog.Cancel>\n <Button variant=\"secondary\">\n <Translation\n defaultMessage=\"Cancel\"\n id=\"hHNj31\"\n description=\"Cancel button text\"\n />\n </Button>\n </AlertDialog.Cancel>\n <Button\n variant=\"destructive\"\n disabled={isPending}\n loading={isPending}\n onClick={() => deleteDataInstallation(installationId)}\n >\n <Translation\n defaultMessage=\"Disconnect\"\n id=\"vMVXQh\"\n description=\"Button to disconnect an account\"\n />\n </Button>\n </Flex>\n </AlertDialog.Content>\n </AlertDialog.Root>\n );\n}\n\ninterface PipesLoadingProps extends WidgetRootDomProps {\n count: number;\n}\n\n/** The skeleton rows shared by the whole-widget and shared-section loaders. */\nfunction PipesSkeletonItems({ count }: { count: number }) {\n return Array.from({ length: count }).map((_, index) => (\n <CardList.Item key={index}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <Skeleton>\n <IconPanel>\n <ProviderIcon provider=\"google\" size=\"2\" />\n </IconPanel>\n </Skeleton>\n <Skeleton>\n <Text size=\"2\" weight=\"bold\">\n <Translation\n defaultMessage=\"Google Drive\"\n id=\"g11OOu\"\n description=\"Placeholder text for loading state\"\n />\n </Text>\n </Skeleton>\n </Flex>\n <Skeleton>\n <Button variant=\"secondary\" disabled>\n <Translation\n defaultMessage=\"Connect\"\n id=\"8TuDfA\"\n description=\"Placeholder button text for loading state\"\n />\n </Button>\n </Skeleton>\n </Flex>\n </CardList.Item>\n ));\n}\n\nconst PipesLoading: React.FC<PipesLoadingProps> = ({ count, ...domProps }) => {\n return (\n <CardList.Root {...getWidgetRootDomProps(\"loading\", domProps)}>\n <PipesSkeletonItems count={count} />\n </CardList.Root>\n );\n};\n\n/** The member's own connections, each with its credential-management actions. */\nfunction PipesItems({ integrations }: { integrations: DataIntegration[] }) {\n return integrations.map((integration) => (\n <CardList.Item key={integration.id}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <IconPanel color=\"panel\">\n <DataIntegrationIcon integration={integration} size=\"2\" />\n </IconPanel>\n <Text size=\"2\" weight=\"bold\">\n {integration.name}\n </Text>\n </Flex>\n <ProviderStatus integration={integration} />\n </Flex>\n </CardList.Item>\n ));\n}\n\n/**\n * Stands in for the rows a list has none of. Filtering is client-side, so an\n * empty list can say whether nothing is enabled yet or a `filter` emptied it.\n */\nfunction PipesEmptyItem({ isFiltered }: { isFiltered: boolean }) {\n return (\n <CardList.Item>\n <Text size=\"2\" color=\"gray\">\n {isFiltered ? (\n <Translation\n defaultMessage=\"No integrations to show.\"\n id=\"cAs7JC\"\n description=\"Empty state shown when the host's filter leaves no integrations to list\"\n />\n ) : (\n <Translation\n defaultMessage=\"No integrations are available yet.\"\n id=\"oK0Rjh\"\n description=\"Empty state shown when no integrations are enabled at all\"\n />\n )}\n </Text>\n </CardList.Item>\n );\n}\n\nconst Pipes: React.FC<PipesProps> = ({\n integrations,\n hasUnfilteredIntegrations,\n ...domProps\n}) => {\n return (\n <CardList.Root {...getWidgetRootDomProps(\"resolved\", domProps)}>\n {integrations.length > 0 ? (\n <PipesItems integrations={integrations} />\n ) : (\n <PipesEmptyItem isFiltered={hasUnfilteredIntegrations ?? false} />\n )}\n </CardList.Root>\n );\n};\n\n/**\n * A member's view of an organization-owned connection: usable as soon as one of\n * the organization's accounts is available, otherwise waiting on an\n * administrator. Members have no actions either way, so this is text only.\n */\nfunction SharedConnectionStatus({\n connection,\n}: {\n connection: SharedDataConnection;\n}) {\n const isAvailable = connection.connected_accounts.some(\n (account) => account.availability === \"available\",\n );\n\n return isAvailable ? (\n <Status state=\"success\">\n <Translation\n defaultMessage=\"Available\"\n id=\"_jQjSu\"\n description=\"Status text for a shared connection the member can use\"\n />\n </Status>\n ) : (\n <Status state=\"warning\">\n <Translation\n defaultMessage=\"Needs admin attention\"\n id=\"K5YoFj\"\n description=\"Status text for a shared connection an administrator must repair\"\n />\n </Status>\n );\n}\n\n/**\n * The sectioned row shell: the provider name with its state inline, the\n * connector description underneath, and actions confined to the right slot.\n *\n * Without an `icon` the row is one connection nested under its provider's row:\n * indented to the provider's text column and named in regular weight.\n */\nfunction SectionedItem({\n icon,\n name,\n status,\n description,\n actions,\n}: {\n icon?: React.ReactNode;\n name: string;\n status?: React.ReactNode;\n description?: string | null;\n actions?: React.ReactNode;\n}) {\n const nested = !icon;\n return (\n <CardList.Item nested={nested}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"4\">\n <Flex gap=\"4\" align=\"center\">\n {icon && <IconPanel color=\"panel\">{icon}</IconPanel>}\n <Flex direction=\"column\" gap=\"1\">\n <Flex align=\"center\" gap=\"2\" wrap=\"wrap\">\n <Text size=\"2\" weight={nested ? \"regular\" : \"bold\"}>\n {name}\n </Text>\n {status}\n </Flex>\n {description && (\n <Text size=\"2\" color=\"gray\">\n {description}\n </Text>\n )}\n </Flex>\n </Flex>\n {actions}\n </Flex>\n </CardList.Item>\n );\n}\n\n/**\n * A read-only row for an organization-owned connection. Shared connections\n * carry no `integrationType`, so the provider slug drives the icon fallbacks.\n */\nfunction SharedConnectionItem({\n connection,\n}: {\n connection: SharedDataConnection;\n}) {\n return (\n <SectionedItem\n icon={\n <DataIntegrationIcon\n integration={{\n integrationType: connection.slug,\n iconSlug: connection.iconSlug,\n iconUrl: connection.iconUrl,\n iconDarkUrl: connection.iconDarkUrl,\n }}\n size=\"2\"\n />\n }\n name={connection.name}\n status={<SharedConnectionStatus connection={connection} />}\n description={connection.description}\n />\n );\n}\n\n/**\n * One connection's state, inline beside its name. A failed OAuth handoff for\n * the row outranks the stored state until something clears it.\n */\nfunction MemberConnectionStatus({\n installation,\n connectionError,\n}: {\n installation: DataInstallation;\n connectionError: ConnectionError | null;\n}) {\n if (connectionError) {\n return <ConnectionFailedStatus />;\n }\n\n if (installation.state === \"connected\") {\n return (\n <Status state=\"success\">\n {installation.auth_method === \"api_key\" ? (\n <Translation\n defaultMessage=\"Connected via API key\"\n id=\"jQLTNe\"\n description=\"Status text for a connection established with an API key\"\n />\n ) : installation.auth_method === \"client_credentials\" ? (\n <Translation\n defaultMessage=\"Connected via client credentials\"\n id=\"hQKIrx\"\n description=\"Status text for a connection established with client credentials\"\n />\n ) : (\n <Translation\n defaultMessage=\"Connected via OAuth\"\n id=\"pJcK_M\"\n description=\"Status text for a connection established with OAuth\"\n />\n )}\n </Status>\n );\n }\n\n return (\n <Status state=\"warning\">\n {installation.auth_method === \"api_key\" ? (\n <Translation\n defaultMessage=\"Update your API key\"\n id=\"-YLPTk\"\n description=\"Status text for a connection whose API key stopped working\"\n />\n ) : (\n <Translation\n defaultMessage=\"Requires reauthorization\"\n id=\"dqczQS\"\n description=\"Status text for integration needing reauthorization\"\n />\n )}\n </Status>\n );\n}\n\n/** The right slot of a provider row the member has not connected yet. */\nfunction MemberConnectActions({\n integration,\n onConnect,\n onConnected,\n}: {\n integration: DataIntegration;\n onConnect: ConnectHandler;\n /** Called after an API key or client credentials connection succeeds. */\n onConnected: () => void;\n}) {\n const authMethods = integration.authMethods ?? [];\n const methods = CONNECT_AUTH_METHODS.filter((method) =>\n authMethods.includes(method),\n );\n\n return methods.length > 1 ? (\n <MultiMethodConnectButton\n integration={integration}\n methods={methods}\n onConnect={onConnect}\n onConnected={onConnected}\n />\n ) : methods.length === 1 && methods[0] === \"api_key\" ? (\n <ApiKeyConnectButton integration={integration} />\n ) : methods.length === 1 && methods[0] === \"client_credentials\" ? (\n <ClientCredentialsConnectButton integration={integration} />\n ) : (\n <ConnectIntegrationButton integration={integration} onConnect={onConnect} />\n );\n}\n\n/**\n * The right slot of one connection's row: the repair its state calls for,\n * promoted to a button, plus the management the connection supports. The state\n * itself lives beside the name, never here.\n */\nfunction MemberConnectionActions({\n integration,\n installation,\n label,\n onConnect,\n clearConnectionError,\n onAddConnection,\n}: {\n integration: DataIntegrationWithCapabilities;\n installation: DataInstallation;\n /** How the connection is named in its row, and so in the disconnect prompt. */\n label: string;\n /** Reauthorizes this exact connection (the row's authorize hook). */\n onConnect: (config?: Record<string, string>) => Promise<void>;\n /** Called once a connect or disconnect makes a prior OAuth failure moot. */\n clearConnectionError: () => void;\n /** Starts another connection, from the provider row that owns the add. */\n onAddConnection: (method: DataIntegrationAuthMethod) => void;\n}) {\n const [disconnectOpen, setDisconnectOpen] = useState(false);\n const [renameOpen, setRenameOpen] = useState(false);\n const [apiKeyOpen, setApiKeyOpen] = useState(false);\n const [clientCredentialsOpen, setClientCredentialsOpen] = useState(false);\n const [reauthConfigOpen, setReauthConfigOpen] = useState(false);\n const translate = useTranslation();\n\n const pipeActionsTitle = translate({\n defaultMessage: \"Pipe actions\",\n id: \"1uF9ve\",\n description: \"Title for pipe actions dropdown button\",\n });\n\n // Unpinned installation fields must be re-collected on reauthorization too;\n // the authorize endpoint rejects them as missing otherwise.\n const unpinnedFields = getUnpinnedInstallationFields(integration);\n\n const connected = installation.state === \"connected\";\n const isApiKeyInstallation = installation.auth_method === \"api_key\";\n const isClientCredentialsInstallation =\n installation.auth_method === \"client_credentials\";\n\n const openApiKey = () => setApiKeyOpen(true);\n const openClientCredentials = () => setClientCredentialsOpen(true);\n const reauthorize = async () => {\n if (unpinnedFields.length > 0) {\n setReauthConfigOpen(true);\n return;\n }\n try {\n await onConnect();\n } catch {\n // pass - error displayed in new tab\n }\n };\n\n // The API-key and client-credentials dialogs target `installation` itself\n // (see getConnectionTarget), as `onConnect` does for OAuth.\n return (\n <>\n <DisconnectAccountDialog\n integrationName={label}\n installationId={installation.id}\n open={disconnectOpen}\n onOpenChange={setDisconnectOpen}\n onSuccess={clearConnectionError}\n />\n {renameOpen && (\n <RenameConnectionDialog\n integrationName={integration.name}\n installation={installation}\n open={renameOpen}\n onOpenChange={setRenameOpen}\n />\n )}\n {apiKeyOpen && (\n <ApiKeyDialog\n integration={integration}\n installation={installation}\n open={apiKeyOpen}\n onOpenChange={setApiKeyOpen}\n onSuccess={clearConnectionError}\n />\n )}\n {clientCredentialsOpen && (\n <ClientCredentialsDialog\n integration={integration}\n installation={installation}\n fields={unpinnedFields}\n open={clientCredentialsOpen}\n onOpenChange={setClientCredentialsOpen}\n onSuccess={clearConnectionError}\n />\n )}\n {unpinnedFields.length > 0 && !isClientCredentialsInstallation && (\n <ConnectDialog\n integration={integration}\n fields={unpinnedFields}\n open={reauthConfigOpen}\n onOpenChange={setReauthConfigOpen}\n onConnect={onConnect}\n />\n )}\n <Flex align=\"center\" gap=\"4\" flexShrink=\"0\">\n {!connected &&\n (isApiKeyInstallation ? (\n <Button variant=\"secondary\" onClick={openApiKey}>\n <Translation\n defaultMessage=\"Update key\"\n id=\"MP-aOE\"\n description=\"Button to replace the API key of a connection that stopped working\"\n />\n </Button>\n ) : isClientCredentialsInstallation ? (\n <Button variant=\"secondary\" onClick={openClientCredentials}>\n <Translation\n defaultMessage=\"Update credentials\"\n id=\"1inB3Y\"\n description=\"Button to update the client credentials of a connection that stopped working\"\n />\n </Button>\n ) : (\n <Button variant=\"secondary\" onClick={reauthorize}>\n <Translation\n defaultMessage=\"Reauthorize\"\n id=\"3IbiTG\"\n description=\"Button to reauthorize a connection that stopped working\"\n />\n </Button>\n ))}\n <DropdownMenu.Root>\n <DropdownMenu.Trigger>\n <IconButton title={pipeActionsTitle}>\n <DotsHorizontalIcon />\n </IconButton>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\">\n {connected && isApiKeyInstallation && (\n <DropdownMenu.Item onClick={openApiKey}>\n <Translation\n defaultMessage=\"Rotate API key\"\n id=\"GML+c8\"\n description=\"Menu option to rotate the API key\"\n />\n </DropdownMenu.Item>\n )}\n {connected && isClientCredentialsInstallation && (\n <DropdownMenu.Item onClick={openClientCredentials}>\n <Translation\n defaultMessage=\"Update client credentials\"\n id=\"daHKWE\"\n description=\"Menu option to update stored client credentials\"\n />\n </DropdownMenu.Item>\n )}\n {canRenameConnections(integration) && (\n <DropdownMenu.Item onClick={() => setRenameOpen(true)}>\n <RenameMenuLabel />\n </DropdownMenu.Item>\n )}\n <ConnectAnotherAccountItem\n capabilities={integration.capabilities}\n onSelect={onAddConnection}\n />\n <DropdownMenu.Item\n variant=\"destructive\"\n onClick={() => setDisconnectOpen(true)}\n >\n <Translation\n defaultMessage=\"Disconnect account\"\n id=\"esZQrd\"\n description=\"Menu option to disconnect an account\"\n />\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n </Flex>\n </>\n );\n}\n\n/**\n * A provider row the member has connected at most once. Owns the OAuth flow\n * for its connection (or its first connect) and for adding another, so a\n * handoff failure reported after a dialog closes reaches the row status.\n */\nfunction MemberConnectionItem({\n integration,\n}: {\n integration: DataIntegrationWithCapabilities;\n}) {\n const installation = integration.connected_accounts[0];\n const { openAuthorizeUrl, connectionError, clearConnectionError } =\n useOpenDataIntegrationAuthorizeUrl(\n integration,\n \"user\",\n getConnectionTarget(installation),\n );\n const addConnection = useAddConnectionFlow(integration);\n const failure = connectionError ?? addConnection.connectionError;\n // The row reports its latest attempt: starting a repair (or the first\n // connect) retires a failed add's status, and starting an add retires a\n // failed repair's, so a success never sits under a stale failure.\n const startRepair = (config?: Record<string, string>) => {\n addConnection.clearConnectionError();\n return openAuthorizeUrl(config);\n };\n const startAdd = (method: DataIntegrationAuthMethod) => {\n clearConnectionError();\n addConnection.start(method, ADD_CONNECTION);\n };\n\n return (\n <>\n {addConnection.dialogs}\n <SectionedItem\n icon={<DataIntegrationIcon integration={integration} size=\"2\" />}\n name={integration.name}\n status={\n installation ? (\n <MemberConnectionStatus\n installation={installation}\n connectionError={failure}\n />\n ) : (\n failure && <ConnectionFailedStatus />\n )\n }\n description={integration.description}\n actions={\n installation ? (\n <MemberConnectionActions\n integration={integration}\n installation={installation}\n label={integration.name}\n onConnect={startRepair}\n clearConnectionError={() => {\n clearConnectionError();\n addConnection.clearConnectionError();\n }}\n onAddConnection={startAdd}\n />\n ) : (\n <MemberConnectActions\n integration={integration}\n onConnect={startRepair}\n onConnected={clearConnectionError}\n />\n )\n }\n />\n </>\n );\n}\n\n/**\n * One connection nested under its provider's row. Owns the OAuth flow for\n * repairing this exact connection; adding another goes through the provider\n * row, which shows that flow's result.\n */\nfunction MemberNestedConnectionItem({\n integration,\n installation,\n onAddConnection,\n onRepairStart,\n}: {\n integration: DataIntegrationWithCapabilities;\n installation: DataInstallation;\n onAddConnection: (method: DataIntegrationAuthMethod) => void;\n /** Lets the provider row retire a failed add once a repair starts. */\n onRepairStart: () => void;\n}) {\n const { openAuthorizeUrl, connectionError, clearConnectionError } =\n useOpenDataIntegrationAuthorizeUrl(\n integration,\n \"user\",\n getConnectionTarget(installation),\n );\n const startRepair = (config?: Record<string, string>) => {\n onRepairStart();\n return openAuthorizeUrl(config);\n };\n const label = getConnectionLabel(integration.name, installation);\n\n return (\n <SectionedItem\n name={label}\n status={\n <MemberConnectionStatus\n installation={installation}\n connectionError={connectionError}\n />\n }\n actions={\n <MemberConnectionActions\n integration={integration}\n installation={installation}\n label={label}\n onConnect={startRepair}\n clearConnectionError={clearConnectionError}\n onAddConnection={onAddConnection}\n />\n }\n />\n );\n}\n\n/**\n * A provider the member has connected more than once: the provider row counts\n * the connections and owns adding another (showing that flow's failure), and\n * each connection follows as its own nested row with its own state and actions.\n */\nfunction MemberConnectionGroup({\n integration,\n}: {\n integration: DataIntegrationWithCapabilities;\n}) {\n const addConnection = useAddConnectionFlow(integration);\n const startAdd = (method: DataIntegrationAuthMethod) =>\n addConnection.start(method, ADD_CONNECTION);\n\n return (\n <>\n {addConnection.dialogs}\n <SectionedItem\n icon={<DataIntegrationIcon integration={integration} size=\"2\" />}\n name={integration.name}\n status={\n addConnection.connectionError ? (\n <ConnectionFailedStatus />\n ) : (\n <ConnectionCountStatus\n count={integration.connected_accounts.length}\n />\n )\n }\n description={integration.description}\n actions={\n <AddConnectionButton\n capabilities={integration.capabilities}\n onSelect={startAdd}\n />\n }\n />\n {integration.connected_accounts.map((installation) => (\n <MemberNestedConnectionItem\n key={installation.id}\n integration={integration}\n installation={installation}\n onAddConnection={startAdd}\n onRepairStart={addConnection.clearConnectionError}\n />\n ))}\n </>\n );\n}\n\n/** The member's own connections in the sectioned experience. */\nfunction MemberConnectionItems({\n integrations,\n}: {\n integrations: DataIntegrationWithCapabilities[];\n}) {\n return integrations.map((integration) =>\n integration.connected_accounts.length > 1 ? (\n <MemberConnectionGroup key={integration.id} integration={integration} />\n ) : (\n <MemberConnectionItem key={integration.id} integration={integration} />\n ),\n );\n}\n\nfunction PipesSection({\n title,\n description,\n children,\n}: {\n title: React.ReactNode;\n description: React.ReactNode;\n children: React.ReactNode;\n}) {\n return (\n <Flex direction=\"column\" gap=\"3\">\n <Flex direction=\"column\" gap=\"1\">\n <Text size=\"3\" weight=\"bold\">\n {title}\n </Text>\n <Text size=\"2\" color=\"gray\">\n {description}\n </Text>\n </Flex>\n {children}\n </Flex>\n );\n}\n\n/**\n * The sectioned member experience: the connections the organization shares,\n * then the member's own. The two lanes come from different endpoints and are\n * never merged — the same provider can legitimately appear in both, once as an\n * organization-owned connection and once as the member's own account.\n *\n * The shared section is omitted entirely when the organization shares nothing\n * (or the request failed), leaving the member's own section usable on its own.\n */\nconst PipesSections: React.FC<PipesSectionsProps> = ({\n integrations,\n hasUnfilteredIntegrations,\n sharedConnections,\n hasUnfilteredSharedConnections,\n isSharedLoading,\n organizationName,\n ...domProps\n}) => {\n return (\n <Flex\n direction=\"column\"\n gap=\"5\"\n {...getWidgetRootDomProps(\"resolved\", domProps)}\n >\n {(isSharedLoading ||\n sharedConnections.length > 0 ||\n hasUnfilteredSharedConnections) && (\n <PipesSection\n title={\n <Translation\n defaultMessage=\"Shared connections\"\n id=\"Fcd-bK\"\n description=\"Heading for the section listing connections the organization owns\"\n />\n }\n description={\n organizationName ? (\n <Translation\n defaultMessage=\"Accounts {organizationName} owns and shares with everyone.\"\n id=\"7U8P0v\"\n description=\"Description of the shared connections section, naming the organization\"\n values={{ organizationName }}\n />\n ) : (\n <Translation\n defaultMessage=\"Accounts your organization owns and shares with everyone.\"\n id=\"72FEZi\"\n description=\"Description of the shared connections section when the organization name is unknown\"\n />\n )\n }\n >\n <CardList.Root>\n {isSharedLoading ? (\n <PipesSkeletonItems count={2} />\n ) : sharedConnections.length > 0 ? (\n sharedConnections.map((connection) => (\n <SharedConnectionItem\n key={connection.id}\n connection={connection}\n />\n ))\n ) : (\n <PipesEmptyItem isFiltered />\n )}\n </CardList.Root>\n </PipesSection>\n )}\n <PipesSection\n title={\n <Translation\n defaultMessage=\"Your connections\"\n id=\"-VDI3G\"\n description=\"Heading for the section listing the member's own connections\"\n />\n }\n description={\n <Translation\n defaultMessage=\"Connect your account to access these connections.\"\n id=\"ObXqUu\"\n description=\"Description of the personal connections section\"\n />\n }\n >\n <CardList.Root>\n {integrations.length > 0 ? (\n <MemberConnectionItems integrations={integrations} />\n ) : (\n <PipesEmptyItem isFiltered={hasUnfilteredIntegrations ?? false} />\n )}\n </CardList.Root>\n </PipesSection>\n </Flex>\n );\n};\n\ninterface PipesErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst PipesError: React.FC<PipesErrorProps> = ({ error, ...domProps }) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <GenericError error={error} />\n </Card>\n );\n};\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getWidgetDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"pipes\",\n widgetState: state,\n });\n}\n\nexport type {\n PipesProps,\n PipesSectionsProps,\n PipesLoadingProps,\n PipesErrorProps,\n ConnectionOwner,\n};\nexport {\n Pipes,\n PipesSections,\n PipesLoading,\n PipesError,\n PipesEmptyItem,\n PipesSection,\n ApiKeyDialog,\n ClientCredentialsDialog,\n ConnectDialog,\n ConnectionFailedStatus,\n getUnpinnedInstallationFields,\n useAddConnectionFlow,\n useOpenDataIntegrationAuthorizeUrl,\n};\n"],"mappings":"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"}
|