mirror of
https://github.com/onyx-dot-app/onyx.git
synced 2026-10-19 01:50:51 -05:00
feat(connectors): Opal logos for the catalog, and source metadata in the connectors library (#15993)
This commit is contained in:
1 parent
777b9bf1f7
commit
458affef19
63 files changed
+776
-725
No files matched your search
@@ -69,7 +69,7 @@ shows only when an index run fails or returns nothing.
|
||||
| File | Holds |
|
||||
|---|---|
|
||||
| `web/src/lib/connectors/connectors.tsx` | `connectorConfigs`, keyed by source: the form schema (fields, types, defaults) the add-connector page renders and posts as `connector_specific_config`. |
|
||||
| `web/src/lib/sources.ts` | `SOURCE_METADATA_MAP`: icon, display name, and docs link per source, read by `getSourceMetadata`/`isValidSource`-style helpers. |
|
||||
| `web/src/lib/connectors/constants.ts` | `SOURCE_METADATA_MAP`: icon, display name, and docs link per source. `getSourceMetadata`, `isValidSource` and the other getters live in `web/src/lib/connectors/utils.ts`; `SourceMetadata` and `SourceCategory` in `web/src/lib/connectors/types/source.ts`. |
|
||||
|
||||
`backend/onyx/connectors/README.md:96,113` names exactly these two files as the
|
||||
frontend changes a new connector requires.
|
||||
@@ -660,7 +660,7 @@ family keep the source's shape and stay usable by that source only.
|
||||
|
||||
| If your change... | Also check |
|
||||
|---|---|
|
||||
| adds a new connector | `DocumentSource` enum, `registry.py:CONNECTOR_CLASS_MAP`, the class itself, `web/src/lib/connectors/connectors.tsx` (`connectorConfigs`), `web/src/lib/sources.ts` (`SOURCE_METADATA_MAP`), a folder under `backend/tests/daily/connectors/`, and (if attachments exist) the `include_attachments` gating on both the main and slim pass |
|
||||
| adds a new connector | `DocumentSource` enum, `registry.py:CONNECTOR_CLASS_MAP`, the class itself, `web/src/lib/connectors/connectors.tsx` (`connectorConfigs`), `web/src/lib/connectors/constants.ts` (`SOURCE_METADATA_MAP`), a folder under `backend/tests/daily/connectors/`, and (if attachments exist) the `include_attachments` gating on both the main and slim pass |
|
||||
| changes the `Document`/`Section`/`SlimDocument` model | every connector that constructs one directly (no central factory does this for them); [[indexing-pipeline]]'s consumption of the new/changed field; the dedup logic keyed on `Document.id` and `content_hash` |
|
||||
| changes `interfaces.py` (adds/renames a base class or method) | `factory.py:_validate_connector_supports_input_type` and `identify_connector_class`; `connector_runner.py`'s `isinstance` branches; every connector implementing the affected interface |
|
||||
| changes checkpoint serialization (`ConnectorCheckpoint` or a subclass) | `validate_checkpoint_json` for that connector; any in-flight, persisted checkpoint from a prior run becomes unreadable, which [[indexing-pipeline]]'s resume logic must handle |
|
||||
|
||||
@@ -109,7 +109,7 @@ indexing them by following the shared convention:
|
||||
|
||||
#### Frontend Changes
|
||||
|
||||
- Add the new Connector definition to the `SOURCE_METADATA_MAP` [here](https://github.com/onyx-dot-app/onyx/blob/main/web/src/lib/sources.ts#L59).
|
||||
- Add the new Connector definition to the `SOURCE_METADATA_MAP` in [`web/src/lib/connectors/constants.ts`](https://github.com/onyx-dot-app/onyx/blob/main/web/src/lib/connectors/constants.ts).
|
||||
- Add the definition for the new Form to the `connectorConfigs` object [here](https://github.com/onyx-dot-app/onyx/blob/main/web/src/lib/connectors/connectors.ts#L79).
|
||||
|
||||
#### Docs Changes
|
||||
|
||||
@@ -29,9 +29,12 @@ function OverflowText({
|
||||
const [element, setElement] = useState<HTMLElement | null>(null);
|
||||
const overflowing = useOverflow(element);
|
||||
|
||||
// Suppressed rather than dropped: dropping the tooltip changes the tree's
|
||||
// shape, which remounts the text and loses the element the measure reads.
|
||||
return (
|
||||
<Tooltip
|
||||
tooltip={overflowing ? children : undefined}
|
||||
tooltip={children}
|
||||
suppressed={!overflowing}
|
||||
side="top"
|
||||
align="start"
|
||||
>
|
||||
|
||||
@@ -16,6 +16,7 @@ Inherits **all** props from [`Content`](../content/README.md) (same discriminate
|
||||
| --------------- | -------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `rightChildren` | `ReactNode` | `undefined` | Content rendered on the right side. Wrapper stretches to the full height of the row. |
|
||||
| `padding` | `0 \| 0.5 \| 1 \| 2` | `2` | Padding around the `Content` area, as a spacing step (`N / 4` rem). Narrowed to the paddings `Interactive.Container` uses. |
|
||||
| `gapping` | `Spacing` | `4` | Gap between the `Content` area and `rightChildren`, as a spacing step (`N / 4` rem). Ignored in the `responsive` branch. |
|
||||
| `fillRight` | `boolean` | `false` | When `true`, the `rightChildren` column grows to fill the row (capped at `--block-width-form-input-column-max`, 240px) instead of hugging its content. Use for full-width form inputs; leave off for compact controls like toggles/buttons. Ignored in the `responsive` branch. |
|
||||
|
||||
### `padding` reference
|
||||
@@ -35,7 +36,7 @@ scale from `Card`, where `lg` was 24px rather than 8px.
|
||||
[ Content (flex-1, padded) ] 1rem [ rightChildren (shrink-0, full height) ]
|
||||
```
|
||||
|
||||
- The outer wrapper is `flex flex-row items-stretch w-full gap-4`: 1rem between `Content` and `rightChildren`.
|
||||
- The outer wrapper is `flex flex-row items-stretch w-full`, with `gapping` between `Content` and `rightChildren` (1rem by default).
|
||||
- `Content` sits inside a `flex-1 min-w-0` div with padding from `padding`.
|
||||
- `rightChildren` is wrapped in `flex items-stretch shrink-0` so it stretches vertically.
|
||||
- With `fillRight`, the `rightChildren` wrapper instead becomes `flex-1 min-w-0` with a
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import "@opal/layouts/content-action/styles.css";
|
||||
import { Content, type ContentProps } from "@opal/layouts/content/components";
|
||||
import { spacingToRem } from "@opal/shared";
|
||||
import type { Spacing } from "@opal/types";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Types
|
||||
@@ -22,6 +23,14 @@ type ContentActionProps = ContentProps & {
|
||||
*/
|
||||
padding?: 0 | 0.5 | 1 | 1.5 | 2;
|
||||
|
||||
/**
|
||||
* The gap between the `Content` area and `rightChildren`, as a spacing
|
||||
* step (`N / 4` rem). Ignored in the `responsive` branch.
|
||||
*
|
||||
* @default 4
|
||||
*/
|
||||
gapping?: Spacing;
|
||||
|
||||
/**
|
||||
* When true, vertically centers the Content and rightChildren.
|
||||
* When false (default), Content is top-aligned and rightChildren
|
||||
@@ -99,6 +108,7 @@ function routesToContentMd(props: {
|
||||
function ContentAction({
|
||||
rightChildren,
|
||||
padding = 2,
|
||||
gapping = 4,
|
||||
center = false,
|
||||
responsive = false,
|
||||
fillRight = false,
|
||||
@@ -120,7 +130,11 @@ function ContentAction({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="opal-content-action" data-centered={center || undefined}>
|
||||
<div
|
||||
className="opal-content-action"
|
||||
data-centered={center || undefined}
|
||||
style={{ gap: spacingToRem(gapping) }}
|
||||
>
|
||||
<div className="opal-content-action-content" style={paddingStyle}>
|
||||
<Content {...contentProps} />
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@reference "#reference.css";
|
||||
|
||||
.opal-content-action {
|
||||
@apply flex flex-row w-full items-stretch gap-4;
|
||||
@apply flex flex-row w-full items-stretch;
|
||||
}
|
||||
|
||||
.opal-content-action[data-centered="true"] {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { IconProps } from "@opal/types";
|
||||
const SvgBox = ({ size, ...props }: IconProps) => (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 52 52"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M26.3478 35.0177C23.5795 35.0177 21.2065 32.645 21.2065 29.7446C21.2065 26.8445 23.4476 24.4716 26.3478 24.4716C29.1164 24.4716 31.489 26.8445 31.489 29.7446C31.489 32.645 29.2478 35.0177 26.3478 35.0177ZM11.3195 35.0177C8.55118 35.0177 6.17829 32.645 6.17829 29.7446C6.17829 26.8445 8.41934 24.4716 11.3195 24.4716C14.0879 24.4716 16.4608 26.8445 16.4608 29.7446C16.4608 32.645 14.2197 35.0177 11.3195 35.0177ZM45.5945 21.9669C46.2537 21.176 47.4402 21.0441 48.2312 21.7033C49.0219 22.2306 49.2856 23.4171 48.6264 24.208L43.8806 30.1401L48.6264 36.0724C49.2856 36.8634 49.0219 37.9181 48.2312 38.5773C47.4402 39.1046 46.2537 38.9728 45.5945 38.3136L41.5079 33.3042L37.4213 38.3136C36.7622 39.1046 35.5756 39.2361 34.7846 38.5773C33.994 38.0499 33.7303 36.8634 34.3891 36.0724L39.1348 30.1401L34.5209 24.0762C33.8621 23.2852 34.1254 22.2306 34.9164 21.5715C35.7075 21.0441 36.894 21.176 37.5532 21.8351L41.6398 26.9764L45.5945 21.9669ZM4.59636 13.53C5.51915 13.53 6.31009 14.321 6.31009 15.2438V22.7579C7.76019 21.7033 9.47396 21.0441 11.4514 21.0441C14.747 21.0441 17.5154 22.8898 18.9655 25.7899C20.4156 23.0216 23.1839 21.0441 26.4796 21.0441C31.2254 21.0441 34.9164 24.999 34.9164 29.8764C34.9164 34.754 31.0935 38.7091 26.4796 38.7091C23.1839 38.7091 20.4156 36.8634 18.9655 33.9634C17.5154 36.7316 14.747 38.7091 11.4514 38.7091C6.83741 38.7091 3.01443 34.8858 3.01443 30.0082V15.2438C2.88259 14.321 3.67358 13.53 4.59636 13.53Z"
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
fill="#0061D5"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
export default SvgBox;
|
||||
@@ -3,14 +3,18 @@ const SvgBraintrust = ({ size, ...props }: IconProps) => (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 32 32"
|
||||
viewBox="0 0 52 52"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M11.8623 0C13.576 0.000127038 14.9658 1.38669 14.9658 3.09668V6.19336C14.9658 7.90339 13.576 9.28991 11.8623 9.29004H10.3105V11.3545H11.8623C13.5758 11.3546 14.9656 12.7413 14.9658 14.4512V17.5488C14.9656 19.2587 13.5758 20.6454 11.8623 20.6455H10.3105V22.71H11.8623C13.576 22.7101 14.9658 24.0966 14.9658 25.8066V28.9033C14.9658 30.6133 13.576 31.9999 11.8623 32H8.75879C7.04503 32 5.65532 30.6134 5.65527 28.9033V26.3223H4.10352C2.38972 26.3223 1 24.9357 1 23.2256V20.1289C1.00007 18.4189 2.38976 17.0322 4.10352 17.0322H5.65527V14.9678H4.10352C2.38976 14.9678 1.00007 13.5811 1 11.8711V8.77441C1 7.06431 2.38972 5.67773 4.10352 5.67773H5.65527V3.09668C5.65532 1.38662 7.04503 0 8.75879 0H11.8623ZM23.2412 0C24.955 0 26.3447 1.38662 26.3447 3.09668V5.67773H27.8965C29.6103 5.67773 31 7.06431 31 8.77441V11.8711C30.9999 13.5811 29.6102 14.9678 27.8965 14.9678H26.3447V17.0322H27.8965C29.6102 17.0322 30.9999 18.4189 31 20.1289V23.2256C31 24.9357 29.6103 26.3223 27.8965 26.3223H26.3447V28.9033C26.3447 30.6134 24.955 32 23.2412 32H20.1377C18.424 31.9999 17.0342 30.6133 17.0342 28.9033V25.8066C17.0342 24.0966 18.424 22.7101 20.1377 22.71H21.6895V20.6455H20.1377C18.4241 20.6454 17.0344 19.2587 17.0342 17.5488V14.4512C17.0344 12.7413 18.4241 11.3546 20.1377 11.3545H21.6895V9.29004H20.1377C18.424 9.28992 17.0342 7.9034 17.0342 6.19336V3.09668C17.0342 1.38669 18.424 0.000115963 20.1377 0H23.2412Z"
|
||||
fill="#2C1FEB"
|
||||
d="M24.9655 7.66454C24.9655 5.06139 22.8787 2.94997 20.306 2.94995H15.6464C13.074 2.95033 10.9885 5.06161 10.9885 7.66454V10.9371H8.65957C6.08685 10.9371 4 13.0485 4 15.6517V20.3662C4.0004 22.969 6.08711 25.0792 8.65957 25.0792H10.9885V26.913H8.65957C6.08711 26.913 4.00041 29.0231 4 31.626V36.3405C4 38.9437 6.08685 41.0551 8.65957 41.0551H10.9885V44.3276C10.9885 46.9305 13.074 49.0419 15.6464 49.0422H20.306C22.8787 49.0422 24.9655 46.9308 24.9655 44.3276V39.6146C24.9655 37.0116 22.8787 34.9001 20.306 34.9001H17.977V33.0663H20.306C22.8785 33.0663 24.9655 30.9565 24.9655 28.3534V23.6387C24.9655 21.0357 22.8785 18.9259 20.306 18.9259H17.977V17.092H20.306C22.8787 17.092 24.9655 14.9806 24.9655 12.3775V7.66454Z"
|
||||
fill="#2C1FEA"
|
||||
/>
|
||||
<path
|
||||
d="M41.0116 7.66454C41.0116 5.06154 38.9261 2.95022 36.3535 2.94995H31.6941C29.1215 2.95008 27.0361 5.06145 27.0361 7.66454V12.3775C27.0361 14.9805 29.1215 17.0919 31.6941 17.092H34.023V18.9259H31.6941C29.1215 18.926 27.0362 21.0359 27.0361 23.6387V28.3534C27.0362 30.9563 29.1215 33.0661 31.6941 33.0663H34.023V34.9001H31.6941C29.1215 34.9002 27.0361 37.0116 27.0361 39.6146V44.3276C27.0361 46.9307 29.1215 49.042 31.6941 49.0422H36.3535C38.9261 49.0419 41.0116 46.9307 41.0116 44.3276V41.0551H43.3421C45.9146 41.0548 48 38.9434 48 36.3405V31.626C47.9997 29.0233 45.9142 26.9133 43.3421 26.913H41.0116V25.0792H43.3421C45.9142 25.0788 47.9997 22.9688 48 20.3662V15.6517C48 13.0487 45.9146 10.9375 43.3421 10.9371H41.0116V7.66454Z"
|
||||
fill="#2C1FEA"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -8,21 +8,14 @@ const SvgCloudflare = ({ size, ...props }: IconProps) => (
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<g clipPath="url(#clip0_2129_46279)">
|
||||
<path
|
||||
d="M35.8174 31.9908C35.9336 31.5457 36.0522 31.0378 35.9959 30.5502C35.9396 30.0627 35.7674 29.5956 35.4938 29.1881C35.2127 28.8513 34.8679 28.5733 34.4792 28.3698C34.0904 28.1663 33.6653 28.0414 33.2282 28.0023L14.4564 27.7867C14.1594 27.7867 14.0537 27.504 14.1594 27.321C14.2205 27.2154 14.3665 27.1098 14.5822 27.1098L33.3968 26.8986C34.5954 26.7656 35.7841 26.2341 36.7511 25.5141C37.7181 24.7941 38.4758 23.8298 38.9461 22.7202L39.9502 20.1391C40.0559 19.8223 40.0352 19.3998 39.9502 19.083C39.2572 16.4987 38.0151 14.6359 35.9712 12.9075C33.9274 11.1792 31.3748 10.1648 28.7013 10.0184C26.0278 9.87203 23.3795 10.6017 21.1589 12.0966C18.9383 13.5914 17.2668 15.7697 16.3984 18.3005C15.2709 17.4959 13.8957 17.1142 12.5145 17.2225C11.247 17.3637 10.0652 17.9315 9.16334 18.8327C8.26149 19.7338 7.69322 20.9147 7.55188 22.1812C7.48005 22.8295 7.5165 23.4852 7.65976 24.1216C5.60883 24.1782 3.66094 25.0322 2.23044 26.5018C0.799944 27.9714 0.00342678 29.9407 1.64306e-05 31.9908C-0.00064861 32.3906 0.0186006 32.788 0.107899 33.1766C0.146936 33.3465 0.241312 33.4888 0.431553 33.5H35.0623C35.278 33.5 35.4497 33.3411 35.4938 33.1766L35.8174 31.9908Z"
|
||||
fill="#F48120"
|
||||
/>
|
||||
<path
|
||||
d="M41.751 20.1307C41.2186 20.1391 40.8525 20.3504 40.7958 20.5616L40.1328 22.9334C39.9592 23.3926 39.898 23.8865 39.9543 24.374C40.0106 24.8616 40.1828 25.3286 40.4564 25.7362C40.7375 26.0729 41.0823 26.351 41.4711 26.5545C41.8598 26.7579 42.2849 26.8828 42.722 26.922L46.7137 27.1376C46.9733 27.1376 47.1378 27.321 47.0373 27.5688C46.9596 27.7605 46.8216 27.8921 46.6058 27.8921L42.5062 28.1077C41.3076 28.2407 40.1661 28.6902 39.1991 29.4102C38.2321 30.1301 37.4745 31.0945 37.0042 32.2041C36.8527 32.5615 36.7884 33.1743 36.7884 33.1743C36.7792 33.3411 36.7884 33.4976 37.0042 33.4976H51.2448C51.3658 33.4976 51.5173 33.4187 51.5772 33.2355C51.8724 32.3338 51.9702 31.3198 52 30.3715C51.9829 27.6607 50.8976 25.0659 48.9793 23.149C47.0609 21.2322 44.464 20.1478 41.751 20.1307Z"
|
||||
fill="#FAAD3F"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_2129_46279">
|
||||
<rect width={52} height={52} fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<path
|
||||
d="M35.8174 31.9908C35.9336 31.5457 36.0522 31.0378 35.9959 30.5502C35.9396 30.0627 35.7674 29.5956 35.4938 29.1881C35.2127 28.8513 34.8679 28.5733 34.4792 28.3698C34.0904 28.1663 33.6653 28.0414 33.2282 28.0023L14.4564 27.7867C14.1594 27.7867 14.0537 27.504 14.1594 27.321C14.2205 27.2154 14.3665 27.1098 14.5822 27.1098L33.3968 26.8986C34.5954 26.7656 35.7841 26.2341 36.7511 25.5141C37.7181 24.7941 38.4758 23.8298 38.9461 22.7202L39.9502 20.1391C40.0559 19.8223 40.0352 19.3998 39.9502 19.083C39.2572 16.4987 38.0151 14.6359 35.9712 12.9075C33.9274 11.1792 31.3748 10.1648 28.7013 10.0184C26.0278 9.87203 23.3795 10.6017 21.1589 12.0966C18.9383 13.5914 17.2668 15.7697 16.3984 18.3005C15.2709 17.4959 13.8957 17.1142 12.5145 17.2225C11.247 17.3637 10.0652 17.9315 9.16334 18.8327C8.26149 19.7338 7.69322 20.9147 7.55188 22.1812C7.48005 22.8295 7.5165 23.4852 7.65976 24.1216C5.60883 24.1782 3.66094 25.0322 2.23044 26.5018C0.799944 27.9714 0.00342678 29.9407 1.64306e-05 31.9908C-0.00064861 32.3906 0.0186006 32.788 0.107899 33.1766C0.146936 33.3465 0.241312 33.4888 0.431553 33.5H35.0623C35.278 33.5 35.4497 33.3411 35.4938 33.1766L35.8174 31.9908Z"
|
||||
fill="#F48120"
|
||||
/>
|
||||
<path
|
||||
d="M41.751 20.1307C41.2186 20.1391 40.8525 20.3504 40.7958 20.5616L40.1328 22.9334C39.9592 23.3926 39.898 23.8865 39.9543 24.374C40.0106 24.8616 40.1828 25.3286 40.4564 25.7362C40.7375 26.0729 41.0823 26.351 41.4711 26.5545C41.8598 26.7579 42.2849 26.8828 42.722 26.922L46.7137 27.1376C46.9733 27.1376 47.1378 27.321 47.0373 27.5688C46.9596 27.7605 46.8216 27.8921 46.6058 27.8921L42.5062 28.1077C41.3076 28.2407 40.1661 28.6902 39.1991 29.4102C38.2321 30.1301 37.4745 31.0945 37.0042 32.2041C36.8527 32.5615 36.7884 33.1743 36.7884 33.1743C36.7792 33.3411 36.7884 33.4976 37.0042 33.4976H51.2448C51.3658 33.4976 51.5173 33.4187 51.5772 33.2355C51.8724 32.3338 51.9702 31.3198 52 30.3715C51.9829 27.6607 50.8976 25.0659 48.9793 23.149C47.0609 21.2322 44.464 20.1478 41.751 20.1307Z"
|
||||
fill="#FAAD3F"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
export default SvgCloudflare;
|
||||
@@ -7,6 +7,7 @@ export { default as SvgAzure } from "@opal/logos/azure";
|
||||
export { default as SvgBifrost } from "@opal/logos/bifrost";
|
||||
export { default as SvgBitbucket } from "@opal/logos/bitbucket";
|
||||
export { default as SvgBookStack } from "@opal/logos/bookstack";
|
||||
export { default as SvgBox } from "@opal/logos/box";
|
||||
export { default as SvgBraintrust } from "@opal/logos/braintrust";
|
||||
export { default as SvgBrave } from "@opal/logos/brave";
|
||||
export { default as SvgCanvas } from "@opal/logos/canvas";
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 44 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.8623 0C13.576 0.000127038 14.9658 1.38669 14.9658 3.09668V6.19336C14.9658 7.90339 13.576 9.28991 11.8623 9.29004H10.3105V11.3545H11.8623C13.5758 11.3546 14.9656 12.7413 14.9658 14.4512V17.5488C14.9656 19.2587 13.5758 20.6454 11.8623 20.6455H10.3105V22.71H11.8623C13.576 22.7101 14.9658 24.0966 14.9658 25.8066V28.9033C14.9658 30.6133 13.576 31.9999 11.8623 32H8.75879C7.04503 32 5.65532 30.6134 5.65527 28.9033V26.3223H4.10352C2.38972 26.3223 1 24.9357 1 23.2256V20.1289C1.00007 18.4189 2.38976 17.0322 4.10352 17.0322H5.65527V14.9678H4.10352C2.38976 14.9678 1.00007 13.5811 1 11.8711V8.77441C1 7.06431 2.38972 5.67773 4.10352 5.67773H5.65527V3.09668C5.65532 1.38662 7.04503 0 8.75879 0H11.8623ZM23.2412 0C24.955 0 26.3447 1.38662 26.3447 3.09668V5.67773H27.8965C29.6103 5.67773 31 7.06431 31 8.77441V11.8711C30.9999 13.5811 29.6102 14.9678 27.8965 14.9678H26.3447V17.0322H27.8965C29.6102 17.0322 30.9999 18.4189 31 20.1289V23.2256C31 24.9357 29.6103 26.3223 27.8965 26.3223H26.3447V28.9033C26.3447 30.6134 24.955 32 23.2412 32H20.1377C18.424 31.9999 17.0342 30.6133 17.0342 28.9033V25.8066C17.0342 24.0966 18.424 22.7101 20.1377 22.71H21.6895V20.6455H20.1377C18.4241 20.6454 17.0344 19.2587 17.0342 17.5488V14.4512C17.0344 12.7413 18.4241 11.3546 20.1377 11.3545H21.6895V9.29004H20.1377C18.424 9.28992 17.0342 7.9034 17.0342 6.19336V3.09668C17.0342 1.38669 18.424 0.000115963 20.1377 0H23.2412Z" fill="#2C1FEB"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 51 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB |
+1
-1
@@ -1,4 +1,5 @@
|
||||
import type { TimelineTranslate } from "@/app/app/message/messageComponents/toolDisplayHelpers";
|
||||
import { getSourceDisplayName, isValidSource } from "@/lib/connectors/utils";
|
||||
import {
|
||||
PacketType,
|
||||
SearchToolPacket,
|
||||
@@ -9,7 +10,6 @@ import {
|
||||
SectionEnd,
|
||||
} from "@/app/app/services/streamingModels";
|
||||
import { OnyxDocument } from "@/lib/search/types";
|
||||
import { getSourceDisplayName, isValidSource } from "@/lib/sources";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
|
||||
export const MAX_TITLE_LENGTH = 25;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getSourceDisplayName } from "@/lib/connectors/utils";
|
||||
import OAuthCallbackPage from "@/components/oauth/OAuthCallbackPage";
|
||||
import { getSourceDisplayName } from "@/lib/sources";
|
||||
|
||||
export default function FederatedOAuthCallbackPage() {
|
||||
const t = useTranslations("admin.federatedCallback");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
|
||||
export interface SourceIconProps {
|
||||
sourceType: ValidSources;
|
||||
|
||||
@@ -7,7 +7,7 @@ import type {
|
||||
SlackConfig,
|
||||
ZulipConfig,
|
||||
} from "@/lib/connectors/types";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
import Link from "next/link";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { IconLoader } from "@opal/loaders";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import {
|
||||
@@ -20,7 +21,6 @@ import {
|
||||
CredentialSchemaResponse,
|
||||
} from "@/lib/credentials/types";
|
||||
import type { ConfigurableSources } from "@/lib/connectors/types/source";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import { SourceIcon } from "@/components/SourceIcon";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Card, Modal } from "@opal/components";
|
||||
import { Button } from "@opal/components";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import { useSettings } from "@/lib/settings/hooks";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import useFederatedOAuthStatus from "@/hooks/useFederatedOAuthStatus";
|
||||
import { SvgLink } from "@opal/icons";
|
||||
import { ContentAction, Section } from "@opal/layouts";
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import React, { JSX } from "react";
|
||||
import { DocumentSetSummary, Tag } from "@/lib/types";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import { SourceMetadata } from "@/lib/search/types";
|
||||
import { listSourceMetadata } from "@/lib/connectors/utils";
|
||||
import { SourceMetadata, ValidSources } from "@/lib/connectors/types/source";
|
||||
import { FiBook, FiBookmark, FiMap, FiX } from "react-icons/fi";
|
||||
import { SearchDateRangeSelector } from "@/components/dateRangeSelectors/SearchDateRangeSelector";
|
||||
import { InputDateRangePickerValue } from "@opal/components";
|
||||
import { listSourceMetadata } from "@/lib/sources";
|
||||
import { SourceIcon } from "@/components/SourceIcon";
|
||||
import { FilterDropdown } from "@/components/search/filtering/FilterDropdown";
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*/
|
||||
import { SvgBifrost, SvgConfluence, SvgGitBook, SvgGitHub } from "@opal/logos";
|
||||
import { render } from "@tests/setup/test-utils";
|
||||
import { GoogleStorageIcon } from "./icons";
|
||||
|
||||
describe("Logo Icons", () => {
|
||||
test("renders as an SVG element", () => {
|
||||
@@ -32,15 +31,6 @@ describe("Logo Icons", () => {
|
||||
expect(svg).toHaveAttribute("height", "24");
|
||||
});
|
||||
|
||||
test("applies size adjustments", () => {
|
||||
// GoogleStorageIcon has a +4px size adjustment
|
||||
const { container } = render(<GoogleStorageIcon size={16} />);
|
||||
const image = container.querySelector("img");
|
||||
|
||||
// Base 16 + adjustment 4 = 20
|
||||
expect(image).toHaveStyle({ width: "20px", height: "20px" });
|
||||
});
|
||||
|
||||
test("renders opal SVG logo as single element", () => {
|
||||
const { container } = render(<SvgGitBook size={32} />);
|
||||
const svg = container.querySelector("svg");
|
||||
|
||||
@@ -3,11 +3,7 @@
|
||||
import Image from "next/image";
|
||||
import { StaticImageData } from "next/image";
|
||||
import { useTranslations } from "next-intl";
|
||||
import googleCloudStorageIcon from "@public/GoogleCloudStorage.png";
|
||||
import openSourceIcon from "@public/OpenSource.png";
|
||||
import r2Icon from "@public/r2.png";
|
||||
import s3Icon from "@public/S3.png";
|
||||
import boxIcon from "@public/Box.png";
|
||||
import trelloIcon from "@public/Trello.png";
|
||||
import serviceNowIcon from "@public/Servicenow.png";
|
||||
import zAIIcon from "@public/Z_AI.png";
|
||||
@@ -237,15 +233,7 @@ export const WindowsIcon = ({
|
||||
// THIRD-PARTY / COMPANY ICONS (Alphabetically)
|
||||
// Only icons that don't yet have opal logo equivalents remain here.
|
||||
// ============================================================================
|
||||
export const BoxIcon = createLogoIcon(boxIcon);
|
||||
export const BraintrustIcon = createLogoIcon("/Braintrust.svg");
|
||||
export const GoogleStorageIcon = createLogoIcon(googleCloudStorageIcon, {
|
||||
sizeAdjustment: 4,
|
||||
classNameAddition: "-m-0.5",
|
||||
});
|
||||
export const OpenSourceIcon = createLogoIcon(openSourceIcon);
|
||||
export const R2Icon = createLogoIcon(r2Icon);
|
||||
export const S3Icon = createLogoIcon(s3Icon);
|
||||
export const ServiceNowIcon = createLogoIcon(serviceNowIcon);
|
||||
export const TrelloIcon = createLogoIcon(trelloIcon);
|
||||
export const ZAIIcon = createLogoIcon(zAIIcon);
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { IconLoader } from "@opal/loaders";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { BaseFilters, MinimalOnyxDocument } from "@/lib/search/types";
|
||||
@@ -9,7 +10,6 @@ import { Divider, Pagination } from "@opal/components";
|
||||
import { EmptyMessageCard } from "@opal/components";
|
||||
import { IllustrationContent, toast } from "@opal/layouts";
|
||||
import SvgNoResult from "@opal/illustrations/no-result";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import { Tag } from "@/lib/types";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import {
|
||||
|
||||
@@ -7,6 +7,8 @@ import {
|
||||
setPreferredResponse,
|
||||
updateLlmOverrideForChatSession,
|
||||
} from "@/app/app/services/lib";
|
||||
import { getConfiguredSources } from "@/lib/connectors/utils";
|
||||
import { type SourceMetadata } from "@/lib/connectors/types/source";
|
||||
import {
|
||||
applyPreferredResponse,
|
||||
chooseImplicitPreferred,
|
||||
@@ -17,7 +19,6 @@ import {
|
||||
import { getMaxSelectedDocumentTokens } from "@/lib/projects/svc";
|
||||
import { DEFAULT_CONTEXT_TOKENS } from "@/lib/constants";
|
||||
import { StreamStopInfo } from "@/lib/search/types";
|
||||
import type { SourceMetadata } from "@/lib/search/types";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import type { Route } from "next";
|
||||
import {
|
||||
@@ -90,7 +91,6 @@ import { ProjectFile, useProjectsContext } from "@/lib/projects/providers";
|
||||
import { useIncognito } from "@/providers/IncognitoProvider";
|
||||
import { projectFilesToFileDescriptors } from "@/lib/projects/utils";
|
||||
import { useAvailableSources } from "@/lib/connectors/hooks";
|
||||
import { getConfiguredSources } from "@/lib/sources";
|
||||
|
||||
const SYSTEM_MESSAGE_ID = -3;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { getConfiguredSources } from "@/lib/connectors/utils";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import type { OnSubmitProps } from "@/hooks/useChatController";
|
||||
import { SEARCH_PARAM_NAMES } from "@/app/app/services/searchParams";
|
||||
@@ -10,7 +11,6 @@ import { useDocumentSets } from "@/lib/hooks/useDocumentSets";
|
||||
import { useProjectsContext } from "@/lib/projects/providers";
|
||||
import { useTags } from "@/lib/searchFilters/hooks";
|
||||
import { normalizeSourceSelection } from "@/lib/searchFilters/utils";
|
||||
import { getConfiguredSources } from "@/lib/sources";
|
||||
import type { ToolConfigurationHandle } from "@/lib/tools/hooks";
|
||||
|
||||
interface UseSendChatMessageFromURLProps {
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
"use client";
|
||||
|
||||
import { useMemo } from "react";
|
||||
import { type SourceMetadata } from "@/lib/connectors/types/source";
|
||||
import type { Route } from "next";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Button, SelectCard } from "@opal/components";
|
||||
import { ContentAction } from "@opal/layouts";
|
||||
import { SvgPlusCircle } from "@opal/icons";
|
||||
import type { SourceMetadata } from "@/lib/search/types";
|
||||
import type { IconFunctionComponent, IconProps } from "@opal/types";
|
||||
import { cn } from "@opal/utils";
|
||||
|
||||
export interface ConnectorSourceCardProps {
|
||||
sourceMetadata: SourceMetadata;
|
||||
@@ -30,6 +33,17 @@ export default function ConnectorSourceCard({
|
||||
const t = useTranslations("admin.addConnector");
|
||||
const router = useRouter();
|
||||
const navigate = () => router.push(navigationUrl);
|
||||
const SourceIcon = sourceMetadata.icon;
|
||||
// The catalog shows its logos a step larger than `main-ui` content does:
|
||||
// 20px instead of 16px. The size is fixed here, so the 16px that Content
|
||||
// asks for is ignored; the negative margin keeps the 16px footprint, so
|
||||
// the title does not move.
|
||||
const icon: IconFunctionComponent = useMemo(() => {
|
||||
function CatalogSourceIcon({ className }: IconProps) {
|
||||
return <SourceIcon size={20} className={cn(className, "-m-0.5")} />;
|
||||
}
|
||||
return CatalogSourceIcon;
|
||||
}, [SourceIcon]);
|
||||
|
||||
return (
|
||||
<SelectCard
|
||||
@@ -44,14 +58,17 @@ export default function ConnectorSourceCard({
|
||||
onClick={navigate}
|
||||
>
|
||||
<ContentAction
|
||||
icon={sourceMetadata.icon}
|
||||
icon={icon}
|
||||
title={sourceMetadata.displayName}
|
||||
description={description}
|
||||
// One line keeps the cards even; a cut description shows in a tooltip.
|
||||
// One line keeps the cards even; a cut title or description shows in
|
||||
// a tooltip.
|
||||
titleMaxLines={1}
|
||||
descriptionMaxLines={1}
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
padding={2}
|
||||
gapping={0}
|
||||
rightChildren={
|
||||
<Button
|
||||
icon={SvgPlusCircle}
|
||||
|
||||
@@ -1,5 +1,63 @@
|
||||
import { SourceCategory } from "@/lib/search/types";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import type { FC } from "react";
|
||||
import { DOCS_ADMINS_PATH, DOCS_BASE_URL } from "@/lib/constants";
|
||||
import { SourceCategory, ValidSources } from "@/lib/connectors/types/source";
|
||||
import { SvgFileText, SvgGlobe, SvgUploadCloud, SvgMail } from "@opal/icons";
|
||||
import {
|
||||
SvgAirtable,
|
||||
SvgAsana,
|
||||
SvgAWS,
|
||||
SvgAxero,
|
||||
SvgBitbucket,
|
||||
SvgBookStack,
|
||||
SvgBox,
|
||||
SvgBraintrust,
|
||||
SvgCanvas,
|
||||
SvgClickUp,
|
||||
SvgCloudflare,
|
||||
SvgCoda,
|
||||
SvgConfluence,
|
||||
SvgDiscord,
|
||||
SvgDiscourse,
|
||||
SvgDocument360,
|
||||
SvgDropbox,
|
||||
SvgDrupal,
|
||||
SvgEgnyte,
|
||||
SvgFireflies,
|
||||
SvgFreshdesk,
|
||||
SvgGitBook,
|
||||
SvgGitHub,
|
||||
SvgGitLab,
|
||||
SvgGmail,
|
||||
SvgGong,
|
||||
SvgGoogleCloud,
|
||||
SvgGoogleDrive,
|
||||
SvgGoogleSites,
|
||||
SvgGuru,
|
||||
SvgHighspot,
|
||||
SvgHubSpot,
|
||||
SvgJira,
|
||||
SvgLinear,
|
||||
SvgLoopio,
|
||||
SvgLumApps,
|
||||
SvgMediaWiki,
|
||||
SvgNotion,
|
||||
SvgOneDrive,
|
||||
SvgOracle,
|
||||
SvgOutline,
|
||||
SvgOutlook,
|
||||
SvgProductboard,
|
||||
SvgSalesforce,
|
||||
SvgSharePoint,
|
||||
SvgSlab,
|
||||
SvgSlack,
|
||||
SvgTeams,
|
||||
SvgTestRail,
|
||||
SvgWikipedia,
|
||||
SvgXenForo,
|
||||
SvgZendesk,
|
||||
SvgZoom,
|
||||
SvgZulip,
|
||||
} from "@opal/logos";
|
||||
|
||||
/**
|
||||
* Message key, inside the `admin.addConnector` namespace, for each category
|
||||
@@ -90,3 +148,432 @@ export const SOURCE_DESCRIPTION_KEYS = {
|
||||
[ValidSources.OneDrive]: "sources.onedrive.description",
|
||||
[ValidSources.Zoom]: "sources.zoom.description",
|
||||
} as const satisfies Record<ValidSources, string>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Source metadata
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export interface PartialSourceMetadata {
|
||||
icon: FC<{ size?: number; className?: string }>;
|
||||
displayName: string;
|
||||
category: SourceCategory;
|
||||
isPopular?: boolean;
|
||||
docs?: string;
|
||||
oauthSupported?: boolean;
|
||||
federated?: boolean;
|
||||
federatedTooltip?: string;
|
||||
// federated connectors store the base source type if it's a source
|
||||
// that has both indexed connectors and federated connectors
|
||||
baseSourceType?: ValidSources;
|
||||
}
|
||||
|
||||
type SourceMap = {
|
||||
[K in ValidSources | "federated_slack"]: PartialSourceMetadata;
|
||||
};
|
||||
|
||||
const slackMetadata = {
|
||||
icon: SvgSlack,
|
||||
displayName: "Slack",
|
||||
category: SourceCategory.Messaging,
|
||||
isPopular: true,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/slack`,
|
||||
oauthSupported: true,
|
||||
// Federated Slack is available as an option but not the default
|
||||
federated: true,
|
||||
federatedTooltip:
|
||||
"⚠️ WARNING: Federated Slack results in significantly greater latency and lower search quality.",
|
||||
baseSourceType: "slack",
|
||||
};
|
||||
|
||||
export const SOURCE_METADATA_MAP: SourceMap = {
|
||||
// Knowledge Base & Wikis
|
||||
confluence: {
|
||||
icon: SvgConfluence,
|
||||
displayName: "Confluence",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/confluence`,
|
||||
oauthSupported: true,
|
||||
isPopular: true,
|
||||
},
|
||||
lumapps: {
|
||||
icon: SvgLumApps,
|
||||
displayName: "LumApps",
|
||||
category: SourceCategory.Wiki,
|
||||
},
|
||||
sharepoint: {
|
||||
icon: SvgSharePoint,
|
||||
displayName: "SharePoint",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/sharepoint`,
|
||||
isPopular: true,
|
||||
},
|
||||
coda: {
|
||||
icon: SvgCoda,
|
||||
displayName: "Coda",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/coda`,
|
||||
},
|
||||
notion: {
|
||||
icon: SvgNotion,
|
||||
displayName: "Notion",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/notion`,
|
||||
},
|
||||
bookstack: {
|
||||
icon: SvgBookStack,
|
||||
displayName: "BookStack",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/bookstack`,
|
||||
},
|
||||
document360: {
|
||||
icon: SvgDocument360,
|
||||
displayName: "Document360",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/document360`,
|
||||
},
|
||||
discourse: {
|
||||
icon: SvgDiscourse,
|
||||
displayName: "Discourse",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/discourse`,
|
||||
},
|
||||
gitbook: {
|
||||
icon: SvgGitBook,
|
||||
displayName: "GitBook",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/gitbook`,
|
||||
},
|
||||
slab: {
|
||||
icon: SvgSlab,
|
||||
displayName: "Slab",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/slab`,
|
||||
},
|
||||
outline: {
|
||||
icon: SvgOutline,
|
||||
displayName: "Outline",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/outline`,
|
||||
},
|
||||
google_sites: {
|
||||
icon: SvgGoogleSites,
|
||||
displayName: "Google Sites",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/google_sites`,
|
||||
},
|
||||
guru: {
|
||||
icon: SvgGuru,
|
||||
displayName: "Guru",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/guru`,
|
||||
},
|
||||
mediawiki: {
|
||||
icon: SvgMediaWiki,
|
||||
displayName: "MediaWiki",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/mediawiki`,
|
||||
},
|
||||
axero: {
|
||||
icon: SvgAxero,
|
||||
displayName: "Axero",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/axero`,
|
||||
},
|
||||
wikipedia: {
|
||||
icon: SvgWikipedia,
|
||||
displayName: "Wikipedia",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/wikipedia`,
|
||||
},
|
||||
canvas: {
|
||||
icon: SvgCanvas,
|
||||
displayName: "Canvas",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/canvas`,
|
||||
},
|
||||
|
||||
// Cloud Storage
|
||||
google_drive: {
|
||||
icon: SvgGoogleDrive,
|
||||
displayName: "Google Drive",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/google_drive/overview`,
|
||||
oauthSupported: true,
|
||||
isPopular: true,
|
||||
},
|
||||
onedrive: {
|
||||
icon: SvgOneDrive,
|
||||
displayName: "OneDrive",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/onedrive`,
|
||||
},
|
||||
box: {
|
||||
icon: SvgBox,
|
||||
displayName: "Box",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/box`,
|
||||
},
|
||||
dropbox: {
|
||||
icon: SvgDropbox,
|
||||
displayName: "Dropbox",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/dropbox`,
|
||||
},
|
||||
s3: {
|
||||
icon: SvgAWS,
|
||||
displayName: "Amazon S3",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/s3`,
|
||||
},
|
||||
google_cloud_storage: {
|
||||
icon: SvgGoogleCloud,
|
||||
displayName: "Google Cloud Storage",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/google_storage`,
|
||||
},
|
||||
egnyte: {
|
||||
icon: SvgEgnyte,
|
||||
displayName: "Egnyte",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/egnyte`,
|
||||
},
|
||||
oci_storage: {
|
||||
icon: SvgOracle,
|
||||
displayName: "Oracle Storage",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/oci_storage`,
|
||||
},
|
||||
r2: {
|
||||
icon: SvgCloudflare,
|
||||
displayName: "Cloudflare R2",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/r2`,
|
||||
},
|
||||
|
||||
// Ticketing & Task Management
|
||||
jira: {
|
||||
icon: SvgJira,
|
||||
displayName: "Jira",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/jira`,
|
||||
isPopular: true,
|
||||
},
|
||||
zendesk: {
|
||||
icon: SvgZendesk,
|
||||
displayName: "Zendesk",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/zendesk`,
|
||||
isPopular: true,
|
||||
},
|
||||
airtable: {
|
||||
icon: SvgAirtable,
|
||||
displayName: "Airtable",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/airtable`,
|
||||
},
|
||||
linear: {
|
||||
icon: SvgLinear,
|
||||
displayName: "Linear",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/linear`,
|
||||
},
|
||||
freshdesk: {
|
||||
icon: SvgFreshdesk,
|
||||
displayName: "Freshdesk",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/freshdesk`,
|
||||
},
|
||||
asana: {
|
||||
icon: SvgAsana,
|
||||
displayName: "Asana",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/asana`,
|
||||
},
|
||||
clickup: {
|
||||
icon: SvgClickUp,
|
||||
displayName: "ClickUp",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/clickup`,
|
||||
},
|
||||
productboard: {
|
||||
icon: SvgProductboard,
|
||||
displayName: "Productboard",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/productboard`,
|
||||
},
|
||||
testrail: {
|
||||
icon: SvgTestRail,
|
||||
displayName: "TestRail",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
},
|
||||
|
||||
// Messaging
|
||||
slack: slackMetadata,
|
||||
federated_slack: slackMetadata,
|
||||
teams: {
|
||||
icon: SvgTeams,
|
||||
displayName: "Teams",
|
||||
category: SourceCategory.Messaging,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/teams`,
|
||||
},
|
||||
outlook: {
|
||||
icon: SvgOutlook,
|
||||
displayName: "Outlook",
|
||||
category: SourceCategory.Messaging,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/outlook`,
|
||||
},
|
||||
zoom: {
|
||||
icon: SvgZoom,
|
||||
displayName: "Zoom",
|
||||
category: SourceCategory.Messaging,
|
||||
},
|
||||
gmail: {
|
||||
icon: SvgGmail,
|
||||
displayName: "Gmail",
|
||||
category: SourceCategory.Messaging,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/gmail/overview`,
|
||||
},
|
||||
drupal_wiki: {
|
||||
icon: SvgDrupal,
|
||||
displayName: "Drupal Wiki",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/drupal_wiki`,
|
||||
},
|
||||
imap: {
|
||||
icon: SvgMail,
|
||||
displayName: "Email",
|
||||
category: SourceCategory.Messaging,
|
||||
},
|
||||
discord: {
|
||||
icon: SvgDiscord,
|
||||
displayName: "Discord",
|
||||
category: SourceCategory.Messaging,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/discord`,
|
||||
},
|
||||
xenforo: {
|
||||
icon: SvgXenForo,
|
||||
displayName: "XenForo",
|
||||
category: SourceCategory.Messaging,
|
||||
},
|
||||
zulip: {
|
||||
icon: SvgZulip,
|
||||
displayName: "Zulip",
|
||||
category: SourceCategory.Messaging,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/zulip`,
|
||||
},
|
||||
|
||||
// Sales
|
||||
salesforce: {
|
||||
icon: SvgSalesforce,
|
||||
displayName: "Salesforce",
|
||||
category: SourceCategory.Sales,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/salesforce`,
|
||||
isPopular: true,
|
||||
},
|
||||
hubspot: {
|
||||
icon: SvgHubSpot,
|
||||
displayName: "HubSpot",
|
||||
category: SourceCategory.Sales,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/hubspot`,
|
||||
isPopular: true,
|
||||
},
|
||||
gong: {
|
||||
icon: SvgGong,
|
||||
displayName: "Gong",
|
||||
category: SourceCategory.Sales,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/gong`,
|
||||
isPopular: true,
|
||||
},
|
||||
fireflies: {
|
||||
icon: SvgFireflies,
|
||||
displayName: "Fireflies",
|
||||
category: SourceCategory.Sales,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/fireflies`,
|
||||
},
|
||||
highspot: {
|
||||
icon: SvgHighspot,
|
||||
displayName: "Highspot",
|
||||
category: SourceCategory.Sales,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/highspot`,
|
||||
},
|
||||
loopio: {
|
||||
icon: SvgLoopio,
|
||||
displayName: "Loopio",
|
||||
category: SourceCategory.Sales,
|
||||
},
|
||||
|
||||
// Code Repository
|
||||
github: {
|
||||
icon: SvgGitHub,
|
||||
displayName: "GitHub",
|
||||
category: SourceCategory.CodeRepository,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/github`,
|
||||
isPopular: true,
|
||||
},
|
||||
gitlab: {
|
||||
icon: SvgGitLab,
|
||||
displayName: "GitLab",
|
||||
category: SourceCategory.CodeRepository,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/gitlab`,
|
||||
},
|
||||
bitbucket: {
|
||||
icon: SvgBitbucket,
|
||||
displayName: "Bitbucket",
|
||||
category: SourceCategory.CodeRepository,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/bitbucket`,
|
||||
},
|
||||
|
||||
// Others
|
||||
web: {
|
||||
icon: SvgGlobe,
|
||||
displayName: "Web",
|
||||
category: SourceCategory.Other,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/web`,
|
||||
isPopular: true,
|
||||
},
|
||||
file: {
|
||||
icon: SvgFileText,
|
||||
displayName: "File",
|
||||
category: SourceCategory.Other,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/file`,
|
||||
isPopular: true,
|
||||
},
|
||||
user_file: {
|
||||
icon: SvgUploadCloud,
|
||||
displayName: "Uploaded Files",
|
||||
category: SourceCategory.Other,
|
||||
docs: `${DOCS_BASE_URL}/overview/core_features/chat#projects`,
|
||||
isPopular: false, // Needs to be false to hide from the Add Connector page
|
||||
},
|
||||
braintrust: {
|
||||
icon: SvgBraintrust,
|
||||
displayName: "Braintrust",
|
||||
category: SourceCategory.AiObservability,
|
||||
},
|
||||
|
||||
// Other
|
||||
ingestion_api: {
|
||||
icon: SvgGlobe,
|
||||
displayName: "Ingestion",
|
||||
category: SourceCategory.Other,
|
||||
},
|
||||
|
||||
// Craft-specific sources
|
||||
craft_file: {
|
||||
icon: SvgFileText,
|
||||
displayName: "Your Files",
|
||||
category: SourceCategory.Other,
|
||||
},
|
||||
|
||||
// Placeholder (non-null default)
|
||||
not_applicable: {
|
||||
icon: SvgGlobe,
|
||||
displayName: "Not Applicable",
|
||||
category: SourceCategory.Other,
|
||||
},
|
||||
mock_connector: {
|
||||
icon: SvgGlobe,
|
||||
displayName: "Mock Connector",
|
||||
category: SourceCategory.Other,
|
||||
},
|
||||
} as SourceMap;
|
||||
@@ -1,12 +1,13 @@
|
||||
import { connectorConfigs } from "@/lib/connectors/connectors";
|
||||
import { CREDENTIAL_SPECS } from "@/lib/credentials/constants";
|
||||
import {
|
||||
getSourceDocLink,
|
||||
getSourceMetadata,
|
||||
createConnectorInitialValues,
|
||||
createConnectorValidationSchema,
|
||||
} from "@/lib/connectors/utils";
|
||||
import { CREDENTIAL_SPECS } from "@/lib/credentials/constants";
|
||||
import { getCredentialFileType } from "@/lib/credentials/utils";
|
||||
import { FileTypeCategory, OneDriveScope } from "@/lib/connectors/types";
|
||||
import { getSourceDocLink, getSourceMetadata } from "@/lib/sources";
|
||||
import {
|
||||
ValidSources,
|
||||
validAutoSyncSources,
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* nothing outside the connector surface defines a source.
|
||||
*/
|
||||
|
||||
import type { FC } from "react";
|
||||
|
||||
export enum ValidSources {
|
||||
Web = "web",
|
||||
GitHub = "github",
|
||||
@@ -123,3 +125,31 @@ export const oauthSupportedSources: ConfigurableSources[] = [
|
||||
];
|
||||
|
||||
export type OAuthSupportedSource = (typeof oauthSupportedSources)[number];
|
||||
|
||||
/** The catalog section a source is listed under. */
|
||||
export enum SourceCategory {
|
||||
Wiki = "Knowledge Base & Wikis",
|
||||
Storage = "Cloud Storage",
|
||||
TicketingAndTaskManagement = "Ticketing & Task Management",
|
||||
Messaging = "Messaging",
|
||||
Sales = "Sales",
|
||||
CodeRepository = "Code Repository",
|
||||
AiObservability = "AI & Observability",
|
||||
Other = "Other",
|
||||
}
|
||||
|
||||
export interface SourceMetadata {
|
||||
icon: FC<{ size?: number; className?: string }>;
|
||||
displayName: string;
|
||||
category: SourceCategory;
|
||||
shortDescription?: string;
|
||||
internalName: ValidSources;
|
||||
adminUrl: string;
|
||||
isPopular?: boolean;
|
||||
oauthSupported?: boolean;
|
||||
federated?: boolean;
|
||||
federatedTooltip?: string;
|
||||
uniqueKey?: string;
|
||||
// For federated connectors, this stores the base source type for the icon
|
||||
baseSourceType?: ValidSources;
|
||||
}
|
||||
@@ -1,11 +1,18 @@
|
||||
import * as Yup from "yup";
|
||||
import {
|
||||
SOURCE_METADATA_MAP,
|
||||
type PartialSourceMetadata,
|
||||
} from "@/lib/connectors/constants";
|
||||
import {
|
||||
type SourceMetadata,
|
||||
ValidSources,
|
||||
type ConfigurableSources,
|
||||
} from "@/lib/connectors/types/source";
|
||||
import type {
|
||||
ConnectorAccessFormValues,
|
||||
ConnectorGroupRestrictionFormValues,
|
||||
} from "@/lib/connectors/accessType";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import type { IndexAttemptStage, IndexAttemptStageMetric } from "@/lib/types";
|
||||
import type { ConfigurableSources } from "@/lib/connectors/types/source";
|
||||
import { SWR_KEYS } from "@/lib/swr-keys";
|
||||
import {
|
||||
connectorConfigs,
|
||||
@@ -438,3 +445,94 @@ export function colorClassForStage(stage: IndexAttemptStage): string {
|
||||
|
||||
export const gmailConnectorNameBuilder = (values: GmailConfig) =>
|
||||
"GmailConnector";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Source metadata
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function fillSourceMetadata(
|
||||
partialMetadata: PartialSourceMetadata,
|
||||
internalName: ValidSources
|
||||
): SourceMetadata {
|
||||
return {
|
||||
internalName: partialMetadata.baseSourceType || internalName,
|
||||
...partialMetadata,
|
||||
adminUrl: `/admin/connectors/${internalName}`,
|
||||
};
|
||||
}
|
||||
|
||||
export function getSourceMetadata(sourceType: ValidSources): SourceMetadata {
|
||||
const partialMetadata = SOURCE_METADATA_MAP[sourceType];
|
||||
|
||||
// Fallback to not_applicable if sourceType not found in map
|
||||
if (!partialMetadata) {
|
||||
return fillSourceMetadata(
|
||||
SOURCE_METADATA_MAP[ValidSources.NotApplicable],
|
||||
ValidSources.NotApplicable
|
||||
);
|
||||
}
|
||||
|
||||
return fillSourceMetadata(partialMetadata, sourceType);
|
||||
}
|
||||
|
||||
export function listSourceMetadata(): SourceMetadata[] {
|
||||
/* This gives back all the viewable / common sources, primarily for
|
||||
display in the Add Connector page */
|
||||
const entries = Object.entries(SOURCE_METADATA_MAP)
|
||||
.filter(
|
||||
([source, _]) =>
|
||||
source !== "not_applicable" &&
|
||||
source !== "ingestion_api" &&
|
||||
source !== "mock_connector" &&
|
||||
// use the "regular" slack connector when listing
|
||||
source !== "federated_slack" &&
|
||||
// user_file is for internal use (projects), not the Add Connector page
|
||||
source !== "user_file" &&
|
||||
// craft_file backs the Craft user library, which has its own upload UI
|
||||
source !== "craft_file" &&
|
||||
// TODO: unhide once the rest of the Zoom connector stack has merged
|
||||
source !== "zoom"
|
||||
)
|
||||
.map(([source, metadata]) => {
|
||||
return fillSourceMetadata(metadata, source as ValidSources);
|
||||
});
|
||||
return entries;
|
||||
}
|
||||
|
||||
export function getSourceDocLink(sourceType: ValidSources): string | null {
|
||||
return SOURCE_METADATA_MAP[sourceType].docs || null;
|
||||
}
|
||||
|
||||
export function isValidSource(sourceType: string): boolean {
|
||||
return Object.keys(SOURCE_METADATA_MAP).includes(sourceType);
|
||||
}
|
||||
|
||||
export function getSourceDisplayName(sourceType: ValidSources): string | null {
|
||||
return getSourceMetadata(sourceType).displayName;
|
||||
}
|
||||
|
||||
/** The configured sources, one entry per source type. */
|
||||
export function getConfiguredSources(
|
||||
availableSources: ValidSources[]
|
||||
): Array<SourceMetadata & { originalName: string; uniqueKey: string }> {
|
||||
const seen = new Set<string>();
|
||||
const result: Array<
|
||||
SourceMetadata & { originalName: string; uniqueKey: string }
|
||||
> = [];
|
||||
|
||||
for (const sourceName of availableSources) {
|
||||
const cleanName = sourceName.replace("federated_", "") as ValidSources;
|
||||
if (seen.has(cleanName)) continue;
|
||||
seen.add(cleanName);
|
||||
|
||||
const metadata = getSourceMetadata(cleanName);
|
||||
if (metadata.internalName === ValidSources.NotApplicable) continue;
|
||||
|
||||
result.push({
|
||||
...metadata,
|
||||
originalName: sourceName,
|
||||
uniqueKey: cleanName,
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as Yup from "yup";
|
||||
import { InputTypeIn, MessageCard } from "@opal/components";
|
||||
import { getSourceDisplayName } from "@/lib/connectors/utils";
|
||||
import { InputVertical, Section } from "@opal/layouts";
|
||||
import { Form, Formik, FormikHelpers } from "formik";
|
||||
import { useState } from "react";
|
||||
@@ -9,7 +10,6 @@ import { getConnectorOauthRedirectUrl } from "@/lib/connectors/svc";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import { FormikField } from "@/refresh-components/form/FormikField";
|
||||
import { OAuthSignInRow } from "@/lib/credentials/components/OAuthSignInRow";
|
||||
import { getSourceDisplayName } from "@/lib/sources";
|
||||
|
||||
type OAuthFormValues = Record<string, string>;
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { AccessType } from "@/lib/types";
|
||||
import {
|
||||
getSourceDisplayName,
|
||||
buildCCPairInfoUrl,
|
||||
} from "@/lib/connectors/utils";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import { useTranslations } from "next-intl";
|
||||
import useSWR, { mutate } from "swr";
|
||||
@@ -15,8 +19,6 @@ import {
|
||||
import { Section, toast } from "@opal/layouts";
|
||||
import type { CCPairFullInfo } from "@/lib/connectors/types";
|
||||
import { Button, Card, Modal, Text } from "@opal/components";
|
||||
import { buildCCPairInfoUrl } from "@/lib/connectors/utils";
|
||||
import { getSourceDisplayName } from "@/lib/sources";
|
||||
import type { Credential } from "@/lib/credentials/types";
|
||||
import { getConnectorOauthRedirectUrl } from "@/lib/connectors/svc";
|
||||
import { useCredentialSetup } from "@/lib/credentials/hooks";
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import {
|
||||
getSourceDisplayName,
|
||||
getSourceMetadata,
|
||||
} from "@/lib/connectors/utils";
|
||||
import { useTranslations } from "next-intl";
|
||||
import useSWR, { mutate, useSWRConfig } from "swr";
|
||||
import { getConnectorOauthRedirectUrl } from "@/lib/connectors/svc";
|
||||
@@ -17,7 +21,6 @@ import {
|
||||
shouldRedirectToOAuth,
|
||||
} from "@/lib/credentials/utils";
|
||||
import { CredentialCreationMethod } from "@/lib/credentials/types";
|
||||
import { getSourceDisplayName, getSourceMetadata } from "@/lib/sources";
|
||||
import { prepareOAuthAuthorizationRequest } from "@/lib/oauth_utils";
|
||||
import {
|
||||
EE_ENABLED,
|
||||
|
||||
@@ -8,7 +8,8 @@ import {
|
||||
ConnectorIndexingStatusLiteResponse,
|
||||
IndexingStatusRequest,
|
||||
} from "@/lib/types";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import { getConfiguredSources } from "@/lib/connectors/utils";
|
||||
import { SourceMetadata, ValidSources } from "@/lib/connectors/types/source";
|
||||
import useSWR, { mutate, useSWRConfig } from "swr";
|
||||
import { errorHandlingFetcher } from "./fetcher";
|
||||
import {
|
||||
@@ -20,7 +21,6 @@ import {
|
||||
useState,
|
||||
} from "react";
|
||||
import { InputDateRangePickerValue } from "@opal/components";
|
||||
import { SourceMetadata } from "@/lib/search/types";
|
||||
import {
|
||||
getProviderOverrideForAgent,
|
||||
parseLlmDescriptor,
|
||||
@@ -35,7 +35,6 @@ import {
|
||||
ReasoningEffortOverride,
|
||||
} from "@/lib/languageModels/types";
|
||||
import { isAnthropic } from "@/lib/languageModels/svc";
|
||||
import { getConfiguredSources } from "@/lib/sources";
|
||||
import { DEFAULT_AGENT_ID, NEXT_PUBLIC_CLOUD_ENABLED } from "./constants";
|
||||
import { useUser } from "@/providers/UserProvider";
|
||||
import { SEARCH_TOOL_ID } from "@/lib/tools/constants";
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { InputDateRangePickerValue } from "@opal/components";
|
||||
import { Tag } from "@/lib/types";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import type {
|
||||
SourceMetadata,
|
||||
ValidSources,
|
||||
} from "@/lib/connectors/types/source";
|
||||
import { Agent } from "@/lib/agents/types";
|
||||
|
||||
export const FlowType = {
|
||||
@@ -120,33 +123,6 @@ export interface SearchResponse {
|
||||
additional_relevance?: Relevance;
|
||||
}
|
||||
|
||||
export enum SourceCategory {
|
||||
Wiki = "Knowledge Base & Wikis",
|
||||
Storage = "Cloud Storage",
|
||||
TicketingAndTaskManagement = "Ticketing & Task Management",
|
||||
Messaging = "Messaging",
|
||||
Sales = "Sales",
|
||||
CodeRepository = "Code Repository",
|
||||
AiObservability = "AI & Observability",
|
||||
Other = "Other",
|
||||
}
|
||||
|
||||
export interface SourceMetadata {
|
||||
icon: React.FC<{ size?: number; className?: string }>;
|
||||
displayName: string;
|
||||
category: SourceCategory;
|
||||
shortDescription?: string;
|
||||
internalName: ValidSources;
|
||||
adminUrl: string;
|
||||
isPopular?: boolean;
|
||||
oauthSupported?: boolean;
|
||||
federated?: boolean;
|
||||
federatedTooltip?: string;
|
||||
uniqueKey?: string;
|
||||
// For federated connectors, this stores the base source type for the icon
|
||||
baseSourceType?: ValidSources;
|
||||
}
|
||||
|
||||
export interface SearchDefaultOverrides {
|
||||
forceDisplayQA: boolean;
|
||||
offset: number;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { type SourceMetadata } from "@/lib/connectors/types/source";
|
||||
import useSWR from "swr";
|
||||
import { errorHandlingFetcher } from "@/lib/fetcher";
|
||||
import { SWR_KEYS } from "@/lib/swr-keys";
|
||||
import type { Tag } from "@/lib/types";
|
||||
import type { SourceMetadata } from "@/lib/search/types";
|
||||
import type { InputDateRangePickerValue } from "@opal/components";
|
||||
import type { SearchFilters } from "@/lib/searchFilters/types";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Tag } from "@/lib/types";
|
||||
import type { SourceMetadata } from "@/lib/search/types";
|
||||
import { type SourceMetadata } from "@/lib/connectors/types/source";
|
||||
import type { InputDateRangePickerValue } from "@opal/components";
|
||||
|
||||
/** What is selected, without the means to change it. */
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import type { Tag } from "@/lib/types";
|
||||
import type { ValidSources } from "@/lib/connectors/types/source";
|
||||
import type {
|
||||
SourceMetadata,
|
||||
ValidSources,
|
||||
} from "@/lib/connectors/types/source";
|
||||
import type { MinimalAgent } from "@/lib/agents/types";
|
||||
import type { ChatSearchFilters } from "@/lib/tools/types";
|
||||
import { isAssistant } from "@/lib/agents/utils";
|
||||
import { SEARCH_TOOL_ID } from "@/lib/tools/constants";
|
||||
import type { SourceMetadata } from "@/lib/search/types";
|
||||
import type { SearchFiltersRequest } from "@/lib/searchFilters/types";
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,575 +0,0 @@
|
||||
import {
|
||||
R2Icon,
|
||||
S3Icon,
|
||||
GoogleStorageIcon,
|
||||
BraintrustIcon,
|
||||
BoxIcon,
|
||||
} from "@/components/icons/icons";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import { SourceCategory, SourceMetadata } from "@/lib/search/types";
|
||||
import React from "react";
|
||||
import { DOCS_ADMINS_PATH, DOCS_BASE_URL } from "@/lib/constants";
|
||||
import { SvgFileText, SvgGlobe, SvgUploadCloud, SvgMail } from "@opal/icons";
|
||||
import {
|
||||
SvgAirtable,
|
||||
SvgAsana,
|
||||
SvgAxero,
|
||||
SvgBitbucket,
|
||||
SvgBookStack,
|
||||
SvgCanvas,
|
||||
SvgClickUp,
|
||||
SvgCoda,
|
||||
SvgConfluence,
|
||||
SvgDiscord,
|
||||
SvgDiscourse,
|
||||
SvgDocument360,
|
||||
SvgDropbox,
|
||||
SvgDrupal,
|
||||
SvgEgnyte,
|
||||
SvgFireflies,
|
||||
SvgFreshdesk,
|
||||
SvgGitBook,
|
||||
SvgGitHub,
|
||||
SvgGitLab,
|
||||
SvgGmail,
|
||||
SvgGong,
|
||||
SvgGoogleDrive,
|
||||
SvgGoogleSites,
|
||||
SvgGuru,
|
||||
SvgHighspot,
|
||||
SvgHubSpot,
|
||||
SvgJira,
|
||||
SvgLinear,
|
||||
SvgLoopio,
|
||||
SvgLumApps,
|
||||
SvgMediaWiki,
|
||||
SvgNotion,
|
||||
SvgOneDrive,
|
||||
SvgOracle,
|
||||
SvgOutline,
|
||||
SvgOutlook,
|
||||
SvgProductboard,
|
||||
SvgSalesforce,
|
||||
SvgSharePoint,
|
||||
SvgSlab,
|
||||
SvgSlack,
|
||||
SvgTeams,
|
||||
SvgTestRail,
|
||||
SvgWikipedia,
|
||||
SvgXenForo,
|
||||
SvgZendesk,
|
||||
SvgZoom,
|
||||
SvgZulip,
|
||||
} from "@opal/logos";
|
||||
|
||||
interface PartialSourceMetadata {
|
||||
icon: React.FC<{ size?: number; className?: string }>;
|
||||
displayName: string;
|
||||
category: SourceCategory;
|
||||
isPopular?: boolean;
|
||||
docs?: string;
|
||||
oauthSupported?: boolean;
|
||||
federated?: boolean;
|
||||
federatedTooltip?: string;
|
||||
// federated connectors store the base source type if it's a source
|
||||
// that has both indexed connectors and federated connectors
|
||||
baseSourceType?: ValidSources;
|
||||
}
|
||||
|
||||
type SourceMap = {
|
||||
[K in ValidSources | "federated_slack"]: PartialSourceMetadata;
|
||||
};
|
||||
|
||||
const slackMetadata = {
|
||||
icon: SvgSlack,
|
||||
displayName: "Slack",
|
||||
category: SourceCategory.Messaging,
|
||||
isPopular: true,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/slack`,
|
||||
oauthSupported: true,
|
||||
// Federated Slack is available as an option but not the default
|
||||
federated: true,
|
||||
federatedTooltip:
|
||||
"⚠️ WARNING: Federated Slack results in significantly greater latency and lower search quality.",
|
||||
baseSourceType: "slack",
|
||||
};
|
||||
|
||||
export const SOURCE_METADATA_MAP: SourceMap = {
|
||||
// Knowledge Base & Wikis
|
||||
confluence: {
|
||||
icon: SvgConfluence,
|
||||
displayName: "Confluence",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/confluence`,
|
||||
oauthSupported: true,
|
||||
isPopular: true,
|
||||
},
|
||||
lumapps: {
|
||||
icon: SvgLumApps,
|
||||
displayName: "LumApps",
|
||||
category: SourceCategory.Wiki,
|
||||
},
|
||||
sharepoint: {
|
||||
icon: SvgSharePoint,
|
||||
displayName: "SharePoint",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/sharepoint`,
|
||||
isPopular: true,
|
||||
},
|
||||
coda: {
|
||||
icon: SvgCoda,
|
||||
displayName: "Coda",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/coda`,
|
||||
},
|
||||
notion: {
|
||||
icon: SvgNotion,
|
||||
displayName: "Notion",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/notion`,
|
||||
},
|
||||
bookstack: {
|
||||
icon: SvgBookStack,
|
||||
displayName: "BookStack",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/bookstack`,
|
||||
},
|
||||
document360: {
|
||||
icon: SvgDocument360,
|
||||
displayName: "Document360",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/document360`,
|
||||
},
|
||||
discourse: {
|
||||
icon: SvgDiscourse,
|
||||
displayName: "Discourse",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/discourse`,
|
||||
},
|
||||
gitbook: {
|
||||
icon: SvgGitBook,
|
||||
displayName: "GitBook",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/gitbook`,
|
||||
},
|
||||
slab: {
|
||||
icon: SvgSlab,
|
||||
displayName: "Slab",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/slab`,
|
||||
},
|
||||
outline: {
|
||||
icon: SvgOutline,
|
||||
displayName: "Outline",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/outline`,
|
||||
},
|
||||
google_sites: {
|
||||
icon: SvgGoogleSites,
|
||||
displayName: "Google Sites",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/google_sites`,
|
||||
},
|
||||
guru: {
|
||||
icon: SvgGuru,
|
||||
displayName: "Guru",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/guru`,
|
||||
},
|
||||
mediawiki: {
|
||||
icon: SvgMediaWiki,
|
||||
displayName: "MediaWiki",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/mediawiki`,
|
||||
},
|
||||
axero: {
|
||||
icon: SvgAxero,
|
||||
displayName: "Axero",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/axero`,
|
||||
},
|
||||
wikipedia: {
|
||||
icon: SvgWikipedia,
|
||||
displayName: "Wikipedia",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/wikipedia`,
|
||||
},
|
||||
canvas: {
|
||||
icon: SvgCanvas,
|
||||
displayName: "Canvas",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/canvas`,
|
||||
},
|
||||
|
||||
// Cloud Storage
|
||||
google_drive: {
|
||||
icon: SvgGoogleDrive,
|
||||
displayName: "Google Drive",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/google_drive/overview`,
|
||||
oauthSupported: true,
|
||||
isPopular: true,
|
||||
},
|
||||
onedrive: {
|
||||
icon: SvgOneDrive,
|
||||
displayName: "OneDrive",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/onedrive`,
|
||||
},
|
||||
box: {
|
||||
icon: BoxIcon,
|
||||
displayName: "Box",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/box`,
|
||||
},
|
||||
dropbox: {
|
||||
icon: SvgDropbox,
|
||||
displayName: "Dropbox",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/dropbox`,
|
||||
},
|
||||
s3: {
|
||||
icon: S3Icon,
|
||||
displayName: "S3",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/s3`,
|
||||
},
|
||||
google_cloud_storage: {
|
||||
icon: GoogleStorageIcon,
|
||||
displayName: "Google Storage",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/google_storage`,
|
||||
},
|
||||
egnyte: {
|
||||
icon: SvgEgnyte,
|
||||
displayName: "Egnyte",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/egnyte`,
|
||||
},
|
||||
oci_storage: {
|
||||
icon: SvgOracle,
|
||||
displayName: "Oracle Storage",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/oci_storage`,
|
||||
},
|
||||
r2: {
|
||||
icon: R2Icon,
|
||||
displayName: "R2",
|
||||
category: SourceCategory.Storage,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/r2`,
|
||||
},
|
||||
|
||||
// Ticketing & Task Management
|
||||
jira: {
|
||||
icon: SvgJira,
|
||||
displayName: "Jira",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/jira`,
|
||||
isPopular: true,
|
||||
},
|
||||
zendesk: {
|
||||
icon: SvgZendesk,
|
||||
displayName: "Zendesk",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/zendesk`,
|
||||
isPopular: true,
|
||||
},
|
||||
airtable: {
|
||||
icon: SvgAirtable,
|
||||
displayName: "Airtable",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/airtable`,
|
||||
},
|
||||
linear: {
|
||||
icon: SvgLinear,
|
||||
displayName: "Linear",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/linear`,
|
||||
},
|
||||
freshdesk: {
|
||||
icon: SvgFreshdesk,
|
||||
displayName: "Freshdesk",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/freshdesk`,
|
||||
},
|
||||
asana: {
|
||||
icon: SvgAsana,
|
||||
displayName: "Asana",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/asana`,
|
||||
},
|
||||
clickup: {
|
||||
icon: SvgClickUp,
|
||||
displayName: "ClickUp",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/clickup`,
|
||||
},
|
||||
productboard: {
|
||||
icon: SvgProductboard,
|
||||
displayName: "Productboard",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/productboard`,
|
||||
},
|
||||
testrail: {
|
||||
icon: SvgTestRail,
|
||||
displayName: "TestRail",
|
||||
category: SourceCategory.TicketingAndTaskManagement,
|
||||
},
|
||||
|
||||
// Messaging
|
||||
slack: slackMetadata,
|
||||
federated_slack: slackMetadata,
|
||||
teams: {
|
||||
icon: SvgTeams,
|
||||
displayName: "Teams",
|
||||
category: SourceCategory.Messaging,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/teams`,
|
||||
},
|
||||
outlook: {
|
||||
icon: SvgOutlook,
|
||||
displayName: "Outlook",
|
||||
category: SourceCategory.Messaging,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/outlook`,
|
||||
},
|
||||
zoom: {
|
||||
icon: SvgZoom,
|
||||
displayName: "Zoom",
|
||||
category: SourceCategory.Messaging,
|
||||
},
|
||||
gmail: {
|
||||
icon: SvgGmail,
|
||||
displayName: "Gmail",
|
||||
category: SourceCategory.Messaging,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/gmail/overview`,
|
||||
},
|
||||
drupal_wiki: {
|
||||
icon: SvgDrupal,
|
||||
displayName: "Drupal Wiki",
|
||||
category: SourceCategory.Wiki,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/drupal_wiki`,
|
||||
},
|
||||
imap: {
|
||||
icon: SvgMail,
|
||||
displayName: "Email",
|
||||
category: SourceCategory.Messaging,
|
||||
},
|
||||
discord: {
|
||||
icon: SvgDiscord,
|
||||
displayName: "Discord",
|
||||
category: SourceCategory.Messaging,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/discord`,
|
||||
},
|
||||
xenforo: {
|
||||
icon: SvgXenForo,
|
||||
displayName: "XenForo",
|
||||
category: SourceCategory.Messaging,
|
||||
},
|
||||
zulip: {
|
||||
icon: SvgZulip,
|
||||
displayName: "Zulip",
|
||||
category: SourceCategory.Messaging,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/zulip`,
|
||||
},
|
||||
|
||||
// Sales
|
||||
salesforce: {
|
||||
icon: SvgSalesforce,
|
||||
displayName: "Salesforce",
|
||||
category: SourceCategory.Sales,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/salesforce`,
|
||||
isPopular: true,
|
||||
},
|
||||
hubspot: {
|
||||
icon: SvgHubSpot,
|
||||
displayName: "HubSpot",
|
||||
category: SourceCategory.Sales,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/hubspot`,
|
||||
isPopular: true,
|
||||
},
|
||||
gong: {
|
||||
icon: SvgGong,
|
||||
displayName: "Gong",
|
||||
category: SourceCategory.Sales,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/gong`,
|
||||
isPopular: true,
|
||||
},
|
||||
fireflies: {
|
||||
icon: SvgFireflies,
|
||||
displayName: "Fireflies",
|
||||
category: SourceCategory.Sales,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/fireflies`,
|
||||
},
|
||||
highspot: {
|
||||
icon: SvgHighspot,
|
||||
displayName: "Highspot",
|
||||
category: SourceCategory.Sales,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/highspot`,
|
||||
},
|
||||
loopio: {
|
||||
icon: SvgLoopio,
|
||||
displayName: "Loopio",
|
||||
category: SourceCategory.Sales,
|
||||
},
|
||||
|
||||
// Code Repository
|
||||
github: {
|
||||
icon: SvgGitHub,
|
||||
displayName: "GitHub",
|
||||
category: SourceCategory.CodeRepository,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/github`,
|
||||
isPopular: true,
|
||||
},
|
||||
gitlab: {
|
||||
icon: SvgGitLab,
|
||||
displayName: "GitLab",
|
||||
category: SourceCategory.CodeRepository,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/gitlab`,
|
||||
},
|
||||
bitbucket: {
|
||||
icon: SvgBitbucket,
|
||||
displayName: "Bitbucket",
|
||||
category: SourceCategory.CodeRepository,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/bitbucket`,
|
||||
},
|
||||
|
||||
// Others
|
||||
web: {
|
||||
icon: SvgGlobe,
|
||||
displayName: "Web",
|
||||
category: SourceCategory.Other,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/web`,
|
||||
isPopular: true,
|
||||
},
|
||||
file: {
|
||||
icon: SvgFileText,
|
||||
displayName: "File",
|
||||
category: SourceCategory.Other,
|
||||
docs: `${DOCS_ADMINS_PATH}/connectors/official/file`,
|
||||
isPopular: true,
|
||||
},
|
||||
user_file: {
|
||||
icon: SvgUploadCloud,
|
||||
displayName: "Uploaded Files",
|
||||
category: SourceCategory.Other,
|
||||
docs: `${DOCS_BASE_URL}/overview/core_features/chat#projects`,
|
||||
isPopular: false, // Needs to be false to hide from the Add Connector page
|
||||
},
|
||||
braintrust: {
|
||||
icon: BraintrustIcon,
|
||||
displayName: "Braintrust",
|
||||
category: SourceCategory.AiObservability,
|
||||
},
|
||||
|
||||
// Other
|
||||
ingestion_api: {
|
||||
icon: SvgGlobe,
|
||||
displayName: "Ingestion",
|
||||
category: SourceCategory.Other,
|
||||
},
|
||||
|
||||
// Craft-specific sources
|
||||
craft_file: {
|
||||
icon: SvgFileText,
|
||||
displayName: "Your Files",
|
||||
category: SourceCategory.Other,
|
||||
},
|
||||
|
||||
// Placeholder (non-null default)
|
||||
not_applicable: {
|
||||
icon: SvgGlobe,
|
||||
displayName: "Not Applicable",
|
||||
category: SourceCategory.Other,
|
||||
},
|
||||
mock_connector: {
|
||||
icon: SvgGlobe,
|
||||
displayName: "Mock Connector",
|
||||
category: SourceCategory.Other,
|
||||
},
|
||||
} as SourceMap;
|
||||
|
||||
function fillSourceMetadata(
|
||||
partialMetadata: PartialSourceMetadata,
|
||||
internalName: ValidSources
|
||||
): SourceMetadata {
|
||||
return {
|
||||
internalName: partialMetadata.baseSourceType || internalName,
|
||||
...partialMetadata,
|
||||
adminUrl: `/admin/connectors/${internalName}`,
|
||||
};
|
||||
}
|
||||
|
||||
export function getSourceMetadata(sourceType: ValidSources): SourceMetadata {
|
||||
const partialMetadata = SOURCE_METADATA_MAP[sourceType];
|
||||
|
||||
// Fallback to not_applicable if sourceType not found in map
|
||||
if (!partialMetadata) {
|
||||
return fillSourceMetadata(
|
||||
SOURCE_METADATA_MAP[ValidSources.NotApplicable],
|
||||
ValidSources.NotApplicable
|
||||
);
|
||||
}
|
||||
|
||||
return fillSourceMetadata(partialMetadata, sourceType);
|
||||
}
|
||||
|
||||
export function listSourceMetadata(): SourceMetadata[] {
|
||||
/* This gives back all the viewable / common sources, primarily for
|
||||
display in the Add Connector page */
|
||||
const entries = Object.entries(SOURCE_METADATA_MAP)
|
||||
.filter(
|
||||
([source, _]) =>
|
||||
source !== "not_applicable" &&
|
||||
source !== "ingestion_api" &&
|
||||
source !== "mock_connector" &&
|
||||
// use the "regular" slack connector when listing
|
||||
source !== "federated_slack" &&
|
||||
// user_file is for internal use (projects), not the Add Connector page
|
||||
source !== "user_file" &&
|
||||
// craft_file backs the Craft user library, which has its own upload UI
|
||||
source !== "craft_file" &&
|
||||
// TODO: unhide once the rest of the Zoom connector stack has merged
|
||||
source !== "zoom"
|
||||
)
|
||||
.map(([source, metadata]) => {
|
||||
return fillSourceMetadata(metadata, source as ValidSources);
|
||||
});
|
||||
return entries;
|
||||
}
|
||||
|
||||
export function getSourceDocLink(sourceType: ValidSources): string | null {
|
||||
return SOURCE_METADATA_MAP[sourceType].docs || null;
|
||||
}
|
||||
|
||||
export function isValidSource(sourceType: string): boolean {
|
||||
return Object.keys(SOURCE_METADATA_MAP).includes(sourceType);
|
||||
}
|
||||
|
||||
export function getSourceDisplayName(sourceType: ValidSources): string | null {
|
||||
return getSourceMetadata(sourceType).displayName;
|
||||
}
|
||||
|
||||
/** The configured sources, one entry per source type. */
|
||||
export function getConfiguredSources(
|
||||
availableSources: ValidSources[]
|
||||
): Array<SourceMetadata & { originalName: string; uniqueKey: string }> {
|
||||
const seen = new Set<string>();
|
||||
const result: Array<
|
||||
SourceMetadata & { originalName: string; uniqueKey: string }
|
||||
> = [];
|
||||
|
||||
for (const sourceName of availableSources) {
|
||||
const cleanName = sourceName.replace("federated_", "") as ValidSources;
|
||||
if (seen.has(cleanName)) continue;
|
||||
seen.add(cleanName);
|
||||
|
||||
const metadata = getSourceMetadata(cleanName);
|
||||
if (metadata.internalName === ValidSources.NotApplicable) continue;
|
||||
|
||||
result.push({
|
||||
...metadata,
|
||||
originalName: sourceName,
|
||||
uniqueKey: cleanName,
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { getConfiguredSources } from "@/lib/connectors/utils";
|
||||
import { createSharedHook } from "@opal/hooks";
|
||||
import { MinimalAgent } from "@/lib/agents/types";
|
||||
import { useAvailableSources } from "@/lib/connectors/hooks";
|
||||
@@ -9,7 +10,6 @@ import {
|
||||
effectiveAvailableSourcesFor,
|
||||
toggleSourceSelection,
|
||||
} from "@/lib/searchFilters/utils";
|
||||
import { getConfiguredSources } from "@/lib/sources";
|
||||
import type { ToolConfigurationHandle } from "@/lib/tools/hooks";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { renderHook, act } from "@testing-library/react";
|
||||
import {
|
||||
type SourceMetadata,
|
||||
ValidSources,
|
||||
} from "@/lib/connectors/types/source";
|
||||
import { useToolConfiguration } from "@/lib/tools/hooks";
|
||||
import {
|
||||
selectedSourcesFrom,
|
||||
@@ -6,8 +10,6 @@ import {
|
||||
toggleSourceSelection,
|
||||
normalizeSourceSelection,
|
||||
} from "@/lib/searchFilters/utils";
|
||||
import type { SourceMetadata } from "@/lib/search/types";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
|
||||
const CHAT_KEY = "onyx:tools:chat:abc";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { SOURCE_METADATA_MAP } from "@/lib/sources";
|
||||
import { MethodSpec, ToolSnapshot } from "@/lib/tools/types";
|
||||
import { SOURCE_METADATA_MAP } from "@/lib/connectors/constants";
|
||||
import {
|
||||
ADMIN_CONFIG_LINKS,
|
||||
OPENAPI_ADMIN_CONFIG,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { OnyxDocument } from "@/lib/search/types";
|
||||
import { getSourceDisplayName } from "@/lib/connectors/utils";
|
||||
import { SubQuestionDetail } from "@/app/app/interfaces";
|
||||
import { StreamingCitation } from "@/app/app/services/streamingModels";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import { getSourceDisplayName } from "@/lib/sources";
|
||||
import { SourceInfo } from "./SourceTagDetailsCard";
|
||||
|
||||
const MAX_TITLE_LENGTH = 40;
|
||||
|
||||
@@ -8,6 +8,7 @@ import React, {
|
||||
useRef,
|
||||
} from "react";
|
||||
import { useLocale, useTranslations } from "next-intl";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import * as GeneralLayouts from "@/layouts/general-layouts";
|
||||
import * as TableLayouts from "@/layouts/table-layouts";
|
||||
import {
|
||||
@@ -33,7 +34,6 @@ import {
|
||||
SvgArrowUpDown,
|
||||
SvgFilter,
|
||||
} from "@opal/icons";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import {
|
||||
HierarchyNodeSummary,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { memo } from "react";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import { useTranslations } from "next-intl";
|
||||
import * as GeneralLayouts from "@/layouts/general-layouts";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import type { ConnectedSource } from "@/lib/hierarchy/types";
|
||||
import type { ValidSources } from "@/lib/connectors/types/source";
|
||||
import { LineItemButton } from "@opal/components";
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
import React from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import * as GeneralLayouts from "@/layouts/general-layouts";
|
||||
import * as TableLayouts from "@/layouts/table-layouts";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import Truncated from "@/refresh-components/texts/Truncated";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import type {
|
||||
ConnectedSource,
|
||||
HierarchyNodeSearchSummary,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import * as TableLayouts from "@/layouts/table-layouts";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import type { ConnectedSource } from "@/lib/hierarchy/types";
|
||||
import type { ValidSources } from "@/lib/connectors/types/source";
|
||||
import { Divider, LineItemButton } from "@opal/components";
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
import React, { useMemo, useState } from "react";
|
||||
import { useLocale, useTranslations } from "next-intl";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import * as GeneralLayouts from "@/layouts/general-layouts";
|
||||
import * as TableLayouts from "@/layouts/table-layouts";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import { useSettings } from "@/lib/settings/hooks";
|
||||
import type { AgentAttachedDocument } from "@/lib/agents/types";
|
||||
import type { ProjectFile } from "@/lib/projects/types";
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
useRouter,
|
||||
useSearchParams,
|
||||
} from "next/navigation";
|
||||
import { SourceMetadata, ValidSources } from "@/lib/connectors/types/source";
|
||||
import { loginPath } from "@/lib/auth/paths";
|
||||
import { endIncognitoSession } from "@/app/app/services/lib";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
@@ -31,9 +32,7 @@ import { NoAgentModal } from "@/lib/agents/components";
|
||||
import PreviewModal from "@/sections/modals/PreviewModal";
|
||||
import { Modal } from "@opal/components";
|
||||
import { useSendMessageToParent } from "@/lib/extension/hooks";
|
||||
import { SourceMetadata } from "@/lib/search/types";
|
||||
import { FederatedConnectorDetail } from "@/lib/types";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import DocumentsSidebar from "@/sections/document-sidebar/DocumentsSidebar";
|
||||
import useChatController from "@/hooks/useChatController";
|
||||
import useMultiModelChat from "@/hooks/useMultiModelChat";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useRef, useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Section } from "@/layouts/general-layouts";
|
||||
@@ -23,7 +24,6 @@ import {
|
||||
SvgTrash,
|
||||
SvgUnplug,
|
||||
} from "@opal/icons";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import {
|
||||
Card,
|
||||
InputTextArea,
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
useTierAtLeast,
|
||||
useTierLockedOptions,
|
||||
} from "@/lib/tiers/hooks";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import { useAdminRouteTitle } from "@/lib/adminNavLabels";
|
||||
import { markdown } from "@opal/utils";
|
||||
import React, {
|
||||
@@ -57,7 +58,6 @@ import {
|
||||
} from "@opal/layouts";
|
||||
import { useSettings } from "@/lib/settings/hooks";
|
||||
import useCCPairs from "@/hooks/useCCPairs";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import { QueryHistoryType, Settings, toSettings } from "@/lib/settings/types";
|
||||
import { useAvailableTools } from "@/lib/tools/hooks";
|
||||
import {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useMemo } from "react";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { SvgEmpty, SvgFiles, SvgXOctagon } from "@opal/icons";
|
||||
import { Content } from "@opal/layouts";
|
||||
@@ -13,7 +14,6 @@ import AgentAvatar from "@/refresh-components/avatars/AgentAvatar";
|
||||
import { useConnectorStatus } from "@/lib/hooks";
|
||||
import { useDocumentSets } from "@/lib/hooks/useDocumentSets";
|
||||
import { useAdminAgents } from "@/lib/agents/hooks";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import type { Agent } from "@/lib/agents/types";
|
||||
import type { ValidSources } from "@/lib/connectors/types/source";
|
||||
import ResourceContent from "@/views/admin/GroupsPage/SharedGroupResources/ResourceContent";
|
||||
|
||||
+12
-14
@@ -7,6 +7,18 @@ import {
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import {
|
||||
getSourceDisplayName,
|
||||
getSourceDocLink,
|
||||
getSourceMetadata,
|
||||
isValidSource,
|
||||
connectorConfigFromForm,
|
||||
connectorFormControlFieldNames,
|
||||
createConnectorInitialValues,
|
||||
createConnectorValidationSchema,
|
||||
isLoadState,
|
||||
splitCredentialBoundFields,
|
||||
} from "@/lib/connectors/utils";
|
||||
import { Formik, type FormikErrors } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
@@ -27,12 +39,6 @@ import { SvgAlertCircle, SvgArrowExchange } from "@opal/icons";
|
||||
import { Disabled } from "@opal/core";
|
||||
import { usePermissionAuthority } from "@/lib/permissions/hooks";
|
||||
import { Permission } from "@/lib/types";
|
||||
import {
|
||||
getSourceDisplayName,
|
||||
getSourceDocLink,
|
||||
getSourceMetadata,
|
||||
isValidSource,
|
||||
} from "@/lib/sources";
|
||||
import { Logo } from "@/lib/app/components";
|
||||
import {
|
||||
createConnectorWithCredential,
|
||||
@@ -59,14 +65,6 @@ import {
|
||||
defaultRefreshFreqMinutes,
|
||||
useConnectorConfiguration,
|
||||
} from "@/lib/connectors/connectors";
|
||||
import {
|
||||
connectorConfigFromForm,
|
||||
connectorFormControlFieldNames,
|
||||
createConnectorInitialValues,
|
||||
createConnectorValidationSchema,
|
||||
isLoadState,
|
||||
splitCredentialBoundFields,
|
||||
} from "@/lib/connectors/utils";
|
||||
import type {
|
||||
ConnectionConfiguration,
|
||||
Connector,
|
||||
|
||||
+1
-1
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { getSourceMetadata } from "@/lib/connectors/utils";
|
||||
import { useFormatter, useTranslations } from "next-intl";
|
||||
import { Disabled } from "@opal/core";
|
||||
import {
|
||||
@@ -40,7 +41,6 @@ import {
|
||||
import { getCredentialDetails } from "@/lib/credentials/utils";
|
||||
import type { ConfigurableSources } from "@/lib/connectors/types/source";
|
||||
import { IconLoader } from "@opal/loaders";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import { useUser } from "@/providers/UserProvider";
|
||||
import { hasPermission } from "@/lib/permissions/utils";
|
||||
import { Permission } from "@/lib/types";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo, useRef } from "react";
|
||||
import { getSourceDisplayName } from "@/lib/connectors/utils";
|
||||
import { useField } from "formik";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { InputSingleSelect, type SelectOption } from "@opal/components";
|
||||
@@ -26,7 +27,6 @@ import type { CredentialValues } from "@/lib/credentials/types";
|
||||
import { getCredentialSpec } from "@/lib/credentials/utils";
|
||||
import { usePermissionAuthority } from "@/lib/permissions/hooks";
|
||||
import { useSettings } from "@/lib/settings/hooks";
|
||||
import { getSourceDisplayName } from "@/lib/sources";
|
||||
|
||||
function isValidAutoSyncSource(
|
||||
value: ConfigurableSources
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { FC, useEffect, useMemo } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getSourceDisplayName } from "@/lib/connectors/utils";
|
||||
import type {
|
||||
BooleanOption,
|
||||
TabOption,
|
||||
@@ -32,7 +33,6 @@ import InputTextAreaField from "@/refresh-components/form/InputTextAreaField";
|
||||
import InputTypeInField from "@/refresh-components/form/InputTypeInField";
|
||||
import FindingListField from "@/views/admin/connectors/AddConnectorPage/form/FindingListField";
|
||||
import type { StoredReportScope } from "@/lib/connectors/checks/findings";
|
||||
import { getSourceDisplayName } from "@/lib/sources";
|
||||
import { markdown } from "@opal/utils";
|
||||
|
||||
// Define a general type for form values
|
||||
|
||||
+1
-1
@@ -1,4 +1,5 @@
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getSourceDisplayName } from "@/lib/connectors/utils";
|
||||
import { Card, Collapsible } from "@opal/components";
|
||||
import { InputVertical, Section } from "@opal/layouts";
|
||||
import InputTypeInField from "@/refresh-components/form/InputTypeInField";
|
||||
@@ -6,7 +7,6 @@ import DocumentAccessField from "@/views/admin/connectors/AddConnectorPage/compo
|
||||
import ManageAccessField from "@/views/admin/connectors/AddConnectorPage/components/ManageAccessField";
|
||||
import type { ConfigurableSources } from "@/lib/connectors/types/source";
|
||||
import type { CredentialValues } from "@/lib/credentials/types";
|
||||
import { getSourceDisplayName } from "@/lib/sources";
|
||||
|
||||
interface ConnectorSettingsSectionProps {
|
||||
connector: ConfigurableSources;
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import type { Route } from "next";
|
||||
import { listSourceMetadata } from "@/lib/connectors/utils";
|
||||
import {
|
||||
SourceCategory,
|
||||
SourceMetadata,
|
||||
federatedSourceToRegularSource,
|
||||
} from "@/lib/connectors/types/source";
|
||||
import { useAdminRouteTitle } from "@/lib/adminNavLabels";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Content, SettingsLayouts } from "@opal/layouts";
|
||||
import * as GeneralLayouts from "@/layouts/general-layouts";
|
||||
import { SourceCategory, SourceMetadata } from "@/lib/search/types";
|
||||
import { listSourceMetadata } from "@/lib/sources";
|
||||
import {
|
||||
useCallback,
|
||||
useDeferredValue,
|
||||
@@ -19,7 +23,6 @@ import { InputTypeIn, Text } from "@opal/components";
|
||||
import { useGridNavigation, useHotkey } from "@opal/hooks";
|
||||
import { useFederatedConnectors } from "@/lib/connectors/hooks";
|
||||
import { FederatedConnectorDetail } from "@/lib/types";
|
||||
import { federatedSourceToRegularSource } from "@/lib/connectors/types/source";
|
||||
import { useSettings } from "@/lib/settings/hooks";
|
||||
import { ConnectorSourceCard } from "@/lib/connectors/components";
|
||||
import { ADMIN_ROUTES } from "@/lib/admin-routes";
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
import { useLocale, useTranslations } from "next-intl";
|
||||
import { getSourceDisplayName } from "@/lib/connectors/utils";
|
||||
import {
|
||||
Table,
|
||||
TableRow,
|
||||
@@ -29,7 +30,6 @@ import {
|
||||
} from "react-icons/fi";
|
||||
import { Tooltip } from "@opal/components";
|
||||
import { SourceIcon } from "@/components/SourceIcon";
|
||||
import { getSourceDisplayName } from "@/lib/sources";
|
||||
import { useTierAtLeast } from "@/lib/tiers/hooks";
|
||||
import { Tier } from "@/lib/tiers/types";
|
||||
import { ConnectorCredentialPairStatus } from "@/lib/connectors/types";
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { getSourceMetadata, isValidSource } from "@/lib/connectors/utils";
|
||||
import { usePathname, useSearchParams } from "next/navigation";
|
||||
import { AdminPageTitle } from "@/components/admin/Title";
|
||||
import { getSourceMetadata, isValidSource } from "@/lib/sources";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import CardSection from "@/components/admin/CardSection";
|
||||
import { handleOAuthAuthorizationResponse } from "@/lib/oauth_utils";
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { getSourceMetadata, isValidSource } from "@/lib/connectors/utils";
|
||||
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
||||
import { AdminPageTitle } from "@/components/admin/Title";
|
||||
import { Button } from "@opal/components";
|
||||
import { getSourceMetadata, isValidSource } from "@/lib/sources";
|
||||
import { ConfluenceAccessibleResource } from "@/lib/types";
|
||||
import { ValidSources } from "@/lib/connectors/types/source";
|
||||
import CardSection from "@/components/admin/CardSection";
|
||||
|
||||
Reference in new issue
Block a user