mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-11 03:12:55 +00:00
Name the services Connect your data can sync
The tile names up to three services this instance can sync (then "and more"), rather than services it may not offer, and spans the grid's width so its line doesn't wrap into a tall tile.
This commit is contained in:
1 parent
4468e19fb8
commit
6ccc506b8c
9 files changed
+68
-16
No files matched your search
@@ -1815,7 +1815,8 @@
|
||||
},
|
||||
"connectData": {
|
||||
"title": "Deine Daten verbinden",
|
||||
"description": "Google Drive, SharePoint, Confluence und mehr synchronisieren"
|
||||
"description": "{{services}} synchronisieren",
|
||||
"more": "mehr"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
|
||||
@@ -1821,7 +1821,8 @@
|
||||
},
|
||||
"connectData": {
|
||||
"title": "Connect your data",
|
||||
"description": "Sync Google Drive, SharePoint, Confluence and more"
|
||||
"description": "Sync {{services}}",
|
||||
"more": "more"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
|
||||
@@ -1815,7 +1815,8 @@
|
||||
},
|
||||
"connectData": {
|
||||
"title": "Conecta tus datos",
|
||||
"description": "Sincroniza Google Drive, SharePoint, Confluence y más"
|
||||
"description": "Sincroniza {{services}}",
|
||||
"more": "más"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
|
||||
@@ -1804,7 +1804,8 @@
|
||||
},
|
||||
"connectData": {
|
||||
"title": "データを接続",
|
||||
"description": "Google Drive、SharePoint、Confluence などを同期"
|
||||
"description": "{{services}} を同期",
|
||||
"more": "その他"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
|
||||
@@ -1899,7 +1899,8 @@
|
||||
},
|
||||
"connectData": {
|
||||
"title": "Подключите свои данные",
|
||||
"description": "Синхронизируйте Google Drive, SharePoint, Confluence и другие сервисы"
|
||||
"description": "Синхронизируйте {{services}}",
|
||||
"more": "другие сервисы"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
|
||||
@@ -1804,7 +1804,8 @@
|
||||
},
|
||||
"connectData": {
|
||||
"title": "連接你的資料",
|
||||
"description": "同步 Google Drive、SharePoint、Confluence 等"
|
||||
"description": "同步 {{services}}",
|
||||
"more": "更多服務"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
|
||||
@@ -1804,7 +1804,8 @@
|
||||
},
|
||||
"connectData": {
|
||||
"title": "连接你的数据",
|
||||
"description": "同步 Google Drive、SharePoint、Confluence 等"
|
||||
"description": "同步 {{services}}",
|
||||
"more": "更多服务"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
|
||||
@@ -2,7 +2,11 @@ import { act } from 'react';
|
||||
import { createRoot, type Root } from 'react-dom/client';
|
||||
|
||||
vi.mock('react-i18next', () => ({
|
||||
useTranslation: () => ({ t: (key: string) => key }),
|
||||
useTranslation: () => ({
|
||||
t: (key: string, opts?: { services?: string }) =>
|
||||
opts?.services ? `${key}(${opts.services})` : key,
|
||||
i18n: { language: 'en' },
|
||||
}),
|
||||
}));
|
||||
|
||||
const connectorsState = vi.hoisted(() => ({
|
||||
@@ -136,6 +140,7 @@ describe('Upload source-type tiles', () => {
|
||||
|
||||
const DRIVE = {
|
||||
key: 'google_drive',
|
||||
name: 'Google Drive',
|
||||
icon: 'drive',
|
||||
sync_ingestor: 'google_drive',
|
||||
capabilities: ['sync'],
|
||||
@@ -168,11 +173,30 @@ describe('Upload source-type tiles', () => {
|
||||
false,
|
||||
);
|
||||
expect(labels.at(-1)).toContain('modals.uploadDoc.connectData.title');
|
||||
expect(labels.at(-1)).toContain('modals.uploadDoc.connectData.description');
|
||||
// Named after what this instance can sync.
|
||||
expect(labels.at(-1)).toContain(
|
||||
'modals.uploadDoc.connectData.description(Google Drive)',
|
||||
);
|
||||
expect(document.body.querySelector('h3')).toBeNull();
|
||||
connectorsState.catalog = [];
|
||||
});
|
||||
|
||||
it('names three syncing services, then the rest as more', async () => {
|
||||
connectorsState.catalog = [
|
||||
DRIVE,
|
||||
{ ...DRIVE, key: 'share_point', name: 'SharePoint' },
|
||||
{ ...DRIVE, key: 'confluence', name: 'Confluence' },
|
||||
{ ...DRIVE, key: 's3', name: 'Amazon S3' },
|
||||
{ ...DRIVE, key: 'off', name: 'Needs setup', available: false },
|
||||
{ key: 'telegram', name: 'Telegram', capabilities: ['write'] },
|
||||
];
|
||||
await render();
|
||||
expect(connectTile()!.textContent).toContain(
|
||||
'modals.uploadDoc.connectData.description(Google Drive, SharePoint, Confluence, and modals.uploadDoc.connectData.more)',
|
||||
);
|
||||
connectorsState.catalog = [];
|
||||
});
|
||||
|
||||
it('opens the Connectors page on the syncing services', async () => {
|
||||
connectorsState.catalog = [DRIVE];
|
||||
navigate.mockClear();
|
||||
@@ -190,6 +214,7 @@ describe('Upload source-type tiles', () => {
|
||||
it('offers no Connect tile when no service can sync', async () => {
|
||||
connectorsState.catalog = [
|
||||
{ key: 'telegram', capabilities: ['write'], available: true },
|
||||
{ ...DRIVE, available: false },
|
||||
];
|
||||
await render();
|
||||
expect(connectTile()).toBeUndefined();
|
||||
|
||||
@@ -29,6 +29,8 @@ import { Separator } from '../components/ui/separator';
|
||||
import { OptionCard } from '../components/ui/option-card';
|
||||
import ConnectorSetupNotice from '../connectors/ConnectorSetupNotice';
|
||||
import useConnectorLauncher from '../connectors/useConnectorLauncher';
|
||||
import { connectorName } from '../connectors/i18n';
|
||||
import { intlLocale } from '../utils/dateTimeUtils';
|
||||
import {
|
||||
loadConnectors,
|
||||
selectConnections,
|
||||
@@ -474,7 +476,7 @@ function Upload({
|
||||
}));
|
||||
const [nameTouched, setNameTouched] = useState(false);
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { t, i18n } = useTranslation();
|
||||
const dispatch = useDispatch<AppDispatch>();
|
||||
const store = useStore<RootState>();
|
||||
|
||||
@@ -1152,10 +1154,27 @@ function Upload({
|
||||
};
|
||||
|
||||
// Services that sync into Knowledge are connected on the Connectors page,
|
||||
// so the picker offers one way there instead of a tile per service.
|
||||
const offersConnect =
|
||||
connectorsEnabled &&
|
||||
connectorCatalog.some((c) => c.capabilities?.includes('sync'));
|
||||
// so the picker offers one way there instead of a tile per service, named
|
||||
// after the first few this instance can sync.
|
||||
const syncServices = connectorsEnabled
|
||||
? connectorCatalog
|
||||
.filter((c) => c.available && c.capabilities?.includes('sync'))
|
||||
.map((c) => connectorName(t, c))
|
||||
: [];
|
||||
const SERVICES_NAMED = 3;
|
||||
const connectDescription = t('modals.uploadDoc.connectData.description', {
|
||||
services: new Intl.ListFormat(intlLocale(i18n.language), {
|
||||
type: 'conjunction',
|
||||
}).format(
|
||||
syncServices.length > SERVICES_NAMED
|
||||
? [
|
||||
...syncServices.slice(0, SERVICES_NAMED),
|
||||
t('modals.uploadDoc.connectData.more'),
|
||||
]
|
||||
: syncServices,
|
||||
),
|
||||
interpolation: { escapeValue: false },
|
||||
});
|
||||
|
||||
const renderIngestorSelection = () => {
|
||||
const options = UPLOAD_AND_WEB_INGESTORS.map((type) =>
|
||||
@@ -1173,11 +1192,12 @@ function Upload({
|
||||
onClick={() => handleIngestorTypeChange(option.value)}
|
||||
/>
|
||||
))}
|
||||
{offersConnect && (
|
||||
{syncServices.length > 0 && (
|
||||
<OptionCard
|
||||
className="sm:col-span-2 md:col-span-3"
|
||||
icon={<Plug />}
|
||||
title={t('modals.uploadDoc.connectData.title')}
|
||||
description={t('modals.uploadDoc.connectData.description')}
|
||||
description={connectDescription}
|
||||
onClick={() => {
|
||||
handleClose();
|
||||
navigate('/settings/connectors?capability=sync');
|
||||
|
||||
Reference in new issue
Block a user