@workos-inc/widgets 1.16.0-next.1785954585478 → 1.16.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 CHANGED
@@ -1,11 +1,17 @@
1
1
  # Changelog
2
2
 
3
- ## 1.16.0-next.1785954585478
3
+ ## 1.16.0
4
4
 
5
5
  ### Minor Changes
6
6
 
7
7
  - Render provider-declared config fields in the DataIntegrations (Pipes) widget. The connect flow now collects unpinned `installation`-scope fields and submits them via POST authorize, and the organization configuration dialog renders `integration`-scope fields, submitted with the saved configuration.
8
8
 
9
+ - Add a `client_credentials` connect form to the DataIntegrations (Pipes) widget. Providers whose `authMethods` include `client_credentials` can now be connected by entering a client id and secret plus any unpinned `installation`-scope config fields, rendered generically from the provider's descriptors and submitted via PUT `/DataIntegrations/:slug/client-credentials`. An existing
10
+ `client_credentials` installation can be updated from the same form, prefilled
11
+ with its client id, a mask of the stored secret's last four digits, and its
12
+ stored config; the secret must be re-entered to save, and `config` is only
13
+ written when a config field is edited.
14
+
9
15
  ### Patch Changes
10
16
 
11
17
  - Sync generated API from upstream OpenAPI spec.
@@ -176,7 +176,7 @@ const TextFieldSlot = React.forwardRef(function TextFieldSlot2({ className, ...p
176
176
  }
177
177
  );
178
178
  });
179
- const PasswordField = React.forwardRef(function PasswordField2({ className, ...props }, ref) {
179
+ const PasswordField = React.forwardRef(function PasswordField2({ className, type, ...props }, ref) {
180
180
  const element = (0, import_widgets_context.useElement)("textfield");
181
181
  const [showPassword, setShowPassword] = React.useState(false);
182
182
  const translate = (0, import_use_translation.useTranslation)();
@@ -198,7 +198,7 @@ const PasswordField = React.forwardRef(function PasswordField2({ className, ...p
198
198
  className: (0, import_clsx.default)((0, import_utils.namespaceClassNames)("text-field"), className),
199
199
  ...props,
200
200
  ...element,
201
- type: showPassword ? "text" : "password",
201
+ type: type ?? (showPassword ? "text" : "password"),
202
202
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_themes.TextField.Slot, { side: "right", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
203
203
  IconButton,
204
204
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/elements.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n Avatar as RadixAvatar,\n AvatarProps as RadixAvatarProps,\n Badge as RadixBadge,\n IconButton as RadixIconButton,\n Skeleton as RadixSkeleton,\n Text,\n TextField as RadixTextField,\n type BadgeProps,\n type ButtonProps as RadixButtonProps,\n type IconButtonProps as RadixIconButtonProps,\n type SkeletonProps,\n type TextProps,\n Button as RadixButton,\n} from \"@radix-ui/themes\";\nimport type {\n GetPropDefTypes,\n avatarPropDefs,\n badgePropDefs,\n buttonPropDefs,\n dialogContentPropDefs,\n dropdownMenuContentPropDefs,\n dropdownMenuItemPropDefs,\n iconButtonPropDefs,\n textPropDefs,\n textFieldRootPropDefs,\n selectTriggerPropDefs,\n skeletonPropDefs,\n} from \"@radix-ui/themes/props\";\nimport cx from \"clsx\";\nimport { useElement } from \"./widgets-context.js\";\nimport { getDomProps, namespaceClassNames } from \"./utils.js\";\nimport { EyeClosedIcon, EyeOpenIcon } from \"@radix-ui/react-icons\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\n\nexport interface ButtonProps extends Omit<\n RadixButtonProps,\n \"variant\" | \"color\"\n> {\n variant?: \"primary\" | \"secondary\" | \"destructive\";\n unsafe_radixVariant?: RadixButtonProps[\"variant\"];\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n function Button(\n { className, variant = \"primary\", unsafe_radixVariant, ...props },\n ref,\n ) {\n const element = useElement(`${variant}Button`);\n\n const themeProps = (() => {\n let props: RadixButtonProps = {};\n if (variant === \"primary\") {\n props = {\n variant: \"solid\",\n } satisfies RadixButtonProps;\n } else if (variant === \"secondary\") {\n props = {\n highContrast: true,\n variant: \"surface\",\n color: \"gray\",\n } satisfies RadixButtonProps;\n } else if (variant === \"destructive\") {\n props = {\n variant: \"solid\",\n color: \"red\",\n } satisfies RadixButtonProps;\n } else {\n variant satisfies never;\n }\n\n if (unsafe_radixVariant) {\n props.variant = unsafe_radixVariant;\n }\n\n return props;\n })();\n\n return (\n <RadixButton\n ref={ref}\n {...getDomProps({\n elementId: `${variant}Button`,\n className: cx(\n className,\n // TODO: Remove BEM-style selector once conventions are standardized\n `button--${variant}`,\n ),\n })}\n {...themeProps}\n {...props}\n {...element}\n />\n );\n },\n);\n\nexport interface IconButtonProps extends RadixIconButtonProps {\n title: string;\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n function IconButton({ className, ...props }, ref) {\n const element = useElement(\"iconButton\");\n return (\n <RadixIconButton\n ref={ref}\n {...getDomProps({ elementId: \"iconButton\", className })}\n variant=\"ghost\"\n color=\"gray\"\n aria-label={props.title}\n {...props}\n {...element}\n />\n );\n },\n);\n\nexport const Skeleton = React.forwardRef<HTMLSpanElement, SkeletonProps>(\n function Skeleton({ className, ...props }, ref) {\n const element = useElement(\"skeleton\");\n return (\n <RadixSkeleton\n ref={ref}\n {...getDomProps({ elementId: \"skeleton\", className })}\n {...props}\n {...element}\n />\n );\n },\n);\n\nexport const Label = React.forwardRef<HTMLLabelElement, TextProps>(\n function Label({ children, className, style = {}, ...props }, ref) {\n const element = useElement(\"label\");\n return (\n <Text\n as=\"label\"\n ref={ref}\n weight=\"bold\"\n size=\"2\"\n {...getDomProps({ elementId: \"label\", className })}\n style={{ width: \"fit-content\", ...style }}\n // Text props are a complex union type depending on the `as` prop value,\n // which breaks down when spreading in `element`.\n {...(props as any)}\n {...element}\n >\n {children}\n </Text>\n );\n },\n);\n\nexport const TextField = React.forwardRef<\n HTMLInputElement,\n RadixTextField.RootProps\n>(function TextField({ className, ...props }, ref) {\n const element = useElement(\"textfield\");\n return (\n <RadixTextField.Root\n ref={ref}\n variant=\"surface\"\n className={cx(namespaceClassNames(\"text-field\"), className)}\n {...props}\n {...element}\n />\n );\n});\n\nexport const TextFieldSlot = React.forwardRef<\n HTMLDivElement,\n RadixTextField.SlotProps\n>(function TextFieldSlot({ className, ...props }, ref) {\n return (\n <RadixTextField.Slot\n ref={ref}\n className={cx(namespaceClassNames(\"text-field-slot\"), className)}\n {...props}\n />\n );\n});\n\nexport const PasswordField = React.forwardRef<\n HTMLInputElement,\n RadixTextField.RootProps\n>(function PasswordField({ className, ...props }, ref) {\n const element = useElement(\"textfield\");\n const [showPassword, setShowPassword] = React.useState(false);\n const translate = useTranslation();\n const hidePasswordText = translate({\n defaultMessage: \"Hide password\",\n id: \"Jv4Vps\",\n description: \"Button text to hide password\",\n });\n const showPasswordText = translate({\n defaultMessage: \"Show password\",\n id: \"UIfBSd\",\n description: \"Button text to show password\",\n });\n return (\n <RadixTextField.Root\n ref={ref}\n variant=\"surface\"\n className={cx(namespaceClassNames(\"text-field\"), className)}\n {...props}\n {...element}\n type={showPassword ? \"text\" : \"password\"}\n >\n <RadixTextField.Slot side=\"right\">\n <IconButton\n type=\"button\"\n size=\"1\"\n onClick={() => setShowPassword(!showPassword)}\n title={showPassword ? hidePasswordText : showPasswordText}\n >\n {showPassword ? <EyeOpenIcon /> : <EyeClosedIcon />}\n </IconButton>\n </RadixTextField.Slot>\n </RadixTextField.Root>\n );\n});\n\nexport const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(\n function Badge({ className, ...props }, ref) {\n const element = useElement(\"badge\");\n return (\n <RadixBadge\n ref={ref}\n {...getDomProps({ elementId: \"badge\", className })}\n {...props}\n {...element}\n />\n );\n },\n);\n\ninterface AvatarProps extends RadixAvatarProps {\n dim?: boolean;\n}\n\nexport const Avatar = React.forwardRef<HTMLImageElement, AvatarProps>(\n function Avatar({ dim, className, ...props }, ref) {\n const element = useElement(\"avatar\");\n return (\n <RadixAvatar\n ref={ref}\n color=\"gray\"\n {...getDomProps({ elementId: \"avatar\", className })}\n {...props}\n {...element}\n // TODO: use CSS var instead of hard-coded value for opacity\n style={dim ? { opacity: 0.6, ...props.style } : props.style}\n />\n );\n },\n);\n\ntype OmitAsChild<T> = {\n [K in keyof T]: T[K] extends undefined\n ? undefined\n : Omit<NonNullable<T[K]>, \"asChild\">;\n};\n\nexport * as Dialog from \"./elements/dialog.js\";\nexport * as AlertDialog from \"./elements/alert-dialog.js\";\nexport * as DropdownMenu from \"./elements/dropdown-menu.js\";\nexport * as Select from \"./elements/select.js\";\n\nexport type Elements = OmitAsChild<{\n dialog?: GetPropDefTypes<typeof dialogContentPropDefs>;\n primaryButton?: GetPropDefTypes<typeof buttonPropDefs>;\n secondaryButton?: GetPropDefTypes<typeof buttonPropDefs>;\n destructiveButton?: GetPropDefTypes<typeof buttonPropDefs>;\n iconButton?: GetPropDefTypes<typeof iconButtonPropDefs>;\n textfield?: GetPropDefTypes<typeof textFieldRootPropDefs>;\n select?: GetPropDefTypes<typeof selectTriggerPropDefs>;\n badge?: GetPropDefTypes<typeof badgePropDefs>;\n dropdown?: GetPropDefTypes<typeof dropdownMenuContentPropDefs>;\n primaryMenuItem?: GetPropDefTypes<typeof dropdownMenuItemPropDefs>;\n destructiveMenuItem?: GetPropDefTypes<typeof dropdownMenuItemPropDefs>;\n avatar?: Omit<GetPropDefTypes<typeof avatarPropDefs>, \"fallback\">;\n label?: GetPropDefTypes<typeof textPropDefs>;\n skeleton?: GetPropDefTypes<typeof skeletonPropDefs>;\n}>;\n"],"mappings":"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","names":["Button","props","RadixButton","cx","IconButton","RadixIconButton","Skeleton","RadixSkeleton","Label","TextField","RadixTextField","TextFieldSlot","PasswordField","Badge","RadixBadge","Avatar","RadixAvatar"]}
1
+ {"version":3,"sources":["../../../src/lib/elements.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n Avatar as RadixAvatar,\n AvatarProps as RadixAvatarProps,\n Badge as RadixBadge,\n IconButton as RadixIconButton,\n Skeleton as RadixSkeleton,\n Text,\n TextField as RadixTextField,\n type BadgeProps,\n type ButtonProps as RadixButtonProps,\n type IconButtonProps as RadixIconButtonProps,\n type SkeletonProps,\n type TextProps,\n Button as RadixButton,\n} from \"@radix-ui/themes\";\nimport type {\n GetPropDefTypes,\n avatarPropDefs,\n badgePropDefs,\n buttonPropDefs,\n dialogContentPropDefs,\n dropdownMenuContentPropDefs,\n dropdownMenuItemPropDefs,\n iconButtonPropDefs,\n textPropDefs,\n textFieldRootPropDefs,\n selectTriggerPropDefs,\n skeletonPropDefs,\n} from \"@radix-ui/themes/props\";\nimport cx from \"clsx\";\nimport { useElement } from \"./widgets-context.js\";\nimport { getDomProps, namespaceClassNames } from \"./utils.js\";\nimport { EyeClosedIcon, EyeOpenIcon } from \"@radix-ui/react-icons\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\n\nexport interface ButtonProps extends Omit<\n RadixButtonProps,\n \"variant\" | \"color\"\n> {\n variant?: \"primary\" | \"secondary\" | \"destructive\";\n unsafe_radixVariant?: RadixButtonProps[\"variant\"];\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n function Button(\n { className, variant = \"primary\", unsafe_radixVariant, ...props },\n ref,\n ) {\n const element = useElement(`${variant}Button`);\n\n const themeProps = (() => {\n let props: RadixButtonProps = {};\n if (variant === \"primary\") {\n props = {\n variant: \"solid\",\n } satisfies RadixButtonProps;\n } else if (variant === \"secondary\") {\n props = {\n highContrast: true,\n variant: \"surface\",\n color: \"gray\",\n } satisfies RadixButtonProps;\n } else if (variant === \"destructive\") {\n props = {\n variant: \"solid\",\n color: \"red\",\n } satisfies RadixButtonProps;\n } else {\n variant satisfies never;\n }\n\n if (unsafe_radixVariant) {\n props.variant = unsafe_radixVariant;\n }\n\n return props;\n })();\n\n return (\n <RadixButton\n ref={ref}\n {...getDomProps({\n elementId: `${variant}Button`,\n className: cx(\n className,\n // TODO: Remove BEM-style selector once conventions are standardized\n `button--${variant}`,\n ),\n })}\n {...themeProps}\n {...props}\n {...element}\n />\n );\n },\n);\n\nexport interface IconButtonProps extends RadixIconButtonProps {\n title: string;\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n function IconButton({ className, ...props }, ref) {\n const element = useElement(\"iconButton\");\n return (\n <RadixIconButton\n ref={ref}\n {...getDomProps({ elementId: \"iconButton\", className })}\n variant=\"ghost\"\n color=\"gray\"\n aria-label={props.title}\n {...props}\n {...element}\n />\n );\n },\n);\n\nexport const Skeleton = React.forwardRef<HTMLSpanElement, SkeletonProps>(\n function Skeleton({ className, ...props }, ref) {\n const element = useElement(\"skeleton\");\n return (\n <RadixSkeleton\n ref={ref}\n {...getDomProps({ elementId: \"skeleton\", className })}\n {...props}\n {...element}\n />\n );\n },\n);\n\nexport const Label = React.forwardRef<HTMLLabelElement, TextProps>(\n function Label({ children, className, style = {}, ...props }, ref) {\n const element = useElement(\"label\");\n return (\n <Text\n as=\"label\"\n ref={ref}\n weight=\"bold\"\n size=\"2\"\n {...getDomProps({ elementId: \"label\", className })}\n style={{ width: \"fit-content\", ...style }}\n // Text props are a complex union type depending on the `as` prop value,\n // which breaks down when spreading in `element`.\n {...(props as any)}\n {...element}\n >\n {children}\n </Text>\n );\n },\n);\n\nexport const TextField = React.forwardRef<\n HTMLInputElement,\n RadixTextField.RootProps\n>(function TextField({ className, ...props }, ref) {\n const element = useElement(\"textfield\");\n return (\n <RadixTextField.Root\n ref={ref}\n variant=\"surface\"\n className={cx(namespaceClassNames(\"text-field\"), className)}\n {...props}\n {...element}\n />\n );\n});\n\nexport const TextFieldSlot = React.forwardRef<\n HTMLDivElement,\n RadixTextField.SlotProps\n>(function TextFieldSlot({ className, ...props }, ref) {\n return (\n <RadixTextField.Slot\n ref={ref}\n className={cx(namespaceClassNames(\"text-field-slot\"), className)}\n {...props}\n />\n );\n});\n\nexport const PasswordField = React.forwardRef<\n HTMLInputElement,\n RadixTextField.RootProps\n>(function PasswordField({ className, type, ...props }, ref) {\n const element = useElement(\"textfield\");\n const [showPassword, setShowPassword] = React.useState(false);\n const translate = useTranslation();\n const hidePasswordText = translate({\n defaultMessage: \"Hide password\",\n id: \"Jv4Vps\",\n description: \"Button text to hide password\",\n });\n const showPasswordText = translate({\n defaultMessage: \"Show password\",\n id: \"UIfBSd\",\n description: \"Button text to show password\",\n });\n return (\n <RadixTextField.Root\n ref={ref}\n variant=\"surface\"\n className={cx(namespaceClassNames(\"text-field\"), className)}\n {...props}\n {...element}\n // An explicit `type` wins, so a caller holding a value that's already\n // redacted (a bullet mask) can render it as plain text.\n type={type ?? (showPassword ? \"text\" : \"password\")}\n >\n <RadixTextField.Slot side=\"right\">\n <IconButton\n type=\"button\"\n size=\"1\"\n onClick={() => setShowPassword(!showPassword)}\n title={showPassword ? hidePasswordText : showPasswordText}\n >\n {showPassword ? <EyeOpenIcon /> : <EyeClosedIcon />}\n </IconButton>\n </RadixTextField.Slot>\n </RadixTextField.Root>\n );\n});\n\nexport const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(\n function Badge({ className, ...props }, ref) {\n const element = useElement(\"badge\");\n return (\n <RadixBadge\n ref={ref}\n {...getDomProps({ elementId: \"badge\", className })}\n {...props}\n {...element}\n />\n );\n },\n);\n\ninterface AvatarProps extends RadixAvatarProps {\n dim?: boolean;\n}\n\nexport const Avatar = React.forwardRef<HTMLImageElement, AvatarProps>(\n function Avatar({ dim, className, ...props }, ref) {\n const element = useElement(\"avatar\");\n return (\n <RadixAvatar\n ref={ref}\n color=\"gray\"\n {...getDomProps({ elementId: \"avatar\", className })}\n {...props}\n {...element}\n // TODO: use CSS var instead of hard-coded value for opacity\n style={dim ? { opacity: 0.6, ...props.style } : props.style}\n />\n );\n },\n);\n\ntype OmitAsChild<T> = {\n [K in keyof T]: T[K] extends undefined\n ? undefined\n : Omit<NonNullable<T[K]>, \"asChild\">;\n};\n\nexport * as Dialog from \"./elements/dialog.js\";\nexport * as AlertDialog from \"./elements/alert-dialog.js\";\nexport * as DropdownMenu from \"./elements/dropdown-menu.js\";\nexport * as Select from \"./elements/select.js\";\n\nexport type Elements = OmitAsChild<{\n dialog?: GetPropDefTypes<typeof dialogContentPropDefs>;\n primaryButton?: GetPropDefTypes<typeof buttonPropDefs>;\n secondaryButton?: GetPropDefTypes<typeof buttonPropDefs>;\n destructiveButton?: GetPropDefTypes<typeof buttonPropDefs>;\n iconButton?: GetPropDefTypes<typeof iconButtonPropDefs>;\n textfield?: GetPropDefTypes<typeof textFieldRootPropDefs>;\n select?: GetPropDefTypes<typeof selectTriggerPropDefs>;\n badge?: GetPropDefTypes<typeof badgePropDefs>;\n dropdown?: GetPropDefTypes<typeof dropdownMenuContentPropDefs>;\n primaryMenuItem?: GetPropDefTypes<typeof dropdownMenuItemPropDefs>;\n destructiveMenuItem?: GetPropDefTypes<typeof dropdownMenuItemPropDefs>;\n avatar?: Omit<GetPropDefTypes<typeof avatarPropDefs>, \"fallback\">;\n label?: GetPropDefTypes<typeof textPropDefs>;\n skeleton?: GetPropDefTypes<typeof skeletonPropDefs>;\n}>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkFM;AAhFN,YAAuB;AACvB,oBAcO;AAeP,kBAAe;AACf,6BAA2B;AAC3B,mBAAiD;AACjD,yBAA2C;AAC3C,6BAA+B;AAyO/B,aAAwB;AACxB,kBAA6B;AAC7B,mBAA8B;AAC9B,aAAwB;AAlOjB,MAAM,SAAS,MAAM;AAAA,EAC1B,SAASA,QACP,EAAE,WAAW,UAAU,WAAW,qBAAqB,GAAG,MAAM,GAChE,KACA;AACA,UAAM,cAAU,mCAAW,GAAG,OAAO,QAAQ;AAE7C,UAAM,cAAc,MAAM;AACxB,UAAIC,SAA0B,CAAC;AAC/B,UAAI,YAAY,WAAW;AACzB,QAAAA,SAAQ;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF,WAAW,YAAY,aAAa;AAClC,QAAAA,SAAQ;AAAA,UACN,cAAc;AAAA,UACd,SAAS;AAAA,UACT,OAAO;AAAA,QACT;AAAA,MACF,WAAW,YAAY,eAAe;AACpC,QAAAA,SAAQ;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,QACT;AAAA,MACF,OAAO;AACL;AAAA,MACF;AAEA,UAAI,qBAAqB;AACvB,QAAAA,OAAM,UAAU;AAAA,MAClB;AAEA,aAAOA;AAAA,IACT,GAAG;AAEH,WACE;AAAA,MAAC,cAAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACC,OAAG,0BAAY;AAAA,UACd,WAAW,GAAG,OAAO;AAAA,UACrB,eAAW,YAAAC;AAAA,YACT;AAAA;AAAA,YAEA,WAAW,OAAO;AAAA,UACpB;AAAA,QACF,CAAC;AAAA,QACA,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AAMO,MAAM,aAAa,MAAM;AAAA,EAC9B,SAASC,YAAW,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AAChD,UAAM,cAAU,mCAAW,YAAY;AACvC,WACE;AAAA,MAAC,cAAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACC,OAAG,0BAAY,EAAE,WAAW,cAAc,UAAU,CAAC;AAAA,QACtD,SAAQ;AAAA,QACR,OAAM;AAAA,QACN,cAAY,MAAM;AAAA,QACjB,GAAG;AAAA,QACH,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AAEO,MAAM,WAAW,MAAM;AAAA,EAC5B,SAASC,UAAS,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AAC9C,UAAM,cAAU,mCAAW,UAAU;AACrC,WACE;AAAA,MAAC,cAAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACC,OAAG,0BAAY,EAAE,WAAW,YAAY,UAAU,CAAC;AAAA,QACnD,GAAG;AAAA,QACH,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AAEO,MAAM,QAAQ,MAAM;AAAA,EACzB,SAASC,OAAM,EAAE,UAAU,WAAW,QAAQ,CAAC,GAAG,GAAG,MAAM,GAAG,KAAK;AACjE,UAAM,cAAU,mCAAW,OAAO;AAClC,WACE;AAAA,MAAC;AAAA;AAAA,QACC,IAAG;AAAA,QACH;AAAA,QACA,QAAO;AAAA,QACP,MAAK;AAAA,QACJ,OAAG,0BAAY,EAAE,WAAW,SAAS,UAAU,CAAC;AAAA,QACjD,OAAO,EAAE,OAAO,eAAe,GAAG,MAAM;AAAA,QAGvC,GAAI;AAAA,QACJ,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEO,MAAM,YAAY,MAAM,WAG7B,SAASC,WAAU,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AACjD,QAAM,cAAU,mCAAW,WAAW;AACtC,SACE;AAAA,IAAC,cAAAC,UAAe;AAAA,IAAf;AAAA,MACC;AAAA,MACA,SAAQ;AAAA,MACR,eAAW,YAAAP,aAAG,kCAAoB,YAAY,GAAG,SAAS;AAAA,MACzD,GAAG;AAAA,MACH,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AAEM,MAAM,gBAAgB,MAAM,WAGjC,SAASQ,eAAc,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AACrD,SACE;AAAA,IAAC,cAAAD,UAAe;AAAA,IAAf;AAAA,MACC;AAAA,MACA,eAAW,YAAAP,aAAG,kCAAoB,iBAAiB,GAAG,SAAS;AAAA,MAC9D,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AAEM,MAAM,gBAAgB,MAAM,WAGjC,SAASS,eAAc,EAAE,WAAW,MAAM,GAAG,MAAM,GAAG,KAAK;AAC3D,QAAM,cAAU,mCAAW,WAAW;AACtC,QAAM,CAAC,cAAc,eAAe,IAAI,MAAM,SAAS,KAAK;AAC5D,QAAM,gBAAY,uCAAe;AACjC,QAAM,mBAAmB,UAAU;AAAA,IACjC,gBAAgB;AAAA,IAChB,IAAI;AAAA,IACJ,aAAa;AAAA,EACf,CAAC;AACD,QAAM,mBAAmB,UAAU;AAAA,IACjC,gBAAgB;AAAA,IAChB,IAAI;AAAA,IACJ,aAAa;AAAA,EACf,CAAC;AACD,SACE;AAAA,IAAC,cAAAF,UAAe;AAAA,IAAf;AAAA,MACC;AAAA,MACA,SAAQ;AAAA,MACR,eAAW,YAAAP,aAAG,kCAAoB,YAAY,GAAG,SAAS;AAAA,MACzD,GAAG;AAAA,MACH,GAAG;AAAA,MAGJ,MAAM,SAAS,eAAe,SAAS;AAAA,MAEvC,sDAAC,cAAAO,UAAe,MAAf,EAAoB,MAAK,SACxB;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,MAAK;AAAA,UACL,SAAS,MAAM,gBAAgB,CAAC,YAAY;AAAA,UAC5C,OAAO,eAAe,mBAAmB;AAAA,UAExC,yBAAe,4CAAC,kCAAY,IAAK,4CAAC,oCAAc;AAAA;AAAA,MACnD,GACF;AAAA;AAAA,EACF;AAEJ,CAAC;AAEM,MAAM,QAAQ,MAAM;AAAA,EACzB,SAASG,OAAM,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AAC3C,UAAM,cAAU,mCAAW,OAAO;AAClC,WACE;AAAA,MAAC,cAAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACC,OAAG,0BAAY,EAAE,WAAW,SAAS,UAAU,CAAC;AAAA,QAChD,GAAG;AAAA,QACH,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AAMO,MAAM,SAAS,MAAM;AAAA,EAC1B,SAASC,QAAO,EAAE,KAAK,WAAW,GAAG,MAAM,GAAG,KAAK;AACjD,UAAM,cAAU,mCAAW,QAAQ;AACnC,WACE;AAAA,MAAC,cAAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,OAAM;AAAA,QACL,OAAG,0BAAY,EAAE,WAAW,UAAU,UAAU,CAAC;AAAA,QACjD,GAAG;AAAA,QACH,GAAG;AAAA,QAEJ,OAAO,MAAM,EAAE,SAAS,KAAK,GAAG,MAAM,MAAM,IAAI,MAAM;AAAA;AAAA,IACxD;AAAA,EAEJ;AACF;","names":["Button","props","RadixButton","cx","IconButton","RadixIconButton","Skeleton","RadixSkeleton","Label","TextField","RadixTextField","TextFieldSlot","PasswordField","Badge","RadixBadge","Avatar","RadixAvatar"]}
@@ -54,9 +54,7 @@ var import_use_permissions = require("./use-permissions.js");
54
54
  var import_utils = require("./utils.js");
55
55
  var import_translation = require("./i18n/translation.js");
56
56
  var import_use_translation = require("./i18n/use-translation.js");
57
- const REDACTED_SECRET_PREFIX = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
58
- const buildRedactedSecret = (last4) => last4 ? `${REDACTED_SECRET_PREFIX}${last4}` : "";
59
- const isRedactedSecret = (value) => value.startsWith(REDACTED_SECRET_PREFIX);
57
+ var import_redacted_secret = require("./redacted-secret.js");
60
58
  function RedirectUriField({ value }) {
61
59
  const translate = (0, import_use_translation.useTranslation)();
62
60
  const copyLabel = translate({
@@ -85,7 +83,7 @@ function OrgCredentialsDialog({
85
83
  const credentials = integration.credentials;
86
84
  const hasCredentials = credentials.hasCredentials;
87
85
  const isOrgCredentials = credentials.credentialsType === "organization";
88
- const redactedSecret = buildRedactedSecret(credentials.redactedClientSecret);
86
+ const redactedSecret = (0, import_redacted_secret.buildRedactedSecret)(credentials.redactedClientSecret);
89
87
  const [clientId, setClientId] = (0, import_react.useState)(credentials.client_id ?? "");
90
88
  const [clientSecret, setClientSecret] = (0, import_react.useState)(redactedSecret);
91
89
  const [enabled, setEnabled] = (0, import_react.useState)(integration.enabled);
@@ -240,7 +238,7 @@ function OrgCredentialsDialog({
240
238
  setClientIdError(null);
241
239
  setClientSecretError(null);
242
240
  const trimmedId = clientId.trim();
243
- const secretUnchanged = hasCredentials && isRedactedSecret(clientSecret);
241
+ const secretUnchanged = hasCredentials && (0, import_redacted_secret.isRedactedSecret)(clientSecret);
244
242
  let valid = true;
245
243
  if (!trimmedId) {
246
244
  setClientIdError(configRequiredMessage);
@@ -279,7 +277,7 @@ function OrgCredentialsDialog({
279
277
  });
280
278
  return;
281
279
  }
282
- const secretUnchanged = hasCredentials && isRedactedSecret(clientSecret);
280
+ const secretUnchanged = hasCredentials && (0, import_redacted_secret.isRedactedSecret)(clientSecret);
283
281
  if (secretUnchanged) {
284
282
  upsertOverride({
285
283
  slug: integration.slug,
@@ -303,7 +301,7 @@ function OrgCredentialsDialog({
303
301
  const initialScopes = integration.scopes ?? [];
304
302
  const scopesChanged = scopes.length !== initialScopes.length || scopes.some((scope) => !initialScopes.includes(scope));
305
303
  const enabledChanged = enabled !== integration.enabled;
306
- const credentialsChanged = isOrgCredentials && (clientId.trim() !== (credentials.client_id ?? "") || clientSecret.trim() !== "" && !isRedactedSecret(clientSecret));
304
+ const credentialsChanged = isOrgCredentials && (clientId.trim() !== (credentials.client_id ?? "") || clientSecret.trim() !== "" && !(0, import_redacted_secret.isRedactedSecret)(clientSecret));
307
305
  const configChanged = configFields.some((field) => {
308
306
  const current = (configValues[field.key] ?? "").trim();
309
307
  const original = typeof integration.config?.[field.key] === "string" ? integration.config[field.key].trim() : "";
@@ -439,6 +437,7 @@ function OrgCredentialsDialog({
439
437
  {
440
438
  value: clientSecret,
441
439
  autoComplete: "off",
440
+ type: (0, import_redacted_secret.isRedactedSecret)(clientSecret) ? "text" : void 0,
442
441
  placeholder: clientSecretPlaceholder,
443
442
  "aria-invalid": !!clientSecretError || void 0,
444
443
  "aria-describedby": clientSecretError ? "pipes-admin-client-secret-error" : void 0,
@@ -447,7 +446,7 @@ function OrgCredentialsDialog({
447
446
  setClientSecretError(null);
448
447
  },
449
448
  onFocus: () => {
450
- if (isRedactedSecret(clientSecret)) {
449
+ if ((0, import_redacted_secret.isRedactedSecret)(clientSecret)) {
451
450
  setClientSecret("");
452
451
  }
453
452
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/pipes-admin.tsx"],"sourcesContent":["\"use client\";\nimport { Callout, Card, Flex, Switch, Text, Tooltip } from \"@radix-ui/themes\";\nimport { useState } from \"react\";\nimport { InfoCircledIcon } from \"@radix-ui/react-icons\";\nimport * as CardList from \"./card-list.js\";\nimport { CopyText } from \"./copy-text.js\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport { isKnownProviderIconSlug } from \"./provider-icon-slugs.js\";\nimport {\n Button,\n Dialog,\n Label,\n PasswordField,\n Skeleton,\n TextField,\n} from \"./elements.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { SearchableSelectList } from \"./searchable-select-list.js\";\nimport { Status } from \"./status.js\";\nimport {\n DataIntegrationConfiguration,\n getListDataIntegrationConfigurationsQueryKey,\n getMyDataIntegrationsQueryKey,\n useListDataIntegrationConfigurations,\n useUpsertDataIntegrationConfiguration,\n} from \"../api/endpoint.js\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { GenericError } from \"./generic-error.js\";\nimport { usePermissions } from \"./use-permissions.js\";\nimport { getDomProps, WidgetRootDomProps, WidgetRootState } from \"./utils.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\n\nconst REDACTED_SECRET_PREFIX = \"••••••••••••••••\";\n\n/** Masked display value for an existing secret: 16 bullets + the last 4 chars. */\nconst buildRedactedSecret = (last4: string | null | undefined): string =>\n last4 ? `${REDACTED_SECRET_PREFIX}${last4}` : \"\";\n\n/** True while the field still holds the unmodified redacted placeholder. */\nconst isRedactedSecret = (value: string): boolean =>\n value.startsWith(REDACTED_SECRET_PREFIX);\n\nfunction RedirectUriField({ value }: { value: string }) {\n const translate = useTranslation();\n\n const copyLabel = translate({\n defaultMessage: \"Copy redirect URI\",\n id: \"xqfxBC\",\n description: \"Accessible label for the copy redirect URI button\",\n });\n\n return (\n <Flex direction=\"column\" gap=\"1\">\n <Label>\n <Translation\n defaultMessage=\"Redirect URI\"\n id=\"lgEaUA\"\n description=\"Label for the read-only OAuth redirect URI field\"\n />\n </Label>\n <CopyText value={value} label={copyLabel} />\n </Flex>\n );\n}\n\nfunction OrgCredentialsDialog({\n integration,\n open,\n onOpenChange,\n}: {\n integration: DataIntegrationConfiguration;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}) {\n const queryClient = useQueryClient();\n const credentials = integration.credentials;\n const hasCredentials = credentials.hasCredentials;\n const isOrgCredentials = credentials.credentialsType === \"organization\";\n\n // Seeded once on mount; the dialog is only mounted while open (see\n // OrgCredentialsButton), so each open starts from the current configuration.\n // `enabled`/`scopes` on the configuration are the effective values\n // (the org override when present, else the developer default).\n const redactedSecret = buildRedactedSecret(credentials.redactedClientSecret);\n const [clientId, setClientId] = useState(credentials.client_id ?? \"\");\n const [clientSecret, setClientSecret] = useState(redactedSecret);\n const [enabled, setEnabled] = useState(integration.enabled);\n const [scopes, setScopes] = useState<string[]>(integration.scopes ?? []);\n // Organization credentials are entered first, then scopes (two-step wizard);\n // shared/custom providers only narrow scopes, so they get a single view.\n const [step, setStep] = useState<\"credentials\" | \"scopes\">(\"credentials\");\n const [clientIdError, setClientIdError] = useState<string | null>(null);\n const [clientSecretError, setClientSecretError] = useState<string | null>(\n null,\n );\n\n // Provider-declared `integration`-scope config fields are configured here, but\n // only for `organization` credentials: the API rejects per-org config for\n // shared/custom creds (those are set on the root integration instead). The\n // `installation`-scope pins are deferred from this UI for now (they're\n // collected in the connect modal instead). `secret` fields are excluded: they\n // are rejected server-side, and seeding a masked secret can't be round-tripped\n // safely under the config-replace write.\n const configFields = isOrgCredentials\n ? (integration.configFields ?? [])\n .filter((field) => field.scope === \"integration\" && !field.secret)\n .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n : [];\n const [configValues, setConfigValues] = useState<Record<string, string>>(\n () => {\n const seed: Record<string, string> = {};\n for (const field of integration.configFields ?? []) {\n if (field.scope !== \"integration\") continue;\n // Never seed a `secret` field from the response: the value may be\n // redacted, and re-submitting the mask would clobber the stored secret.\n if (field.secret) continue;\n const value = integration.config?.[field.key];\n if (typeof value === \"string\") {\n seed[field.key] = value;\n }\n }\n return seed;\n },\n );\n const [configErrors, setConfigErrors] = useState<\n Record<string, string | null>\n >({});\n\n const {\n mutate: upsertOverride,\n error,\n isPending,\n } = useUpsertDataIntegrationConfiguration({\n mutation: {\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: getListDataIntegrationConfigurationsQueryKey(),\n });\n // Saving a configuration can change which providers/scopes are available\n // in the user connection list, so refresh that list too.\n queryClient.invalidateQueries({\n queryKey: getMyDataIntegrationsQueryKey(),\n });\n onOpenChange(false);\n },\n },\n });\n\n const translate = useTranslation();\n\n // Selectable scope pool: organization credentials can request the provider's\n // full catalog; shared/custom can only (re)select within the developer's\n // configured defaults. The current effective selection is always included so\n // it stays toggleable, and the defaults are included so a previously removed\n // default can be re-added.\n const defaultScopes = integration.defaultScopes;\n const effectiveScopes = integration.scopes ?? [];\n const scopePool = isOrgCredentials\n ? [\n ...new Set([\n ...effectiveScopes,\n ...defaultScopes,\n ...integration.availableScopes,\n ]),\n ]\n : [...new Set([...effectiveScopes, ...defaultScopes])];\n // Developer-configured scopes the admin has unselected — named in the warning.\n const removedDefaultScopes = defaultScopes.filter(\n (scope) => !scopes.includes(scope),\n );\n\n const enabledLabel = translate({\n defaultMessage: \"Enable\",\n id: \"hkhtrS\",\n description: \"Label for the enable toggle\",\n });\n const enableTooltip = translate({\n defaultMessage:\n \"Allow this integration to be connected in your organization.\",\n id: \"7ItyG3\",\n description: \"Tooltip explaining the enable toggle\",\n });\n\n const clientIdPlaceholder = translate({\n defaultMessage: \"Enter your {providerName} Client ID\",\n id: \"pAUj4e\",\n description: \"Placeholder for the OAuth client ID input\",\n values: { providerName: integration.name },\n });\n const clientSecretPlaceholder = translate({\n defaultMessage: \"Enter your {providerName} Client Secret\",\n id: \"WoFO8+\",\n description: \"Placeholder for the OAuth client secret input\",\n values: { providerName: integration.name },\n });\n const scopeSearchPlaceholder = translate({\n defaultMessage: \"Search scopes\",\n id: \"fjuuw1\",\n description: \"Placeholder for the scope override search input\",\n });\n const scopeEmptyLabel = translate({\n defaultMessage: \"No scopes found\",\n id: \"OSyQvz\",\n description: \"Empty state for the scope override search\",\n });\n const configRequiredMessage = 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 configPatternMessage = 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 const secretRequiredMessage = translate({\n defaultMessage: \"Enter a new Client Secret to change the Client ID.\",\n id: \"O+5rxK\",\n description:\n \"Validation error when changing client id without a new secret\",\n });\n\n // Validate the integration-scope config fields against their descriptors.\n const validateConfigFields = (): boolean => {\n const nextErrors: Record<string, string | null> = {};\n let valid = true;\n for (const field of configFields) {\n const value = (configValues[field.key] ?? \"\").trim();\n if (field.required && !value) {\n nextErrors[field.key] = configRequiredMessage;\n valid = false;\n continue;\n }\n if (value && field.pattern) {\n let matches = true;\n try {\n matches = new RegExp(field.pattern).test(value);\n } catch {\n // Ignore invalid descriptor patterns client-side; the API validates.\n matches = true;\n }\n if (!matches) {\n nextErrors[field.key] = configPatternMessage;\n valid = false;\n continue;\n }\n }\n nextErrors[field.key] = null;\n }\n setConfigErrors(nextErrors);\n return valid;\n };\n\n // Secret descriptor keys are never round-tripped: if the API ever returned a\n // secret as a redacted mask, copying it into the replacement payload would\n // overwrite the stored value. (Secret config fields are rejected server-side\n // today, so this is defensive.)\n const secretConfigKeys = new Set(\n (integration.configFields ?? [])\n .filter((field) => field.secret)\n .map((field) => field.key),\n );\n\n const buildConfigPayload = () => {\n // Preserve existing config keys this UI doesn't render (e.g. installation\n // pins, deferred for now) so saving org settings never drops them.\n const config: Record<string, string> = {};\n for (const [key, value] of Object.entries(integration.config ?? {})) {\n if (typeof value === \"string\" && !secretConfigKeys.has(key)) {\n config[key] = value;\n }\n }\n // Overlay the edited integration-scope fields; an emptied field clears it.\n for (const field of configFields) {\n const value = (configValues[field.key] ?? \"\").trim();\n if (value) {\n config[field.key] = value;\n } else {\n delete config[field.key];\n }\n }\n return config;\n };\n\n // Validate organization credentials before advancing to the scopes step. The\n // secret field is pre-filled with a redacted placeholder for an existing\n // secret; if untouched, keep the stored secret. Since client_id and\n // client_secret travel together, changing the id requires a new secret.\n const validateCredentials = (): boolean => {\n setClientIdError(null);\n setClientSecretError(null);\n const trimmedId = clientId.trim();\n const secretUnchanged = hasCredentials && isRedactedSecret(clientSecret);\n let valid = true;\n if (!trimmedId) {\n setClientIdError(configRequiredMessage);\n valid = false;\n }\n if (secretUnchanged) {\n // Existing secret kept: only re-entry is required when the id changes.\n if (trimmedId && trimmedId !== (credentials.client_id ?? \"\")) {\n setClientSecretError(secretRequiredMessage);\n valid = false;\n }\n } else if (!clientSecret.trim()) {\n setClientSecretError(configRequiredMessage);\n valid = false;\n }\n return valid;\n };\n\n // API-key integrations have no OAuth credentials or scopes to configure;\n // the only override is the enabled toggle.\n const isApiKeyOnly = !(integration.authMethods ?? [\"oauth\"]).includes(\n \"oauth\",\n );\n\n const handleSubmit = () => {\n // Org-cred config fields were validated on the way to the scopes step; the\n // other surfaces submit directly from this view, so validate here.\n if (!isOrgCredentials && !validateConfigFields()) {\n return;\n }\n const configPayload =\n configFields.length > 0 ? { config: buildConfigPayload() } : undefined;\n\n if (isApiKeyOnly) {\n upsertOverride({\n slug: integration.slug,\n data: { enabled, ...configPayload },\n });\n return;\n }\n if (!isOrgCredentials) {\n // shared/custom: enable + (possibly narrowed) scopes only.\n upsertOverride({\n slug: integration.slug,\n data: { enabled, scopes, ...configPayload },\n });\n return;\n }\n // Credentials were validated on the way to the scopes step.\n const secretUnchanged = hasCredentials && isRedactedSecret(clientSecret);\n if (secretUnchanged) {\n upsertOverride({\n slug: integration.slug,\n data: { enabled, scopes, ...configPayload },\n });\n return;\n }\n upsertOverride({\n slug: integration.slug,\n data: {\n enabled,\n client_id: clientId.trim(),\n client_secret: clientSecret.trim(),\n scopes,\n ...configPayload,\n },\n });\n };\n\n const showCredentialsStep =\n !isApiKeyOnly && isOrgCredentials && step === \"credentials\";\n const showScopesStep =\n !isApiKeyOnly && (!isOrgCredentials || step === \"scopes\");\n\n // Disable Save when nothing differs from the seeded override state. Same\n // length + one-way subset means equal scope sets. Credential fields only\n // exist for organization credentials; a \"changed\" secret is a freshly typed\n // value (not the redacted placeholder), so focusing the field doesn't count.\n const initialScopes = integration.scopes ?? [];\n const scopesChanged =\n scopes.length !== initialScopes.length ||\n scopes.some((scope) => !initialScopes.includes(scope));\n const enabledChanged = enabled !== integration.enabled;\n const credentialsChanged =\n isOrgCredentials &&\n (clientId.trim() !== (credentials.client_id ?? \"\") ||\n (clientSecret.trim() !== \"\" && !isRedactedSecret(clientSecret)));\n const configChanged = configFields.some((field) => {\n const current = (configValues[field.key] ?? \"\").trim();\n // Trim both sides so an existing value with incidental surrounding\n // whitespace doesn't read as a pending change on open.\n const original =\n typeof integration.config?.[field.key] === \"string\"\n ? (integration.config[field.key] as string).trim()\n : \"\";\n return current !== original;\n });\n const hasPendingChanges =\n enabledChanged || scopesChanged || credentialsChanged || configChanged;\n\n // Gate the primary button on required fields being populated (matches the\n // ApiKeyDialog / change-email patterns). A redacted secret placeholder counts\n // as populated, so editing an existing config isn't blocked.\n const requiredConfigMissing = configFields.some(\n (field) => field.required && !(configValues[field.key] ?? \"\").trim(),\n );\n const credentialsMissing =\n isOrgCredentials && (!clientId.trim() || !clientSecret.trim());\n const nextDisabled = credentialsMissing || requiredConfigMissing;\n\n const enableToggle = (\n <Flex align=\"center\" gap=\"2\">\n <Switch\n checked={enabled}\n onCheckedChange={setEnabled}\n aria-label={enabledLabel}\n />\n <Text size=\"2\" weight=\"bold\">\n <Translation\n defaultMessage=\"Enable\"\n id=\"hkhtrS\"\n description=\"Label for the enable toggle\"\n />\n </Text>\n <Tooltip content={enableTooltip}>\n <InfoCircledIcon aria-hidden style={{ color: \"var(--gray-9)\" }} />\n </Tooltip>\n </Flex>\n );\n\n const configFieldsSection =\n configFields.length > 0\n ? configFields.map((field) => {\n const fieldId = `pipes-admin-config-${field.key}`;\n const errorId = `${fieldId}-error`;\n const descriptionId = `${fieldId}-description`;\n const error = configErrors[field.key];\n const Control = field.secret ? PasswordField : TextField;\n const describedBy =\n [field.description ? descriptionId : null, error ? errorId : null]\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={configValues[field.key] ?? \"\"}\n placeholder={field.example}\n autoComplete=\"off\"\n required={field.required || undefined}\n aria-invalid={!!error || undefined}\n aria-describedby={describedBy}\n onChange={(event) => {\n setConfigValues((prev) => ({\n ...prev,\n [field.key]: event.target.value,\n }));\n if (error) {\n setConfigErrors((prev) => ({\n ...prev,\n [field.key]: null,\n }));\n }\n }}\n />\n {error ? (\n <Text color=\"red\" size=\"2\" id={errorId}>\n {error}\n </Text>\n ) : null}\n </Flex>\n );\n })\n : null;\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content>\n <Dialog.Title size=\"3\" weight=\"bold\">\n <Translation\n defaultMessage=\"Configure {integrationName} for your organization\"\n id=\"ep4eY4\"\n description=\"Title of the organization credentials dialog\"\n values={{ integrationName: integration.name }}\n />\n </Dialog.Title>\n {integration.description && (\n <Text size=\"2\" color=\"gray\" mb=\"4\" as=\"p\">\n {integration.description}\n </Text>\n )}\n\n {error && (\n <Callout.Root my=\"3\" color=\"red\" role=\"alert\">\n <Callout.Text>\n <Translation\n defaultMessage=\"We couldn't save these settings. Please check the values and try again.\"\n id=\"zr1ZFZ\"\n description=\"Error message when saving organization settings fails\"\n />\n </Callout.Text>\n </Callout.Root>\n )}\n\n <Flex direction=\"column\" gap=\"4\" mt=\"2\">\n {isApiKeyOnly && (\n <>\n {enableToggle}\n {configFieldsSection}\n </>\n )}\n\n {showCredentialsStep && (\n <>\n {enableToggle}\n\n <RedirectUriField value={credentials.redirectUri} />\n\n <Flex direction=\"column\" gap=\"1\">\n <Label>\n <Translation\n defaultMessage=\"{providerName} Client ID\"\n id=\"Ew2Xew\"\n description=\"Label for the OAuth client ID input\"\n values={{ providerName: integration.name }}\n />\n </Label>\n <TextField\n value={clientId}\n autoComplete=\"off\"\n placeholder={clientIdPlaceholder}\n aria-invalid={!!clientIdError || undefined}\n aria-describedby={\n clientIdError ? \"pipes-admin-client-id-error\" : undefined\n }\n onChange={(event) => {\n setClientId(event.target.value);\n setClientIdError(null);\n }}\n />\n {clientIdError ? (\n <Text color=\"red\" size=\"2\" id=\"pipes-admin-client-id-error\">\n {clientIdError}\n </Text>\n ) : null}\n </Flex>\n\n <Flex direction=\"column\" gap=\"1\">\n <Label>\n <Translation\n defaultMessage=\"{providerName} Client Secret\"\n id=\"hZK/jR\"\n description=\"Label for the OAuth client secret input\"\n values={{ providerName: integration.name }}\n />\n </Label>\n <PasswordField\n value={clientSecret}\n autoComplete=\"off\"\n placeholder={clientSecretPlaceholder}\n aria-invalid={!!clientSecretError || undefined}\n aria-describedby={\n clientSecretError\n ? \"pipes-admin-client-secret-error\"\n : undefined\n }\n onChange={(event) => {\n setClientSecret(event.target.value);\n setClientSecretError(null);\n }}\n onFocus={() => {\n if (isRedactedSecret(clientSecret)) {\n setClientSecret(\"\");\n }\n }}\n onBlur={() => {\n if (clientSecret === \"\") {\n setClientSecret(redactedSecret);\n }\n }}\n />\n {clientSecretError ? (\n <Text\n color=\"red\"\n size=\"2\"\n id=\"pipes-admin-client-secret-error\"\n >\n {clientSecretError}\n </Text>\n ) : null}\n </Flex>\n\n {configFieldsSection}\n </>\n )}\n\n {showScopesStep && (\n <>\n {!isOrgCredentials && enableToggle}\n\n {!isOrgCredentials && configFieldsSection}\n\n {scopePool.length > 0 && (\n <Flex direction=\"column\" gap=\"2\">\n <Flex direction=\"column\" gap=\"1\">\n <Label>\n <Translation\n defaultMessage=\"Allowed scopes\"\n id=\"kNy90T\"\n description=\"Label for the scope override picker\"\n />\n </Label>\n <Text size=\"1\" color=\"gray\">\n <Translation\n defaultMessage=\"Selected scopes may be requested by your app. Users still authorize access during their own OAuth flow.\"\n id=\"E2nzZd\"\n description=\"Helper text for the scope override picker\"\n />\n </Text>\n </Flex>\n <SearchableSelectList\n options={scopePool}\n selected={scopes}\n getKey={(scope) => scope}\n getLabel={(scope) => scope}\n onChange={setScopes}\n searchPlaceholder={scopeSearchPlaceholder}\n emptyLabel={scopeEmptyLabel}\n />\n {removedDefaultScopes.length > 0 && (\n <Callout.Root color=\"amber\" role=\"status\">\n <Callout.Icon>\n <InfoCircledIcon />\n </Callout.Icon>\n <Callout.Text>\n <Translation\n defaultMessage=\"You removed developer-configured scopes: {scopes}. This may break this integration.\"\n id=\"1nCuju\"\n description=\"Warning naming the developer-configured scopes the admin removed\"\n values={{ scopes: removedDefaultScopes.join(\", \") }}\n />\n </Callout.Text>\n </Callout.Root>\n )}\n </Flex>\n )}\n </>\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 {showCredentialsStep ? (\n <Button\n type=\"button\"\n disabled={nextDisabled}\n onClick={() => {\n // Run both so each surfaces its own errors before advancing.\n const credentialsValid = validateCredentials();\n const configValid = validateConfigFields();\n if (credentialsValid && configValid) {\n setStep(\"scopes\");\n }\n }}\n >\n <Translation\n defaultMessage=\"Next\"\n id=\"VlKGPx\"\n description=\"Button to advance to the scopes step\"\n />\n </Button>\n ) : (\n <>\n {isOrgCredentials && !isApiKeyOnly && (\n <Button\n variant=\"secondary\"\n type=\"button\"\n onClick={() => setStep(\"credentials\")}\n >\n <Translation\n defaultMessage=\"Back\"\n id=\"bnFIEs\"\n description=\"Button to return to the credentials step\"\n />\n </Button>\n )}\n <Button\n type=\"button\"\n disabled={\n isPending || !hasPendingChanges || requiredConfigMissing\n }\n loading={isPending}\n onClick={handleSubmit}\n >\n <Translation\n defaultMessage=\"Save\"\n id=\"MVKPfz\"\n description=\"Button to save organization settings\"\n />\n </Button>\n </>\n )}\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\nfunction OrgCredentialsButton({\n integration,\n}: {\n integration: DataIntegrationConfiguration;\n}) {\n const [open, setOpen] = useState(false);\n\n return (\n <>\n {open && (\n <OrgCredentialsDialog\n integration={integration}\n open={open}\n onOpenChange={setOpen}\n />\n )}\n <Button variant=\"secondary\" onClick={() => setOpen(true)}>\n <Translation\n defaultMessage=\"Configure\"\n id=\"ADidi3\"\n description=\"Button to configure organization credentials\"\n />\n </Button>\n </>\n );\n}\n\n/**\n * Integrations the current viewer can manage at the organization level. Backed\n * by React Query, so calling it from multiple components doesn't trigger extra\n * fetches. Surfaces errors so the caller can render an error state rather than\n * a misleadingly empty list: a denied permission (`usePermissions` throws\n * `IncorrectPermissionsError`) and a failed `/configurations` fetch both flow\n * through `error`.\n */\nfunction useManageableIntegrations(): {\n data: DataIntegrationConfiguration[];\n isLoading: boolean;\n isError: boolean;\n error: unknown;\n} {\n const permission = usePermissions(\"widgets:pipes:manage\");\n const configurations = useListDataIntegrationConfigurations({\n query: { enabled: permission.isSuccess },\n });\n\n if (permission.isError) {\n return {\n data: [],\n isLoading: false,\n isError: true,\n error: permission.error,\n };\n }\n if (configurations.isError) {\n return {\n data: [],\n isLoading: false,\n isError: true,\n error: configurations.error,\n };\n }\n\n if (!permission.isSuccess || !configurations.isSuccess) {\n return {\n data: [],\n isLoading: permission.isLoading || configurations.isLoading,\n isError: false,\n error: null,\n };\n }\n\n // All manageable providers (not just organization-credential ones): the\n // tabbed \"Organization settings\" list covers every available provider.\n return {\n data: configurations.data.data,\n isLoading: false,\n isError: false,\n error: null,\n };\n}\n\n/**\n * Returns whether an integration is currently available to members of the\n * organization. All credential types require the effective `enabled` state to\n * be on; organization credentials additionally require a stored credential\n * pair.\n */\nfunction isIntegrationAvailable(\n integration: DataIntegrationConfiguration,\n): boolean {\n // API-key integrations have no org-level OAuth credentials; availability is\n // governed solely by the enabled toggle.\n if (!(integration.authMethods ?? [\"oauth\"]).includes(\"oauth\")) {\n return integration.enabled;\n }\n const credentials = integration.credentials;\n // `enabled` is the effective state (org override when present, else the\n // developer default). Organization credentials additionally require a stored\n // credential pair before the provider can be connected.\n if (credentials.credentialsType === \"organization\") {\n return credentials.hasCredentials && integration.enabled;\n }\n return integration.enabled;\n}\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"pipes-admin\",\n widgetState: state,\n });\n}\n\ninterface PipesAdminProps extends WidgetRootDomProps {\n integrations: DataIntegrationConfiguration[];\n}\n\n/**\n * IT-admin organization configuration list: every manageable provider with its\n * availability status and a Configure action (credentials + scope overrides).\n * Presentational — the client wrapper fetches via `useManageableIntegrations`.\n */\nconst PipesAdmin: React.FC<PipesAdminProps> = ({\n integrations,\n ...domProps\n}) => {\n return (\n <CardList.Root {...getWidgetRootDomProps(\"resolved\", domProps)}>\n {integrations.map((integration) => {\n const available = isIntegrationAvailable(integration);\n\n return (\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 <ProviderIcon\n provider={\n isKnownProviderIconSlug(integration.integrationType)\n ? integration.integrationType\n : \"generic-oauth\"\n }\n />\n </IconPanel>\n <Text size=\"2\" weight=\"bold\">\n {integration.name}\n </Text>\n </Flex>\n <Flex align=\"center\" gap=\"4\">\n <Status state={available ? \"success\" : \"neutral\"}>\n {available ? (\n <Translation\n defaultMessage=\"Available\"\n id=\"SytbAY\"\n description=\"Status when an org connection is available to members\"\n />\n ) : (\n <Translation\n defaultMessage=\"Disabled\"\n id=\"O4SGtP\"\n description=\"Status when an org connection is disabled\"\n />\n )}\n </Status>\n <OrgCredentialsButton integration={integration} />\n </Flex>\n </Flex>\n </CardList.Item>\n );\n })}\n </CardList.Root>\n );\n};\n\ninterface PipesAdminLoadingProps extends WidgetRootDomProps {\n count: number;\n}\n\nconst PipesAdminLoading: React.FC<PipesAdminLoadingProps> = ({\n count,\n ...domProps\n}) => {\n return (\n <CardList.Root {...getWidgetRootDomProps(\"loading\", domProps)}>\n {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\" />\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=\"Configure\"\n id=\"ADidi3\"\n description=\"Button to configure organization credentials\"\n />\n </Button>\n </Skeleton>\n </Flex>\n </CardList.Item>\n ))}\n </CardList.Root>\n );\n};\n\ninterface PipesAdminErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst PipesAdminError: React.FC<PipesAdminErrorProps> = ({\n error,\n ...domProps\n}) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <GenericError error={error} />\n </Card>\n );\n};\n\nexport type { PipesAdminProps, PipesAdminLoadingProps, PipesAdminErrorProps };\nexport {\n PipesAdmin,\n PipesAdminLoading,\n PipesAdminError,\n useManageableIntegrations,\n};\n"],"mappings":"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","names":["error"]}
1
+ {"version":3,"sources":["../../../src/lib/pipes-admin.tsx"],"sourcesContent":["\"use client\";\nimport { Callout, Card, Flex, Switch, Text, Tooltip } from \"@radix-ui/themes\";\nimport { useState } from \"react\";\nimport { InfoCircledIcon } from \"@radix-ui/react-icons\";\nimport * as CardList from \"./card-list.js\";\nimport { CopyText } from \"./copy-text.js\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport { isKnownProviderIconSlug } from \"./provider-icon-slugs.js\";\nimport {\n Button,\n Dialog,\n Label,\n PasswordField,\n Skeleton,\n TextField,\n} from \"./elements.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { SearchableSelectList } from \"./searchable-select-list.js\";\nimport { Status } from \"./status.js\";\nimport {\n DataIntegrationConfiguration,\n getListDataIntegrationConfigurationsQueryKey,\n getMyDataIntegrationsQueryKey,\n useListDataIntegrationConfigurations,\n useUpsertDataIntegrationConfiguration,\n} from \"../api/endpoint.js\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { GenericError } from \"./generic-error.js\";\nimport { usePermissions } from \"./use-permissions.js\";\nimport { getDomProps, WidgetRootDomProps, WidgetRootState } from \"./utils.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\nimport { buildRedactedSecret, isRedactedSecret } from \"./redacted-secret.js\";\n\nfunction RedirectUriField({ value }: { value: string }) {\n const translate = useTranslation();\n\n const copyLabel = translate({\n defaultMessage: \"Copy redirect URI\",\n id: \"xqfxBC\",\n description: \"Accessible label for the copy redirect URI button\",\n });\n\n return (\n <Flex direction=\"column\" gap=\"1\">\n <Label>\n <Translation\n defaultMessage=\"Redirect URI\"\n id=\"lgEaUA\"\n description=\"Label for the read-only OAuth redirect URI field\"\n />\n </Label>\n <CopyText value={value} label={copyLabel} />\n </Flex>\n );\n}\n\nfunction OrgCredentialsDialog({\n integration,\n open,\n onOpenChange,\n}: {\n integration: DataIntegrationConfiguration;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}) {\n const queryClient = useQueryClient();\n const credentials = integration.credentials;\n const hasCredentials = credentials.hasCredentials;\n const isOrgCredentials = credentials.credentialsType === \"organization\";\n\n // Seeded once on mount; the dialog is only mounted while open (see\n // OrgCredentialsButton), so each open starts from the current configuration.\n // `enabled`/`scopes` on the configuration are the effective values\n // (the org override when present, else the developer default).\n const redactedSecret = buildRedactedSecret(credentials.redactedClientSecret);\n const [clientId, setClientId] = useState(credentials.client_id ?? \"\");\n const [clientSecret, setClientSecret] = useState(redactedSecret);\n const [enabled, setEnabled] = useState(integration.enabled);\n const [scopes, setScopes] = useState<string[]>(integration.scopes ?? []);\n // Organization credentials are entered first, then scopes (two-step wizard);\n // shared/custom providers only narrow scopes, so they get a single view.\n const [step, setStep] = useState<\"credentials\" | \"scopes\">(\"credentials\");\n const [clientIdError, setClientIdError] = useState<string | null>(null);\n const [clientSecretError, setClientSecretError] = useState<string | null>(\n null,\n );\n\n // Provider-declared `integration`-scope config fields are configured here, but\n // only for `organization` credentials: the API rejects per-org config for\n // shared/custom creds (those are set on the root integration instead). The\n // `installation`-scope pins are deferred from this UI for now (they're\n // collected in the connect modal instead). `secret` fields are excluded: they\n // are rejected server-side, and seeding a masked secret can't be round-tripped\n // safely under the config-replace write.\n const configFields = isOrgCredentials\n ? (integration.configFields ?? [])\n .filter((field) => field.scope === \"integration\" && !field.secret)\n .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n : [];\n const [configValues, setConfigValues] = useState<Record<string, string>>(\n () => {\n const seed: Record<string, string> = {};\n for (const field of integration.configFields ?? []) {\n if (field.scope !== \"integration\") continue;\n // Never seed a `secret` field from the response: the value may be\n // redacted, and re-submitting the mask would clobber the stored secret.\n if (field.secret) continue;\n const value = integration.config?.[field.key];\n if (typeof value === \"string\") {\n seed[field.key] = value;\n }\n }\n return seed;\n },\n );\n const [configErrors, setConfigErrors] = useState<\n Record<string, string | null>\n >({});\n\n const {\n mutate: upsertOverride,\n error,\n isPending,\n } = useUpsertDataIntegrationConfiguration({\n mutation: {\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: getListDataIntegrationConfigurationsQueryKey(),\n });\n // Saving a configuration can change which providers/scopes are available\n // in the user connection list, so refresh that list too.\n queryClient.invalidateQueries({\n queryKey: getMyDataIntegrationsQueryKey(),\n });\n onOpenChange(false);\n },\n },\n });\n\n const translate = useTranslation();\n\n // Selectable scope pool: organization credentials can request the provider's\n // full catalog; shared/custom can only (re)select within the developer's\n // configured defaults. The current effective selection is always included so\n // it stays toggleable, and the defaults are included so a previously removed\n // default can be re-added.\n const defaultScopes = integration.defaultScopes;\n const effectiveScopes = integration.scopes ?? [];\n const scopePool = isOrgCredentials\n ? [\n ...new Set([\n ...effectiveScopes,\n ...defaultScopes,\n ...integration.availableScopes,\n ]),\n ]\n : [...new Set([...effectiveScopes, ...defaultScopes])];\n // Developer-configured scopes the admin has unselected — named in the warning.\n const removedDefaultScopes = defaultScopes.filter(\n (scope) => !scopes.includes(scope),\n );\n\n const enabledLabel = translate({\n defaultMessage: \"Enable\",\n id: \"hkhtrS\",\n description: \"Label for the enable toggle\",\n });\n const enableTooltip = translate({\n defaultMessage:\n \"Allow this integration to be connected in your organization.\",\n id: \"7ItyG3\",\n description: \"Tooltip explaining the enable toggle\",\n });\n\n const clientIdPlaceholder = translate({\n defaultMessage: \"Enter your {providerName} Client ID\",\n id: \"pAUj4e\",\n description: \"Placeholder for the OAuth client ID input\",\n values: { providerName: integration.name },\n });\n const clientSecretPlaceholder = translate({\n defaultMessage: \"Enter your {providerName} Client Secret\",\n id: \"WoFO8+\",\n description: \"Placeholder for the OAuth client secret input\",\n values: { providerName: integration.name },\n });\n const scopeSearchPlaceholder = translate({\n defaultMessage: \"Search scopes\",\n id: \"fjuuw1\",\n description: \"Placeholder for the scope override search input\",\n });\n const scopeEmptyLabel = translate({\n defaultMessage: \"No scopes found\",\n id: \"OSyQvz\",\n description: \"Empty state for the scope override search\",\n });\n const configRequiredMessage = 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 configPatternMessage = 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 const secretRequiredMessage = translate({\n defaultMessage: \"Enter a new Client Secret to change the Client ID.\",\n id: \"O+5rxK\",\n description:\n \"Validation error when changing client id without a new secret\",\n });\n\n // Validate the integration-scope config fields against their descriptors.\n const validateConfigFields = (): boolean => {\n const nextErrors: Record<string, string | null> = {};\n let valid = true;\n for (const field of configFields) {\n const value = (configValues[field.key] ?? \"\").trim();\n if (field.required && !value) {\n nextErrors[field.key] = configRequiredMessage;\n valid = false;\n continue;\n }\n if (value && field.pattern) {\n let matches = true;\n try {\n matches = new RegExp(field.pattern).test(value);\n } catch {\n // Ignore invalid descriptor patterns client-side; the API validates.\n matches = true;\n }\n if (!matches) {\n nextErrors[field.key] = configPatternMessage;\n valid = false;\n continue;\n }\n }\n nextErrors[field.key] = null;\n }\n setConfigErrors(nextErrors);\n return valid;\n };\n\n // Secret descriptor keys are never round-tripped: if the API ever returned a\n // secret as a redacted mask, copying it into the replacement payload would\n // overwrite the stored value. (Secret config fields are rejected server-side\n // today, so this is defensive.)\n const secretConfigKeys = new Set(\n (integration.configFields ?? [])\n .filter((field) => field.secret)\n .map((field) => field.key),\n );\n\n const buildConfigPayload = () => {\n // Preserve existing config keys this UI doesn't render (e.g. installation\n // pins, deferred for now) so saving org settings never drops them.\n const config: Record<string, string> = {};\n for (const [key, value] of Object.entries(integration.config ?? {})) {\n if (typeof value === \"string\" && !secretConfigKeys.has(key)) {\n config[key] = value;\n }\n }\n // Overlay the edited integration-scope fields; an emptied field clears it.\n for (const field of configFields) {\n const value = (configValues[field.key] ?? \"\").trim();\n if (value) {\n config[field.key] = value;\n } else {\n delete config[field.key];\n }\n }\n return config;\n };\n\n // Validate organization credentials before advancing to the scopes step. The\n // secret field is pre-filled with a redacted placeholder for an existing\n // secret; if untouched, keep the stored secret. Since client_id and\n // client_secret travel together, changing the id requires a new secret.\n const validateCredentials = (): boolean => {\n setClientIdError(null);\n setClientSecretError(null);\n const trimmedId = clientId.trim();\n const secretUnchanged = hasCredentials && isRedactedSecret(clientSecret);\n let valid = true;\n if (!trimmedId) {\n setClientIdError(configRequiredMessage);\n valid = false;\n }\n if (secretUnchanged) {\n // Existing secret kept: only re-entry is required when the id changes.\n if (trimmedId && trimmedId !== (credentials.client_id ?? \"\")) {\n setClientSecretError(secretRequiredMessage);\n valid = false;\n }\n } else if (!clientSecret.trim()) {\n setClientSecretError(configRequiredMessage);\n valid = false;\n }\n return valid;\n };\n\n // API-key integrations have no OAuth credentials or scopes to configure;\n // the only override is the enabled toggle.\n const isApiKeyOnly = !(integration.authMethods ?? [\"oauth\"]).includes(\n \"oauth\",\n );\n\n const handleSubmit = () => {\n // Org-cred config fields were validated on the way to the scopes step; the\n // other surfaces submit directly from this view, so validate here.\n if (!isOrgCredentials && !validateConfigFields()) {\n return;\n }\n const configPayload =\n configFields.length > 0 ? { config: buildConfigPayload() } : undefined;\n\n if (isApiKeyOnly) {\n upsertOverride({\n slug: integration.slug,\n data: { enabled, ...configPayload },\n });\n return;\n }\n if (!isOrgCredentials) {\n // shared/custom: enable + (possibly narrowed) scopes only.\n upsertOverride({\n slug: integration.slug,\n data: { enabled, scopes, ...configPayload },\n });\n return;\n }\n // Credentials were validated on the way to the scopes step.\n const secretUnchanged = hasCredentials && isRedactedSecret(clientSecret);\n if (secretUnchanged) {\n upsertOverride({\n slug: integration.slug,\n data: { enabled, scopes, ...configPayload },\n });\n return;\n }\n upsertOverride({\n slug: integration.slug,\n data: {\n enabled,\n client_id: clientId.trim(),\n client_secret: clientSecret.trim(),\n scopes,\n ...configPayload,\n },\n });\n };\n\n const showCredentialsStep =\n !isApiKeyOnly && isOrgCredentials && step === \"credentials\";\n const showScopesStep =\n !isApiKeyOnly && (!isOrgCredentials || step === \"scopes\");\n\n // Disable Save when nothing differs from the seeded override state. Same\n // length + one-way subset means equal scope sets. Credential fields only\n // exist for organization credentials; a \"changed\" secret is a freshly typed\n // value (not the redacted placeholder), so focusing the field doesn't count.\n const initialScopes = integration.scopes ?? [];\n const scopesChanged =\n scopes.length !== initialScopes.length ||\n scopes.some((scope) => !initialScopes.includes(scope));\n const enabledChanged = enabled !== integration.enabled;\n const credentialsChanged =\n isOrgCredentials &&\n (clientId.trim() !== (credentials.client_id ?? \"\") ||\n (clientSecret.trim() !== \"\" && !isRedactedSecret(clientSecret)));\n const configChanged = configFields.some((field) => {\n const current = (configValues[field.key] ?? \"\").trim();\n // Trim both sides so an existing value with incidental surrounding\n // whitespace doesn't read as a pending change on open.\n const original =\n typeof integration.config?.[field.key] === \"string\"\n ? (integration.config[field.key] as string).trim()\n : \"\";\n return current !== original;\n });\n const hasPendingChanges =\n enabledChanged || scopesChanged || credentialsChanged || configChanged;\n\n // Gate the primary button on required fields being populated (matches the\n // ApiKeyDialog / change-email patterns). A redacted secret placeholder counts\n // as populated, so editing an existing config isn't blocked.\n const requiredConfigMissing = configFields.some(\n (field) => field.required && !(configValues[field.key] ?? \"\").trim(),\n );\n const credentialsMissing =\n isOrgCredentials && (!clientId.trim() || !clientSecret.trim());\n const nextDisabled = credentialsMissing || requiredConfigMissing;\n\n const enableToggle = (\n <Flex align=\"center\" gap=\"2\">\n <Switch\n checked={enabled}\n onCheckedChange={setEnabled}\n aria-label={enabledLabel}\n />\n <Text size=\"2\" weight=\"bold\">\n <Translation\n defaultMessage=\"Enable\"\n id=\"hkhtrS\"\n description=\"Label for the enable toggle\"\n />\n </Text>\n <Tooltip content={enableTooltip}>\n <InfoCircledIcon aria-hidden style={{ color: \"var(--gray-9)\" }} />\n </Tooltip>\n </Flex>\n );\n\n const configFieldsSection =\n configFields.length > 0\n ? configFields.map((field) => {\n const fieldId = `pipes-admin-config-${field.key}`;\n const errorId = `${fieldId}-error`;\n const descriptionId = `${fieldId}-description`;\n const error = configErrors[field.key];\n const Control = field.secret ? PasswordField : TextField;\n const describedBy =\n [field.description ? descriptionId : null, error ? errorId : null]\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={configValues[field.key] ?? \"\"}\n placeholder={field.example}\n autoComplete=\"off\"\n required={field.required || undefined}\n aria-invalid={!!error || undefined}\n aria-describedby={describedBy}\n onChange={(event) => {\n setConfigValues((prev) => ({\n ...prev,\n [field.key]: event.target.value,\n }));\n if (error) {\n setConfigErrors((prev) => ({\n ...prev,\n [field.key]: null,\n }));\n }\n }}\n />\n {error ? (\n <Text color=\"red\" size=\"2\" id={errorId}>\n {error}\n </Text>\n ) : null}\n </Flex>\n );\n })\n : null;\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content>\n <Dialog.Title size=\"3\" weight=\"bold\">\n <Translation\n defaultMessage=\"Configure {integrationName} for your organization\"\n id=\"ep4eY4\"\n description=\"Title of the organization credentials dialog\"\n values={{ integrationName: integration.name }}\n />\n </Dialog.Title>\n {integration.description && (\n <Text size=\"2\" color=\"gray\" mb=\"4\" as=\"p\">\n {integration.description}\n </Text>\n )}\n\n {error && (\n <Callout.Root my=\"3\" color=\"red\" role=\"alert\">\n <Callout.Text>\n <Translation\n defaultMessage=\"We couldn't save these settings. Please check the values and try again.\"\n id=\"zr1ZFZ\"\n description=\"Error message when saving organization settings fails\"\n />\n </Callout.Text>\n </Callout.Root>\n )}\n\n <Flex direction=\"column\" gap=\"4\" mt=\"2\">\n {isApiKeyOnly && (\n <>\n {enableToggle}\n {configFieldsSection}\n </>\n )}\n\n {showCredentialsStep && (\n <>\n {enableToggle}\n\n <RedirectUriField value={credentials.redirectUri} />\n\n <Flex direction=\"column\" gap=\"1\">\n <Label>\n <Translation\n defaultMessage=\"{providerName} Client ID\"\n id=\"Ew2Xew\"\n description=\"Label for the OAuth client ID input\"\n values={{ providerName: integration.name }}\n />\n </Label>\n <TextField\n value={clientId}\n autoComplete=\"off\"\n placeholder={clientIdPlaceholder}\n aria-invalid={!!clientIdError || undefined}\n aria-describedby={\n clientIdError ? \"pipes-admin-client-id-error\" : undefined\n }\n onChange={(event) => {\n setClientId(event.target.value);\n setClientIdError(null);\n }}\n />\n {clientIdError ? (\n <Text color=\"red\" size=\"2\" id=\"pipes-admin-client-id-error\">\n {clientIdError}\n </Text>\n ) : null}\n </Flex>\n\n <Flex direction=\"column\" gap=\"1\">\n <Label>\n <Translation\n defaultMessage=\"{providerName} Client Secret\"\n id=\"hZK/jR\"\n description=\"Label for the OAuth client secret input\"\n values={{ providerName: integration.name }}\n />\n </Label>\n <PasswordField\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-invalid={!!clientSecretError || undefined}\n aria-describedby={\n clientSecretError\n ? \"pipes-admin-client-secret-error\"\n : undefined\n }\n onChange={(event) => {\n setClientSecret(event.target.value);\n setClientSecretError(null);\n }}\n onFocus={() => {\n if (isRedactedSecret(clientSecret)) {\n setClientSecret(\"\");\n }\n }}\n onBlur={() => {\n if (clientSecret === \"\") {\n setClientSecret(redactedSecret);\n }\n }}\n />\n {clientSecretError ? (\n <Text\n color=\"red\"\n size=\"2\"\n id=\"pipes-admin-client-secret-error\"\n >\n {clientSecretError}\n </Text>\n ) : null}\n </Flex>\n\n {configFieldsSection}\n </>\n )}\n\n {showScopesStep && (\n <>\n {!isOrgCredentials && enableToggle}\n\n {!isOrgCredentials && configFieldsSection}\n\n {scopePool.length > 0 && (\n <Flex direction=\"column\" gap=\"2\">\n <Flex direction=\"column\" gap=\"1\">\n <Label>\n <Translation\n defaultMessage=\"Allowed scopes\"\n id=\"kNy90T\"\n description=\"Label for the scope override picker\"\n />\n </Label>\n <Text size=\"1\" color=\"gray\">\n <Translation\n defaultMessage=\"Selected scopes may be requested by your app. Users still authorize access during their own OAuth flow.\"\n id=\"E2nzZd\"\n description=\"Helper text for the scope override picker\"\n />\n </Text>\n </Flex>\n <SearchableSelectList\n options={scopePool}\n selected={scopes}\n getKey={(scope) => scope}\n getLabel={(scope) => scope}\n onChange={setScopes}\n searchPlaceholder={scopeSearchPlaceholder}\n emptyLabel={scopeEmptyLabel}\n />\n {removedDefaultScopes.length > 0 && (\n <Callout.Root color=\"amber\" role=\"status\">\n <Callout.Icon>\n <InfoCircledIcon />\n </Callout.Icon>\n <Callout.Text>\n <Translation\n defaultMessage=\"You removed developer-configured scopes: {scopes}. This may break this integration.\"\n id=\"1nCuju\"\n description=\"Warning naming the developer-configured scopes the admin removed\"\n values={{ scopes: removedDefaultScopes.join(\", \") }}\n />\n </Callout.Text>\n </Callout.Root>\n )}\n </Flex>\n )}\n </>\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 {showCredentialsStep ? (\n <Button\n type=\"button\"\n disabled={nextDisabled}\n onClick={() => {\n // Run both so each surfaces its own errors before advancing.\n const credentialsValid = validateCredentials();\n const configValid = validateConfigFields();\n if (credentialsValid && configValid) {\n setStep(\"scopes\");\n }\n }}\n >\n <Translation\n defaultMessage=\"Next\"\n id=\"VlKGPx\"\n description=\"Button to advance to the scopes step\"\n />\n </Button>\n ) : (\n <>\n {isOrgCredentials && !isApiKeyOnly && (\n <Button\n variant=\"secondary\"\n type=\"button\"\n onClick={() => setStep(\"credentials\")}\n >\n <Translation\n defaultMessage=\"Back\"\n id=\"bnFIEs\"\n description=\"Button to return to the credentials step\"\n />\n </Button>\n )}\n <Button\n type=\"button\"\n disabled={\n isPending || !hasPendingChanges || requiredConfigMissing\n }\n loading={isPending}\n onClick={handleSubmit}\n >\n <Translation\n defaultMessage=\"Save\"\n id=\"MVKPfz\"\n description=\"Button to save organization settings\"\n />\n </Button>\n </>\n )}\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\nfunction OrgCredentialsButton({\n integration,\n}: {\n integration: DataIntegrationConfiguration;\n}) {\n const [open, setOpen] = useState(false);\n\n return (\n <>\n {open && (\n <OrgCredentialsDialog\n integration={integration}\n open={open}\n onOpenChange={setOpen}\n />\n )}\n <Button variant=\"secondary\" onClick={() => setOpen(true)}>\n <Translation\n defaultMessage=\"Configure\"\n id=\"ADidi3\"\n description=\"Button to configure organization credentials\"\n />\n </Button>\n </>\n );\n}\n\n/**\n * Integrations the current viewer can manage at the organization level. Backed\n * by React Query, so calling it from multiple components doesn't trigger extra\n * fetches. Surfaces errors so the caller can render an error state rather than\n * a misleadingly empty list: a denied permission (`usePermissions` throws\n * `IncorrectPermissionsError`) and a failed `/configurations` fetch both flow\n * through `error`.\n */\nfunction useManageableIntegrations(): {\n data: DataIntegrationConfiguration[];\n isLoading: boolean;\n isError: boolean;\n error: unknown;\n} {\n const permission = usePermissions(\"widgets:pipes:manage\");\n const configurations = useListDataIntegrationConfigurations({\n query: { enabled: permission.isSuccess },\n });\n\n if (permission.isError) {\n return {\n data: [],\n isLoading: false,\n isError: true,\n error: permission.error,\n };\n }\n if (configurations.isError) {\n return {\n data: [],\n isLoading: false,\n isError: true,\n error: configurations.error,\n };\n }\n\n if (!permission.isSuccess || !configurations.isSuccess) {\n return {\n data: [],\n isLoading: permission.isLoading || configurations.isLoading,\n isError: false,\n error: null,\n };\n }\n\n // All manageable providers (not just organization-credential ones): the\n // tabbed \"Organization settings\" list covers every available provider.\n return {\n data: configurations.data.data,\n isLoading: false,\n isError: false,\n error: null,\n };\n}\n\n/**\n * Returns whether an integration is currently available to members of the\n * organization. All credential types require the effective `enabled` state to\n * be on; organization credentials additionally require a stored credential\n * pair.\n */\nfunction isIntegrationAvailable(\n integration: DataIntegrationConfiguration,\n): boolean {\n // API-key integrations have no org-level OAuth credentials; availability is\n // governed solely by the enabled toggle.\n if (!(integration.authMethods ?? [\"oauth\"]).includes(\"oauth\")) {\n return integration.enabled;\n }\n const credentials = integration.credentials;\n // `enabled` is the effective state (org override when present, else the\n // developer default). Organization credentials additionally require a stored\n // credential pair before the provider can be connected.\n if (credentials.credentialsType === \"organization\") {\n return credentials.hasCredentials && integration.enabled;\n }\n return integration.enabled;\n}\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"pipes-admin\",\n widgetState: state,\n });\n}\n\ninterface PipesAdminProps extends WidgetRootDomProps {\n integrations: DataIntegrationConfiguration[];\n}\n\n/**\n * IT-admin organization configuration list: every manageable provider with its\n * availability status and a Configure action (credentials + scope overrides).\n * Presentational — the client wrapper fetches via `useManageableIntegrations`.\n */\nconst PipesAdmin: React.FC<PipesAdminProps> = ({\n integrations,\n ...domProps\n}) => {\n return (\n <CardList.Root {...getWidgetRootDomProps(\"resolved\", domProps)}>\n {integrations.map((integration) => {\n const available = isIntegrationAvailable(integration);\n\n return (\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 <ProviderIcon\n provider={\n isKnownProviderIconSlug(integration.integrationType)\n ? integration.integrationType\n : \"generic-oauth\"\n }\n />\n </IconPanel>\n <Text size=\"2\" weight=\"bold\">\n {integration.name}\n </Text>\n </Flex>\n <Flex align=\"center\" gap=\"4\">\n <Status state={available ? \"success\" : \"neutral\"}>\n {available ? (\n <Translation\n defaultMessage=\"Available\"\n id=\"SytbAY\"\n description=\"Status when an org connection is available to members\"\n />\n ) : (\n <Translation\n defaultMessage=\"Disabled\"\n id=\"O4SGtP\"\n description=\"Status when an org connection is disabled\"\n />\n )}\n </Status>\n <OrgCredentialsButton integration={integration} />\n </Flex>\n </Flex>\n </CardList.Item>\n );\n })}\n </CardList.Root>\n );\n};\n\ninterface PipesAdminLoadingProps extends WidgetRootDomProps {\n count: number;\n}\n\nconst PipesAdminLoading: React.FC<PipesAdminLoadingProps> = ({\n count,\n ...domProps\n}) => {\n return (\n <CardList.Root {...getWidgetRootDomProps(\"loading\", domProps)}>\n {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\" />\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=\"Configure\"\n id=\"ADidi3\"\n description=\"Button to configure organization credentials\"\n />\n </Button>\n </Skeleton>\n </Flex>\n </CardList.Item>\n ))}\n </CardList.Root>\n );\n};\n\ninterface PipesAdminErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst PipesAdminError: React.FC<PipesAdminErrorProps> = ({\n error,\n ...domProps\n}) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <GenericError error={error} />\n </Card>\n );\n};\n\nexport type { PipesAdminProps, PipesAdminLoadingProps, PipesAdminErrorProps };\nexport {\n PipesAdmin,\n PipesAdminLoading,\n PipesAdminError,\n useManageableIntegrations,\n};\n"],"mappings":"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","names":["error"]}