Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f316902ea | ||
|
|
e552704201 | ||
|
|
ddedecbb36 | ||
|
|
5011e1d77b | ||
|
|
a07337fea0 | ||
|
|
6e36ad9fa2 | ||
|
|
5c745059ad | ||
|
|
6340b9e2f7 | ||
|
|
2c2f66b584 | ||
|
|
95a35f8a1d | ||
|
|
87c519b72f | ||
|
|
1b20bdaf6d | ||
|
|
67866ff59c | ||
|
|
e6f1bdd1c8 | ||
|
|
ba9aa41bba |
@@ -6302,6 +6302,10 @@
|
||||
"source": "/developers/extend/capabilities/apps",
|
||||
"destination": "/developers/extend/apps/getting-started"
|
||||
},
|
||||
{
|
||||
"source": "/developers/extend/mcp",
|
||||
"destination": "/user-guide/ai/capabilities/mcp"
|
||||
},
|
||||
{
|
||||
"source": "/developers/local-setup",
|
||||
"destination": "/developers/contribute/capabilities/local-setup"
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: خادم MCP},{
|
||||
description: اربط مساعدي الذكاء الاصطناعي بمساحة عمل Twenty الخاصة بك باستخدام بروتوكول سياق النموذج.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
MCP حاليًا في مرحلة **ألفا** وهو متاح فقط في بعض مساحات العمل. قد لا يكون مفعّلًا لمساحة عملك بعد.
|
||||
</Warning>
|
||||
|
||||
تعرض Twenty خادم [MCP](https://modelcontextprotocol.io/) بحيث تتمكّن مساعدات الذكاء الاصطناعي — Claude Desktop وClaude Code وCursor وChatGPT وغيرها — من قراءة وكتابة بيانات نظام إدارة علاقات العملاء (CRM) لديك باستخدام اللغة الطبيعية.
|
||||
|
||||
استخدم **عنوان URL لمساحة العمل** (عنوان URL الذي تستخدمه للوصول إلى Twenty) كنقطة نهاية MCP. على Twenty Cloud، قد يكون عنوان URL لمساحة العمل هو `https://{mycompany}.twenty.com` أو نطاق مخصص. الخادم متاح على:
|
||||
|
||||
| البيئة | نقطة نهاية MCP |
|
||||
| --------------------- | ---------------------------------------------------------------------------------------- |
|
||||
| **السحابة** | `https://{your-workspace-url}/mcp` (على سبيل المثال: `https://mycompany.twenty.com/mcp`) |
|
||||
| **الاستضافة الذاتية** | `https://{your-domain}/mcp` |
|
||||
|
||||
## طرق المصادقة
|
||||
|
||||
لديك طريقتان لمصادقة عميل MCP: **OAuth** (مُوصى بها) أو **مفتاح API**.
|
||||
|
||||
### الخيار أ — OAuth (مُوصى به)
|
||||
|
||||
باستخدام OAuth، يفتح عميل MCP لديك نافذة متصفح لتسجيل الدخول. لا يتم تخزين أي أسرار في ملفات الإعداد، ويتم تحديث الرموز المميِّزة تلقائيًا.
|
||||
|
||||
<Note>
|
||||
يتطلب OAuth عميل MCP يدعم [مواصفة تفويض MCP](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization). تدعمه Claude Desktop وClaude Code وCursor وChatGPT.
|
||||
</Note>
|
||||
|
||||
أضِف ما يلي إلى تهيئة عميل MCP لديك، واستبدِل `{your-workspace-url}` بمضيف مساحة العمل لديك (على سبيل المثال: `mycompany.twenty.com`):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
هذا كل شيء — لا حاجة إلى مفتاح API. عند اتصال العميل للمرة الأولى، سيفعل ما يلي:
|
||||
|
||||
1. اكتشاف بيانات التعريف الخاصة بـ OAuth لدى Twenty عبر `/.well-known/oauth-protected-resource` و`/.well-known/oauth-authorization-server`
|
||||
2. تسجيل نفسه كعميل OAuth عبر التسجيل الديناميكي للعميل (RFC 7591)
|
||||
3. فتح متصفحك لتفويض الوصول
|
||||
4. استلام الرموز المميِّزة والاتصال بخادم MCP
|
||||
|
||||
تعيد الاتصالات اللاحقة استخدام الرموز المميِّزة المخزنة وتحدِّثها تلقائيًا.
|
||||
|
||||
### الخيار ب — مفتاح API
|
||||
|
||||
إذا كان عميل MCP لديك لا يدعم OAuth، أو كنت تفضّل بيانات اعتماد ثابتة، فمرِّر مفتاح API في ترويسة `Authorization`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Warning>
|
||||
يمنح مفتاح API الخاص بك حق الوصول إلى بيانات مساحة العمل. أبعِده عن أنظمة التحكم في الإصدارات وملفات dotfiles المشتركة.
|
||||
</Warning>
|
||||
|
||||
لإنشاء مفتاح API، انتقل إلى **Settings > APIs & Webhooks > + Create key**. راجع [واجهات برمجة التطبيقات](/l/ar/developers/extend/api#create-an-api-key) للتفاصيل.
|
||||
|
||||
## البدء السريع
|
||||
|
||||
### 1. انسخ الإعداد
|
||||
|
||||
انتقل إلى **Settings > AI > More > MCP Server** في Twenty. اختر طريقة المصادقة (OAuth أو مفتاح API)، وانسخ مقطع JSON (سيستخدم بالفعل عنوان URL لمساحة العمل لديك)، ثم الصقه في ملف إعدادات عميل MCP لديك.
|
||||
|
||||
| العميل | موقع ملف الإعداد |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) أو `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
|
||||
| **Claude Code** | `~/.claude.json` (المستخدم) أو `.mcp.json` (المشروع) |
|
||||
| **Cursor** | `.cursor/mcp.json` ضمن مشروعك، أو `~/.cursor/mcp.json` عالميًا |
|
||||
| **ChatGPT** | فعِّل وضع المطوّر في **Settings > Apps & Connectors > Advanced settings**، ثم استخدم **Create** في **Settings > Apps & Connectors** لإضافة خادم MCP |
|
||||
|
||||
### ٢. الاتصال
|
||||
|
||||
أعِد تشغيل عميل MCP لديك (أو أعد تحميل ملف الإعداد). إذا كنت تستخدم OAuth فسيتم توجيهك إلى Twenty لتفويض الوصول. إذا كنت تستخدم مفتاح API فسيكون الاتصال فوريًا.
|
||||
|
||||
### ٣. ابدأ باستخدامه
|
||||
|
||||
اطلب من مساعد الذكاء الاصطناعي التفاعل مع نظام إدارة علاقات العملاء (CRM) لديك:
|
||||
|
||||
* *"أرني أحدث 5 شركات تم إنشاؤها"*
|
||||
* *"أنشئ شخصًا جديدًا باسم Jane Doe في Acme Corp"*
|
||||
* *"اعثر على جميع الفرص المفتوحة التي تزيد قيمتها عن 10 آلاف دولار"*
|
||||
|
||||
## الأدوات المتاحة
|
||||
|
||||
بعد الاتصال، يوفّر خادم MCP أدوات تعكس واجهة برمجة تطبيقات Twenty (API). سير العمل الموصى به هو:
|
||||
|
||||
1. **`get_tool_catalog`** — اكتشف جميع الأدوات المتاحة
|
||||
2. **`learn_tools`** — احصل على مخطط الإدخال لأدوات محددة
|
||||
3. **`execute_tool`** — شغّل أداة
|
||||
|
||||
لا تحتاج إلى تذكّر أسماء الأدوات. اسأل مساعد الذكاء الاصطناعي عمّا يمكنه فعله وسيستدعي `get_tool_catalog` تلقائيًا.
|
||||
|
||||
## الصلاحيات
|
||||
|
||||
ترث اتصالات MCP أذونات المستخدم المُصادَق عليه (OAuth) أو الدور المُعيَّن لمفتاح API. لتقييد ما يمكن لخادم MCP القيام به:
|
||||
|
||||
* **OAuth**: ينطبق دور المستخدم في مساحة العمل.
|
||||
* **API Key**: عيِّن دورًا لمفتاح API ضمن **Settings > Roles**. راجع [الأذونات](/l/ar/user-guide/permissions-access/capabilities/permissions).
|
||||
|
||||
## التكوين ذاتي الاستضافة
|
||||
|
||||
في حالات الاستضافة الذاتية، استبدِل `{your-workspace-url}` بعنوان URL الخاص بالخادم لديك. تأكّد من أن قيمة `SERVER_URL` في بيئتك تطابق عنوان URL العام لمثيل Twenty لديك — إذ يُستخدَم ذلك لإنشاء بيانات تعريف اكتشاف OAuth.
|
||||
|
||||
```bash
|
||||
SERVER_URL=https://twenty.yourcompany.com
|
||||
```
|
||||
|
||||
تُشتق نقطة نهاية MCP ونقاط نهاية OAuth وبيانات تعريف الاكتشاف جميعها من هذه القيمة.
|
||||
|
||||
## استكشاف الأخطاء وإصلاحها
|
||||
|
||||
**أخطاء "Unauthorized" أو 401**
|
||||
|
||||
* OAuth: أعد التفويض عبر مسح الرموز المميِّزة المخزنة في عميل MCP لديك ثم أعد الاتصال.
|
||||
* API Key: تحقّق من أن المفتاح صالح ولم تنتهِ صلاحيته. أعِد توليده إذا لزم الأمر.
|
||||
|
||||
**عملية OAuth لا تفتح متصفحًا**
|
||||
|
||||
* تأكّد من أن عميل MCP لديك يدعم تفويض MCP. ارجع إلى طريقة مفتاح API إذا لم يكن كذلك.
|
||||
|
||||
**انتهاء مهلة الاتصال**
|
||||
|
||||
* تحقّق من إمكانية الوصول إلى عنوان URL لنقطة نهاية MCP من جهازك. بالنسبة لحالات الاستضافة الذاتية، تحقّق من أن الخادم يعمل وأن `SERVER_URL` مُعيَّن بشكل صحيح.
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: MCP-Server
|
||||
description: Verbinden Sie KI-Assistenten mit Ihrem Twenty-Workspace über das Model Context Protocol.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
MCP befindet sich derzeit in **alpha** und ist nur in einigen Workspaces verfügbar. Möglicherweise ist es für Ihren Workspace noch nicht aktiviert.
|
||||
</Warning>
|
||||
|
||||
Twenty stellt einen [MCP](https://modelcontextprotocol.io/)-Server bereit, damit KI-Assistenten — Claude Desktop, Claude Code, Cursor, ChatGPT und andere — Ihre CRM-Daten in natürlicher Sprache lesen und schreiben können.
|
||||
|
||||
Verwenden Sie Ihre **Workspace-URL** (die URL, mit der Sie auf Twenty zugreifen) als MCP-Endpunkt. In Twenty Cloud kann Ihre Workspace-URL `https://{mycompany}.twenty.com` oder eine benutzerdefinierte Domain sein. Der Server ist verfügbar unter:
|
||||
|
||||
| Umgebung | MCP-Endpunkt |
|
||||
| ----------------- | ----------------------------------------------------------------------------- |
|
||||
| **Cloud** | `https://{your-workspace-url}/mcp` (z. B. `https://mycompany.twenty.com/mcp`) |
|
||||
| **Selbsthosting** | `https://{your-domain}/mcp` |
|
||||
|
||||
## Authentifizierungsmethoden
|
||||
|
||||
Sie haben zwei Möglichkeiten, Ihren MCP-Client zu authentifizieren: **OAuth** (empfohlen) oder **API-Schlüssel**.
|
||||
|
||||
### Option A — OAuth (empfohlen)
|
||||
|
||||
Mit OAuth öffnet Ihr MCP-Client ein Browserfenster, damit Sie sich anmelden können. Es werden keine geheimen Informationen in Konfigurationsdateien gespeichert, und Token werden automatisch erneuert.
|
||||
|
||||
<Note>
|
||||
OAuth erfordert einen MCP-Client, der die [MCP-Autorisierungsspezifikation](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization) unterstützt. Claude Desktop, Claude Code, Cursor und ChatGPT unterstützen dies.
|
||||
</Note>
|
||||
|
||||
Fügen Sie dies zu Ihrer MCP-Client-Konfiguration hinzu und ersetzen Sie `{your-workspace-url}` durch den Host Ihrer Workspace-URL (z. B. `mycompany.twenty.com`):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Das ist alles — kein API-Schlüssel erforderlich. Wenn der Client sich zum ersten Mal verbindet, wird er:
|
||||
|
||||
1. Die OAuth-Metadaten von Twenty über `/.well-known/oauth-protected-resource` und `/.well-known/oauth-authorization-server` ermitteln
|
||||
2. Sich über die dynamische Client-Registrierung (RFC 7591) als OAuth-Client registrieren
|
||||
3. Ihren Browser öffnen, um den Zugriff zu autorisieren
|
||||
4. Token empfangen und eine Verbindung zum MCP-Server herstellen
|
||||
|
||||
Nachfolgende Verbindungen verwenden die gespeicherten Token erneut und erneuern sie automatisch.
|
||||
|
||||
### Option B — API-Schlüssel
|
||||
|
||||
Wenn Ihr MCP-Client OAuth nicht unterstützt oder Sie statische Anmeldeinformationen bevorzugen, übergeben Sie einen API-Schlüssel im `Authorization`-Header:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Ihr API-Schlüssel gewährt Zugriff auf Workspace-Daten. Halten Sie es von der Versionskontrolle und von gemeinsam genutzten Dotfiles fern.
|
||||
</Warning>
|
||||
|
||||
Um einen API-Schlüssel zu erstellen, gehen Sie zu **Settings > APIs & Webhooks > + Create key**. Details finden Sie unter [APIs](/l/de/developers/extend/api#create-an-api-key).
|
||||
|
||||
## Schnellstart
|
||||
|
||||
### 1. Konfiguration kopieren
|
||||
|
||||
Gehen Sie in Twenty zu **Settings > AI > More > MCP Server**. Wählen Sie Ihre Authentifizierungsmethode (OAuth oder API-Schlüssel), kopieren Sie das JSON-Snippet (es verwendet bereits Ihre Workspace-URL) und fügen Sie es in die Konfigurationsdatei Ihres MCP-Clients ein.
|
||||
|
||||
| Client | Speicherort der Konfigurationsdatei |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) oder `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
|
||||
| **Claude Code** | `~/.claude.json` (Benutzer) oder `.mcp.json` (Projekt) |
|
||||
| **Cursor** | `.cursor/mcp.json` in Ihrem Projekt oder `~/.cursor/mcp.json` global |
|
||||
| **ChatGPT** | Aktivieren Sie den Entwicklermodus in **Settings > Apps & Connectors > Advanced settings** und verwenden Sie dann **Create** in **Settings > Apps & Connectors**, um den MCP-Server hinzuzufügen |
|
||||
|
||||
### 2. Verbinden
|
||||
|
||||
Starten Sie Ihren MCP-Client neu (oder laden Sie die Konfiguration neu). Bei Verwendung von OAuth werden Sie zu Twenty weitergeleitet, um den Zugriff zu autorisieren. Bei Verwendung eines API-Schlüssels wird die Verbindung sofort hergestellt.
|
||||
|
||||
### 3. Jetzt loslegen
|
||||
|
||||
Bitten Sie Ihren KI-Assistenten, mit Ihrem CRM zu interagieren:
|
||||
|
||||
* *"Zeige mir die 5 zuletzt erstellten Unternehmen"*
|
||||
* *"Erstelle eine neue Person namens Jane Doe bei Acme Corp"*
|
||||
* *"Finde alle offenen Verkaufschancen mit einem Wert von mehr als $10k"*
|
||||
|
||||
## Verfügbare Tools
|
||||
|
||||
Nach der Verbindung stellt der MCP-Server Tools bereit, die die Twenty-API widerspiegeln. Der empfohlene Workflow ist:
|
||||
|
||||
1. **`get_tool_catalog`** — alle verfügbaren Tools entdecken
|
||||
2. **`learn_tools`** — das Eingabeschema für bestimmte Tools abrufen
|
||||
3. **`execute_tool`** — ein Tool ausführen
|
||||
|
||||
Sie müssen sich die Tool-Namen nicht merken. Fragen Sie Ihren KI-Assistenten, was er tun kann, und er ruft `get_tool_catalog` automatisch auf.
|
||||
|
||||
## Berechtigungen
|
||||
|
||||
MCP-Verbindungen erben die Berechtigungen des authentifizierten Benutzers (OAuth) oder die dem API-Schlüssel zugewiesene Rolle. So beschränken Sie, was der MCP-Server tun darf:
|
||||
|
||||
* **OAuth**: Es gilt die Workspace-Rolle des Benutzers.
|
||||
* **API-Schlüssel**: Weisen Sie dem API-Schlüssel unter **Settings > Roles** eine Rolle zu. Siehe [Berechtigungen](/l/de/user-guide/permissions-access/capabilities/permissions).
|
||||
|
||||
## Selbstgehostete Konfiguration
|
||||
|
||||
Für selbstgehostete Instanzen ersetzen Sie `{your-workspace-url}` durch die URL Ihres Servers. Stellen Sie sicher, dass `SERVER_URL` in Ihrer Umgebung der öffentlichen URL Ihrer Twenty-Instanz entspricht — dieser Wert wird verwendet, um die OAuth-Discovery-Metadaten zu generieren.
|
||||
|
||||
```bash
|
||||
SERVER_URL=https://twenty.yourcompany.com
|
||||
```
|
||||
|
||||
Der MCP-Endpunkt, die OAuth-Endpunkte und die Discovery-Metadaten leiten sich alle von diesem Wert ab.
|
||||
|
||||
## Fehlerbehebung
|
||||
|
||||
**"Unauthorized"- oder 401-Fehler**
|
||||
|
||||
* OAuth: Autorisieren Sie erneut, indem Sie die gespeicherten Token in Ihrem MCP-Client löschen und die Verbindung wiederherstellen.
|
||||
* API-Schlüssel: Überprüfen Sie, ob der Schlüssel gültig ist und nicht abgelaufen ist. Generieren Sie ihn bei Bedarf neu.
|
||||
|
||||
**Der OAuth-Flow öffnet keinen Browser**
|
||||
|
||||
* Stellen Sie sicher, dass Ihr MCP-Client MCP Authorization unterstützt. Wechseln Sie andernfalls zur API-Schlüssel-Methode.
|
||||
|
||||
**Verbindungszeitüberschreitung**
|
||||
|
||||
* Stellen Sie sicher, dass die MCP-Endpunkt-URL von Ihrem Rechner aus erreichbar ist. Bei selbstgehosteten Instanzen prüfen Sie, ob der Server läuft und `SERVER_URL` korrekt gesetzt ist.
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: Server MCP
|
||||
description: Collega gli assistenti AI al tuo spazio di lavoro di Twenty utilizzando il Model Context Protocol.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
MCP è attualmente in **alpha** ed è disponibile solo su alcuni spazi di lavoro. Potrebbe non essere ancora abilitato per il tuo spazio di lavoro.
|
||||
</Warning>
|
||||
|
||||
Twenty espone un server [MCP](https://modelcontextprotocol.io/) affinché gli assistenti AI — Claude Desktop, Claude Code, Cursor, ChatGPT e altri — possano leggere e scrivere i dati del tuo CRM in linguaggio naturale.
|
||||
|
||||
Usa l'**URL dello spazio di lavoro** (l'URL che usi per accedere a Twenty) come endpoint MCP. Su Twenty Cloud, l'URL del tuo spazio di lavoro potrebbe essere `https://{mycompany}.twenty.com` oppure un dominio personalizzato. Il server è disponibile all'indirizzo:
|
||||
|
||||
| Ambiente | Endpoint MCP |
|
||||
| ----------------- | ------------------------------------------------------------------------------ |
|
||||
| **Cloud** | `https://{your-workspace-url}/mcp` (ad es. `https://mycompany.twenty.com/mcp`) |
|
||||
| **Auto-ospitato** | `https://{your-domain}/mcp` |
|
||||
|
||||
## Metodi di autenticazione
|
||||
|
||||
Hai due modi per autenticare il tuo client MCP: **OAuth** (consigliato) o **API Key**.
|
||||
|
||||
### Opzione A — OAuth (Consigliato)
|
||||
|
||||
Con OAuth, il tuo client MCP apre una finestra del browser per effettuare l'accesso. Nessun segreto viene archiviato nei file di configurazione e i token si rinnovano automaticamente.
|
||||
|
||||
<Note>
|
||||
OAuth richiede un client MCP che supporti la [specifica MCP Authorization](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization). Claude Desktop, Claude Code, Cursor e ChatGPT lo supportano.
|
||||
</Note>
|
||||
|
||||
Aggiungi questo alla configurazione del tuo client MCP, sostituendo `{your-workspace-url}` con l'host del tuo spazio di lavoro (ad es. `mycompany.twenty.com`):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
È tutto — non è necessaria alcuna chiave API. Quando il client si connette per la prima volta, eseguirà:
|
||||
|
||||
1. Scoprire i metadati OAuth di Twenty tramite `/.well-known/oauth-protected-resource` e `/.well-known/oauth-authorization-server`
|
||||
2. Registrarsi come client OAuth tramite registrazione dinamica del client (RFC 7591)
|
||||
3. Aprire il browser per autorizzare l'accesso
|
||||
4. Ricevere i token e connettersi al server MCP
|
||||
|
||||
Le connessioni successive riutilizzano i token memorizzati e li rinnovano automaticamente.
|
||||
|
||||
### Opzione B — Chiave API
|
||||
|
||||
Se il tuo client MCP non supporta OAuth, o preferisci credenziali statiche, passa una chiave API nell'header `Authorization`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Warning>
|
||||
La tua chiave API concede l'accesso ai dati dello spazio di lavoro. Mantienila fuori dal controllo versione e dai dotfile condivisi.
|
||||
</Warning>
|
||||
|
||||
Per creare una chiave API, vai su **Impostazioni > API e Webhook > + Crea chiave**. Vedi [API](/l/it/developers/extend/api#create-an-api-key) per i dettagli.
|
||||
|
||||
## Avvio rapido
|
||||
|
||||
### 1. Copia la configurazione
|
||||
|
||||
Vai su **Impostazioni > AI > Altro > MCP Server** in Twenty. Scegli il metodo di autenticazione (OAuth o Chiave API), copia lo snippet JSON (userà già l'URL del tuo spazio di lavoro) e incollalo nel file di configurazione del tuo client MCP.
|
||||
|
||||
| Client | Percorso del file di configurazione |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) o `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
|
||||
| **Claude Code** | `~/.claude.json` (utente) o `.mcp.json` (progetto) |
|
||||
| **Cursor** | `.cursor/mcp.json` nel tuo progetto, oppure `~/.cursor/mcp.json` globalmente |
|
||||
| **ChatGPT** | Attiva la Modalità sviluppatore in **Impostazioni > App e Connettori > Impostazioni avanzate**, quindi usa **Crea** in **Impostazioni > App e Connettori** per aggiungere il server MCP |
|
||||
|
||||
### 2. Connetti
|
||||
|
||||
Riavvia il tuo client MCP (o ricarica la configurazione). Se usi OAuth verrai reindirizzato a Twenty per autorizzare l'accesso. Se usi una chiave API la connessione è immediata.
|
||||
|
||||
### 3. Inizia a usarlo
|
||||
|
||||
Chiedi al tuo assistente AI di interagire con il tuo CRM:
|
||||
|
||||
* *"Mostrami le 5 aziende create più di recente"*
|
||||
* *"Crea una nuova persona di nome Jane Doe presso Acme Corp"*
|
||||
* *"Trova tutte le opportunità aperte di valore superiore a $10k"*
|
||||
|
||||
## Strumenti disponibili
|
||||
|
||||
Una volta connesso, il server MCP espone strumenti che rispecchiano l'API di Twenty. Il flusso di lavoro consigliato è:
|
||||
|
||||
1. **`get_tool_catalog`** — scoprire tutti gli strumenti disponibili
|
||||
2. **`learn_tools`** — ottenere lo schema di input per strumenti specifici
|
||||
3. **`execute_tool`** — eseguire uno strumento
|
||||
|
||||
Non è necessario ricordare i nomi degli strumenti. Chiedi al tuo assistente AI cosa può fare e chiamerà `get_tool_catalog` automaticamente.
|
||||
|
||||
## Permessi
|
||||
|
||||
Le connessioni MCP ereditano le autorizzazioni dell'utente autenticato (OAuth) o il ruolo assegnato alla chiave API. Per limitare ciò che il server MCP può fare:
|
||||
|
||||
* **OAuth**: si applica il ruolo dell'utente nello spazio di lavoro.
|
||||
* **Chiave API**: assegna un ruolo alla chiave API in **Impostazioni > Ruoli**. Vedi [Autorizzazioni](/l/it/user-guide/permissions-access/capabilities/permissions).
|
||||
|
||||
## Configurazione self-hosted
|
||||
|
||||
Per le istanze self-hosted, sostituisci `{your-workspace-url}` con l'URL del tuo server. Assicurati che `SERVER_URL` nel tuo ambiente corrisponda all'URL pubblico della tua istanza Twenty — viene utilizzato per generare i metadati di discovery OAuth.
|
||||
|
||||
```bash
|
||||
SERVER_URL=https://twenty.yourcompany.com
|
||||
```
|
||||
|
||||
L'endpoint MCP, gli endpoint OAuth e i metadati di discovery derivano tutti da questo valore.
|
||||
|
||||
## Risoluzione dei problemi
|
||||
|
||||
**Errori "Unauthorized" o 401**
|
||||
|
||||
* OAuth: esegui nuovamente l'autorizzazione eliminando i token memorizzati nel tuo client MCP e riconnettiti.
|
||||
* Chiave API: verifica che la chiave sia valida e non sia scaduta. Rigenerala se necessario.
|
||||
|
||||
**Il flusso OAuth non apre il browser**
|
||||
|
||||
* Assicurati che il tuo client MCP supporti MCP Authorization. In caso contrario, ricorri al metodo con Chiave API.
|
||||
|
||||
**Timeout di connessione**
|
||||
|
||||
* Verifica che l'URL dell'endpoint MCP sia raggiungibile dalla tua macchina. Per le istanze self-hosted, controlla che il server sia in esecuzione e che `SERVER_URL` sia impostato correttamente.
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: Servidor MCP
|
||||
description: Conecte assistentes de IA ao seu espaço de trabalho do Twenty usando o Model Context Protocol.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
O MCP está atualmente em **alfa** e está disponível apenas em alguns espaços de trabalho. O MCP pode ainda não estar ativado no seu espaço de trabalho.
|
||||
</Warning>
|
||||
|
||||
O Twenty expõe um servidor [MCP](https://modelcontextprotocol.io/) para que assistentes de IA — Claude Desktop, Claude Code, Cursor, ChatGPT e outros — possam ler e escrever seus dados de CRM por meio de linguagem natural.
|
||||
|
||||
Use o **URL do espaço de trabalho** (o URL que você usa para acessar o Twenty) como o endpoint do MCP. Na Twenty Cloud, o URL do seu espaço de trabalho pode ser `https://{mycompany}.twenty.com` ou um domínio personalizado. O servidor está disponível em:
|
||||
|
||||
| Ambiente | Endpoint do MCP |
|
||||
| ------------------ | ------------------------------------------------------------------------------------ |
|
||||
| **Nuvem** | `https://{your-workspace-url}/mcp` (por exemplo, `https://mycompany.twenty.com/mcp`) |
|
||||
| **Auto-hospedado** | `https://{your-domain}/mcp` |
|
||||
|
||||
## Métodos de autenticação
|
||||
|
||||
Você tem duas maneiras de autenticar seu cliente MCP: **OAuth** (recomendado) ou **Chave de API**.
|
||||
|
||||
### Opção A — OAuth (recomendado)
|
||||
|
||||
Com o OAuth, seu cliente MCP abre uma janela do navegador para você fazer login. Nenhum segredo é armazenado em arquivos de configuração, e os tokens são atualizados automaticamente.
|
||||
|
||||
<Note>
|
||||
O OAuth requer um cliente MCP que ofereça suporte à [especificação de Autorização MCP](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization). Claude Desktop, Claude Code, Cursor e ChatGPT oferecem suporte.
|
||||
</Note>
|
||||
|
||||
Adicione isto à configuração do seu cliente MCP, substituindo `{your-workspace-url}` pelo host do seu espaço de trabalho (por exemplo, `mycompany.twenty.com`):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
É isso — nenhuma chave de API é necessária. Quando o cliente se conectar pela primeira vez, ele irá:
|
||||
|
||||
1. Descobrir os metadados de OAuth do Twenty por meio de `/.well-known/oauth-protected-resource` e `/.well-known/oauth-authorization-server`
|
||||
2. Registrar-se como um cliente OAuth por meio de registro dinâmico de cliente (RFC 7591)
|
||||
3. Abrir seu navegador para autorizar o acesso
|
||||
4. Receber tokens e conectar-se ao servidor MCP
|
||||
|
||||
Conexões subsequentes reutilizam os tokens armazenados e os atualizam automaticamente.
|
||||
|
||||
### Opção B — Chave de API
|
||||
|
||||
Se o seu cliente MCP não oferecer suporte a OAuth, ou se você preferir credenciais estáticas, passe uma chave de API no cabeçalho `Authorization`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Sua chave de API concede acesso aos dados do espaço de trabalho. Mantenha-a fora do controle de versão e de dotfiles compartilhados.
|
||||
</Warning>
|
||||
|
||||
Para criar uma chave de API, vá em **Settings > APIs & Webhooks > + Create key**. Veja [APIs](/l/pt/developers/extend/api#create-an-api-key) para detalhes.
|
||||
|
||||
## Início rápido
|
||||
|
||||
### 1. Copie a configuração
|
||||
|
||||
Vá até **Settings > AI > More > MCP Server** no Twenty. Escolha seu método de autenticação (OAuth ou Chave de API), copie o trecho de JSON (ele já usará o URL do seu espaço de trabalho) e cole-o no arquivo de configuração do seu cliente MCP.
|
||||
|
||||
| Cliente | Local do arquivo de configuração |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) ou `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
|
||||
| **Claude Code** | `~/.claude.json` (usuário) ou `.mcp.json` (projeto) |
|
||||
| **Cursor** | `.cursor/mcp.json` no seu projeto, ou `~/.cursor/mcp.json` globalmente |
|
||||
| **ChatGPT** | Ative o Modo Desenvolvedor em **Settings > Apps & Connectors > Advanced settings** e, em seguida, use **Create** em **Settings > Apps & Connectors** para adicionar o servidor MCP |
|
||||
|
||||
### 2. Conectar
|
||||
|
||||
Reinicie seu cliente MCP (ou recarregue a configuração). Se estiver usando OAuth, você será redirecionado ao Twenty para autorizar o acesso. Se estiver usando uma chave de API, a conexão é imediata.
|
||||
|
||||
### 3. Comece a usá-lo
|
||||
|
||||
Peça ao seu assistente de IA para interagir com seu CRM:
|
||||
|
||||
* *"Mostre-me as 5 empresas criadas mais recentemente"*
|
||||
* *"Crie uma nova pessoa chamada Jane Doe na Acme Corp"*
|
||||
* *"Encontre todas as oportunidades em aberto com valor superior a $10k"*
|
||||
|
||||
## Ferramentas disponíveis
|
||||
|
||||
Depois de conectado, o servidor MCP expõe ferramentas que refletem a API do Twenty. O fluxo de trabalho recomendado é:
|
||||
|
||||
1. **`get_tool_catalog`** — descobrir todas as ferramentas disponíveis
|
||||
2. **`learn_tools`** — obter o esquema de entrada para ferramentas específicas
|
||||
3. **`execute_tool`** — executar uma ferramenta
|
||||
|
||||
Você não precisa se lembrar dos nomes das ferramentas. Pergunte ao seu assistente de IA o que ele pode fazer e ele chamará `get_tool_catalog` automaticamente.
|
||||
|
||||
## Permissões
|
||||
|
||||
As conexões MCP herdam as permissões do usuário autenticado (OAuth) ou da função atribuída à chave de API. Para restringir o que o servidor MCP pode fazer:
|
||||
|
||||
* **OAuth**: Aplica-se à função do espaço de trabalho do usuário.
|
||||
* **Chave de API**: Atribua uma função à chave de API em **Settings > Roles**. Veja [Permissões](/l/pt/user-guide/permissions-access/capabilities/permissions).
|
||||
|
||||
## Configuração auto-hospedada
|
||||
|
||||
Para instâncias auto-hospedadas, substitua `{your-workspace-url}` pelo URL do seu servidor. Certifique-se de que `SERVER_URL` no seu ambiente corresponda ao URL público da sua instância do Twenty — isso é usado para gerar os metadados de descoberta do OAuth.
|
||||
|
||||
```bash
|
||||
SERVER_URL=https://twenty.yourcompany.com
|
||||
```
|
||||
|
||||
O endpoint do MCP, os endpoints de OAuth e os metadados de descoberta derivam todos desse valor.
|
||||
|
||||
## Resolução de Problemas
|
||||
|
||||
**Erros "Unauthorized" ou 401**
|
||||
|
||||
* OAuth: autorize novamente limpando os tokens armazenados no seu cliente MCP e reconectando.
|
||||
* Chave de API: verifique se a chave é válida e não expirou. Gere-a novamente, se necessário.
|
||||
|
||||
**O fluxo do OAuth não abre um navegador**
|
||||
|
||||
* Garanta que seu cliente MCP ofereça suporte à Autorização MCP. Se não oferecer, utilize o método de Chave de API.
|
||||
|
||||
**Tempo limite de conexão**
|
||||
|
||||
* Confirme que o URL do endpoint MCP é acessível a partir da sua máquina. Para instâncias auto-hospedadas, verifique se o servidor está em execução e se `SERVER_URL` está definido corretamente.
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: Server MCP
|
||||
description: Conectați asistenți AI la spațiul dvs. de lucru Twenty folosind Model Context Protocol.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
MCP este în prezent în **alpha** și este disponibil doar în unele spații de lucru. Este posibil să nu fie activat încă pentru spațiul dvs. de lucru.
|
||||
</Warning>
|
||||
|
||||
Twenty expune un server [MCP](https://modelcontextprotocol.io/) astfel încât asistenții AI — Claude Desktop, Claude Code, Cursor, ChatGPT și alții — să poată citi și scrie datele tale din CRM prin limbaj natural.
|
||||
|
||||
Folosește **URL-ul spațiului de lucru** (URL-ul pe care îl folosești pentru a accesa Twenty) drept punct final MCP. Pe Twenty Cloud, URL-ul spațiului tău de lucru poate fi `https://{mycompany}.twenty.com` sau un domeniu personalizat. Serverul este disponibil la:
|
||||
|
||||
| Mediu | Punct final MCP |
|
||||
| -------------------- | ------------------------------------------------------------------------------ |
|
||||
| **Cloud** | `https://{your-workspace-url}/mcp` (de ex. `https://mycompany.twenty.com/mcp`) |
|
||||
| **Găzduire proprie** | `https://{your-domain}/mcp` |
|
||||
|
||||
## Metode de autentificare
|
||||
|
||||
Ai două moduri de a-ți autentifica clientul MCP: **OAuth** (recomandat) sau **Cheie API**.
|
||||
|
||||
### Opțiunea A — OAuth (Recomandat)
|
||||
|
||||
Cu OAuth, clientul tău MCP deschide o fereastră de browser pentru a te autentifica. Nicio informație secretă nu este stocată în fișierele de configurare, iar tokenurile se reîmprospătează automat.
|
||||
|
||||
<Note>
|
||||
OAuth necesită un client MCP care suportă [specificația MCP Authorization](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization). Claude Desktop, Claude Code, Cursor și ChatGPT o suportă.
|
||||
</Note>
|
||||
|
||||
Adaugă asta în configurația clientului tău MCP, înlocuind `{your-workspace-url}` cu gazda spațiului tău de lucru (de ex. `mycompany.twenty.com`):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Atât — nu este necesară nicio cheie API. Când clientul se conectează pentru prima dată, acesta va:
|
||||
|
||||
1. Va descoperi metadatele OAuth ale Twenty prin `/.well-known/oauth-protected-resource` și `/.well-known/oauth-authorization-server`
|
||||
2. Se va înregistra ca un client OAuth prin înregistrare dinamică a clientului (RFC 7591)
|
||||
3. Îți va deschide browserul pentru a autoriza accesul
|
||||
4. Va primi tokenurile și se va conecta la serverul MCP
|
||||
|
||||
Conexiunile ulterioare reutilizează tokenurile stocate și le reîmprospătează automat.
|
||||
|
||||
### Opțiunea B — Cheie API
|
||||
|
||||
Dacă clientul tău MCP nu suportă OAuth sau preferi acreditări statice, furnizează o cheie API în antetul `Authorization`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Cheia ta API oferă acces la datele spațiului de lucru. Ține-o în afara controlului versiunilor și a dotfiles partajate.
|
||||
</Warning>
|
||||
|
||||
Pentru a crea o cheie API, mergi la **Settings > APIs & Webhooks > + Create key**. Vezi [API-uri](/l/ro/developers/extend/api#create-an-api-key) pentru detalii.
|
||||
|
||||
## Pornire rapidă
|
||||
|
||||
### 1. Copiază configurația
|
||||
|
||||
Mergi la **Settings > AI > More > MCP Server** în Twenty. Alege metoda de autentificare (OAuth sau Cheie API), copiază fragmentul JSON (va folosi deja URL-ul spațiului tău de lucru) și lipește-l în fișierul de configurare al clientului tău MCP.
|
||||
|
||||
| Client | Locația fișierului de configurare |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) sau `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
|
||||
| **Claude Code** | `~/.claude.json` (utilizator) sau `.mcp.json` (proiect) |
|
||||
| **Cursor** | `.cursor/mcp.json` în proiectul tău sau `~/.cursor/mcp.json` global |
|
||||
| **ChatGPT** | Activează Modul pentru dezvoltatori în **Settings > Apps & Connectors > Advanced settings**, apoi folosește **Create** în **Settings > Apps & Connectors** pentru a adăuga serverul MCP |
|
||||
|
||||
### 2. Conectează-te
|
||||
|
||||
Repornește clientul tău MCP (sau reîncarcă configurația). Dacă folosești OAuth, vei fi redirecționat către Twenty pentru a autoriza accesul. Dacă folosești o cheie API, conexiunea este imediată.
|
||||
|
||||
### 3. Începe să-l folosești
|
||||
|
||||
Roagă-ți asistentul AI să interacționeze cu CRM-ul tău:
|
||||
|
||||
* *"Arată-mi cele 5 companii create cel mai recent"*
|
||||
* *"Creează o persoană nouă numită Jane Doe la Acme Corp"*
|
||||
* *"Găsește toate oportunitățile deschise cu o valoare mai mare de $10k"*
|
||||
|
||||
## Instrumente disponibile
|
||||
|
||||
După conectare, serverul MCP expune instrumente care oglindesc API-ul Twenty. Fluxul de lucru recomandat este:
|
||||
|
||||
1. **`get_tool_catalog`** — descoperă toate instrumentele disponibile
|
||||
2. **`learn_tools`** — obține schema de intrare pentru instrumente specifice
|
||||
3. **`execute_tool`** — rulează un instrument
|
||||
|
||||
Nu este nevoie să reții numele instrumentelor. Întreabă-ți asistentul AI ce poate face și va apela `get_tool_catalog` automat.
|
||||
|
||||
## Permisiuni
|
||||
|
||||
Conexiunile MCP moștenesc permisiunile utilizatorului autentificat (OAuth) sau rolul atribuit cheii API. Pentru a restricționa ce poate face serverul MCP:
|
||||
|
||||
* **OAuth**: Se aplică rolul utilizatorului din spațiul de lucru.
|
||||
* **Cheie API**: Atribuie un rol cheii API în **Settings > Roles**. Vezi [Permisiuni](/l/ro/user-guide/permissions-access/capabilities/permissions).
|
||||
|
||||
## Configurație pentru auto-găzduire
|
||||
|
||||
Pentru instanțele auto-găzduite, înlocuiește `{your-workspace-url}` cu URL-ul serverului tău. Asigură-te că `SERVER_URL` din mediul tău corespunde URL-ului public al instanței tale Twenty — acesta este folosit pentru a genera metadatele de descoperire OAuth.
|
||||
|
||||
```bash
|
||||
SERVER_URL=https://twenty.yourcompany.com
|
||||
```
|
||||
|
||||
Punctul final MCP, punctele finale OAuth și metadatele de descoperire derivă toate din această valoare.
|
||||
|
||||
## Depanare
|
||||
|
||||
**Erori "Unauthorized" sau 401**
|
||||
|
||||
* OAuth: reautorizează ștergând tokenurile stocate din clientul tău MCP și reconectează-te.
|
||||
* Cheie API: verifică dacă cheia este validă și nu a expirat. Regenereaz-o dacă este necesar.
|
||||
|
||||
**Fluxul OAuth nu deschide un browser**
|
||||
|
||||
* Asigură-te că clientul tău MCP suportă MCP Authorization. Dacă nu, revino la metoda cu Cheie API.
|
||||
|
||||
**Timeout de conexiune**
|
||||
|
||||
* Confirmă că URL-ul punctului final MCP este accesibil de pe calculatorul tău. Pentru instanțele auto-găzduite, verifică faptul că serverul rulează și că `SERVER_URL` este setat corect.
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: Сервер MCP
|
||||
description: Подключайте ИИ-ассистентов к вашему рабочему пространству Twenty с помощью протокола Model Context Protocol.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
В настоящее время MCP находится на стадии **alpha** и доступен только в некоторых рабочих пространствах. В вашем рабочем пространстве он может быть ещё не включён.
|
||||
</Warning>
|
||||
|
||||
Twenty предоставляет сервер [MCP](https://modelcontextprotocol.io/), чтобы ИИ-ассистенты — Claude Desktop, Claude Code, Cursor, ChatGPT и другие — могли читать и записывать ваши данные CRM на естественном языке.
|
||||
|
||||
Используйте **URL рабочей области** (URL, который вы используете для доступа к Twenty) в качестве конечной точки MCP. В Twenty Cloud URL вашей рабочей области может быть `https://{mycompany}.twenty.com` или собственный домен. Сервер доступен по адресу:
|
||||
|
||||
| Среда | Конечная точка MCP |
|
||||
| --------------------------- | --------------------------------------------------------------------------------- |
|
||||
| **Облако** | `https://{your-workspace-url}/mcp` (например, `https://mycompany.twenty.com/mcp`) |
|
||||
| **Самостоятельный хостинг** | `https://{your-domain}/mcp` |
|
||||
|
||||
## Методы аутентификации
|
||||
|
||||
Есть два способа аутентифицировать ваш MCP-клиент: **OAuth** (рекомендуется) или **API Key**.
|
||||
|
||||
### Вариант A — OAuth (рекомендуется)
|
||||
|
||||
При использовании OAuth ваш MCP-клиент откроет окно браузера для входа в систему. Секреты не хранятся в файлах конфигурации, а токены обновляются автоматически.
|
||||
|
||||
<Note>
|
||||
Для OAuth требуется MCP-клиент, поддерживающий [спецификацию авторизации MCP](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization). Её поддерживают Claude Desktop, Claude Code, Cursor и ChatGPT.
|
||||
</Note>
|
||||
|
||||
Добавьте это в конфигурацию вашего MCP-клиента, заменив `{your-workspace-url}` на хост вашей рабочей области (например, `mycompany.twenty.com`):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Вот и всё — ключ API не требуется. При первом подключении клиент выполнит:
|
||||
|
||||
1. Обнаружит метаданные OAuth Twenty через `/.well-known/oauth-protected-resource` и `/.well-known/oauth-authorization-server`
|
||||
2. Зарегистрирует себя как OAuth-клиент через динамическую регистрацию клиентов (RFC 7591)
|
||||
3. Откроет браузер для авторизации доступа
|
||||
4. Получит токены и подключится к серверу MCP
|
||||
|
||||
При последующих подключениях используются сохранённые токены, которые автоматически обновляются.
|
||||
|
||||
### Вариант B — ключ API
|
||||
|
||||
Если ваш MCP-клиент не поддерживает OAuth или вы предпочитаете статические учётные данные, передайте ключ API в заголовке `Authorization`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Ваш ключ API предоставляет доступ к данным рабочей области. Не храните его в системе контроля версий и общих dotfiles.
|
||||
</Warning>
|
||||
|
||||
Чтобы создать ключ API, перейдите в **Settings > APIs & Webhooks > + Create key**. См. [API](/l/ru/developers/extend/api#create-an-api-key) для подробностей.
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
### 1. Скопируйте конфигурацию
|
||||
|
||||
Перейдите в **Settings > AI > More > MCP Server** в Twenty. Выберите метод аутентификации (OAuth или ключ API), скопируйте фрагмент JSON (в нём уже будет использован URL вашей рабочей области) и вставьте его в файл конфигурации вашего MCP-клиента.
|
||||
|
||||
| Клиент | Расположение файла конфигурации |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) или `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
|
||||
| **Claude Code** | `~/.claude.json` (пользователь) или `.mcp.json` (проект) |
|
||||
| **Cursor** | `.cursor/mcp.json` в вашем проекте или `~/.cursor/mcp.json` глобально |
|
||||
| **ChatGPT** | Включите режим разработчика в **Settings > Apps & Connectors > Advanced settings**, затем используйте **Create** в **Settings > Apps & Connectors**, чтобы добавить сервер MCP |
|
||||
|
||||
### 2. Подключение
|
||||
|
||||
Перезапустите ваш MCP-клиент (или перезагрузите конфигурацию). Если используется OAuth, вы будете перенаправлены в Twenty для авторизации доступа. Если используется ключ API, подключение произойдёт сразу.
|
||||
|
||||
### 3. Начните использовать
|
||||
|
||||
Попросите вашего ИИ-ассистента взаимодействовать с вашей CRM:
|
||||
|
||||
* *"Покажи мне 5 последних созданных компаний"*
|
||||
* *"Создай новый контакт по имени Jane Doe в компании Acme Corp"*
|
||||
* *"Найди все открытые сделки стоимостью более $10 000"*
|
||||
|
||||
## Доступные инструменты
|
||||
|
||||
После подключения сервер MCP предоставляет инструменты, отражающие API Twenty. Рекомендуемый рабочий процесс:
|
||||
|
||||
1. **`get_tool_catalog`** — получить список всех доступных инструментов
|
||||
2. **`learn_tools`** — получить схему входных данных для конкретных инструментов
|
||||
3. **`execute_tool`** — запустить инструмент
|
||||
|
||||
Вам не нужно запоминать названия инструментов. Спросите у вашего ИИ-ассистента, что он умеет, и он автоматически вызовет `get_tool_catalog`.
|
||||
|
||||
## Разрешения
|
||||
|
||||
Подключения MCP наследуют разрешения аутентифицированного пользователя (OAuth) или роль, назначенную ключу API. Чтобы ограничить действия, доступные серверу MCP:
|
||||
|
||||
* **OAuth**: Применяется роль пользователя в рабочей области.
|
||||
* **API Key**: Назначьте ключу API роль в **Settings > Roles**. См. [Разрешения](/l/ru/user-guide/permissions-access/capabilities/permissions).
|
||||
|
||||
## Конфигурация для самостоятельного хостинга
|
||||
|
||||
Для экземпляров с самостоятельным хостингом замените `{your-workspace-url}` на URL вашего сервера. Убедитесь, что значение `SERVER_URL` в вашей среде соответствует публичному URL экземпляра Twenty — оно используется для генерации метаданных обнаружения OAuth.
|
||||
|
||||
```bash
|
||||
SERVER_URL=https://twenty.yourcompany.com
|
||||
```
|
||||
|
||||
Конечная точка MCP, конечные точки OAuth и метаданные обнаружения формируются на основе этого значения.
|
||||
|
||||
## Устранение неполадок
|
||||
|
||||
**Ошибки "Unauthorized" или 401**
|
||||
|
||||
* OAuth: повторно авторизуйтесь, очистив сохранённые токены в вашем MCP-клиенте и переподключившись.
|
||||
* API Key: убедитесь, что ключ действителен и не истёк. При необходимости сгенерируйте его заново.
|
||||
|
||||
**Процесс OAuth не открывает браузер**
|
||||
|
||||
* Убедитесь, что ваш MCP-клиент поддерживает MCP Authorization. Если нет — используйте метод с ключом API.
|
||||
|
||||
**Тайм-аут подключения**
|
||||
|
||||
* Убедитесь, что URL конечной точки MCP доступен с вашего компьютера. Для экземпляров с самостоятельным хостингом проверьте, что сервер запущен и значение `SERVER_URL` установлено корректно.
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: MCP Sunucusu
|
||||
description: Model Context Protocol kullanarak yapay zeka asistanlarını Twenty çalışma alanınıza bağlayın.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
MCP şu anda **alfa** aşamasındadır ve yalnızca bazı çalışma alanlarında kullanılabilir. Çalışma alanınızda henüz etkinleştirilmemiş olabilir.
|
||||
</Warning>
|
||||
|
||||
Twenty, yapay zeka asistanlarının — Claude Desktop, Claude Code, Cursor, ChatGPT ve diğerlerinin — doğal dil aracılığıyla CRM verilerinizi okuması ve yazması için bir [MCP](https://modelcontextprotocol.io/) sunucusu sunar.
|
||||
|
||||
MCP uç noktası olarak **çalışma alanı URL'nizi** (Twenty'ye erişmek için kullandığınız URL) kullanın. Twenty Cloud'da, çalışma alanı URL'niz `https://{mycompany}.twenty.com` ya da özel bir alan adı olabilir. Sunucu şu adreste kullanılabilir:
|
||||
|
||||
| Ortam | MCP Uç Noktası |
|
||||
| ---------------------------- | ---------------------------------------------------------------------------- |
|
||||
| **Bulut** | `https://{your-workspace-url}/mcp` (örn. `https://mycompany.twenty.com/mcp`) |
|
||||
| **Kendi Kendine Barındırma** | `https://{your-domain}/mcp` |
|
||||
|
||||
## Kimlik Doğrulama Yöntemleri
|
||||
|
||||
MCP istemcinizi kimlik doğrulamak için iki yolunuz var: **OAuth** (önerilir) veya **API Anahtarı**.
|
||||
|
||||
### Seçenek A — OAuth (Önerilir)
|
||||
|
||||
OAuth ile, MCP istemciniz oturum açmanız için bir tarayıcı penceresi açar. Gizli bilgiler yapılandırma dosyalarında saklanmaz ve belirteçler otomatik olarak yenilenir.
|
||||
|
||||
<Note>
|
||||
OAuth, [MCP Yetkilendirme belirtimi](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization)ni destekleyen bir MCP istemcisi gerektirir. Claude Desktop, Claude Code, Cursor ve ChatGPT bunu destekler.
|
||||
</Note>
|
||||
|
||||
Bunu MCP istemci yapılandırmanıza ekleyin; `{your-workspace-url}` öğesini çalışma alanınızın ana makine adıyla değiştirin (örn. `mycompany.twenty.com`):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Hepsi bu — API anahtarı gerekmez. İstemci ilk kez bağlandığında şunları yapacaktır:
|
||||
|
||||
1. Twenty'nin OAuth üst verilerini `/.well-known/oauth-protected-resource` ve `/.well-known/oauth-authorization-server` üzerinden keşfeder
|
||||
2. Dinamik istemci kaydı (RFC 7591) yoluyla kendisini bir OAuth istemcisi olarak kaydeder
|
||||
3. Erişimi yetkilendirmek için tarayıcınızı açar
|
||||
4. Belirteçleri alır ve MCP sunucusuna bağlanır
|
||||
|
||||
Sonraki bağlantılar, depolanan belirteçleri yeniden kullanır ve bunları otomatik olarak yeniler.
|
||||
|
||||
### Seçenek B — API Anahtarı
|
||||
|
||||
MCP istemciniz OAuth'u desteklemiyorsa veya statik kimlik bilgilerini tercih ediyorsanız, `Authorization` üstbilgisinde bir API anahtarı gönderin:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Warning>
|
||||
API anahtarınız çalışma alanı verilerine erişim sağlar. Sürüm kontrolünün ve paylaşılan dotfile'ların dışında tutun.
|
||||
</Warning>
|
||||
|
||||
Bir API anahtarı oluşturmak için **Settings > APIs & Webhooks > + Create key** bölümüne gidin. Ayrıntılar için [API'ler](/l/tr/developers/extend/api#create-an-api-key) bölümüne bakın.
|
||||
|
||||
## Hızlı Başlangıç
|
||||
|
||||
### 1. Yapılandırmayı kopyalayın
|
||||
|
||||
Twenty içinde **Settings > AI > More > MCP Server** bölümüne gidin. Kimlik doğrulama yöntemini (OAuth veya API Anahtarı) seçin, JSON parçacığını kopyalayın (çalışma alanı URL'nizi zaten kullanacaktır) ve MCP istemcinizin yapılandırma dosyasına yapıştırın.
|
||||
|
||||
| İstemci | Yapılandırma dosyasının konumu |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) veya `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
|
||||
| **Claude Code** | `~/.claude.json` (kullanıcı) veya `.mcp.json` (proje) |
|
||||
| **Cursor** | Projenizde `.cursor/mcp.json` veya genel olarak `~/.cursor/mcp.json` |
|
||||
| **ChatGPT** | Developer Mode'u **Settings > Apps & Connectors > Advanced settings** içinde açın, ardından MCP sunucusunu eklemek için **Settings > Apps & Connectors** içindeki **Create** seçeneğini kullanın |
|
||||
|
||||
### 2. Bağlan
|
||||
|
||||
MCP istemcinizi yeniden başlatın (veya yapılandırmayı yeniden yükleyin). OAuth kullanıyorsanız, erişimi yetkilendirmek için Twenty'ye yönlendirileceksiniz. API anahtarı kullanıyorsanız, bağlantı anında kurulur.
|
||||
|
||||
### 3. Kullanmaya başlayın
|
||||
|
||||
Yapay zeka asistanınızdan CRM'inizle etkileşime geçmesini isteyin:
|
||||
|
||||
* *"Bana en son oluşturulan 5 şirketi göster"*
|
||||
* *"Acme Corp'ta Jane Doe adlı yeni bir kişi oluştur"*
|
||||
* *"10.000 $'dan fazla değere sahip tüm açık fırsatları bul"*
|
||||
|
||||
## Kullanılabilir Araçlar
|
||||
|
||||
Bağlandıktan sonra, MCP sunucusu Twenty API'sini yansıtan araçlar sunar. Önerilen iş akışı:
|
||||
|
||||
1. **`get_tool_catalog`** — mevcut tüm araçları keşfedin
|
||||
2. **`learn_tools`** — belirli araçların girdi şemasını alın
|
||||
3. **`execute_tool`** — bir aracı çalıştırın
|
||||
|
||||
Araç adlarını hatırlamanıza gerek yok. Yapay zeka asistanınıza neler yapabileceğini sorun; `get_tool_catalog` çağrısını otomatik olarak yapacaktır.
|
||||
|
||||
## İzinler
|
||||
|
||||
MCP bağlantıları, kimliği doğrulanmış kullanıcının (OAuth) izinlerini veya API anahtarına atanan rolü devralır. MCP sunucusunun neler yapabileceğini kısıtlamak için:
|
||||
|
||||
* **OAuth**: Kullanıcının çalışma alanı rolü geçerlidir.
|
||||
* **API Anahtarı**: **Settings > Roles** altında API anahtarına bir rol atayın. Bkz. [İzinler](/l/tr/user-guide/permissions-access/capabilities/permissions).
|
||||
|
||||
## Öz Barındırmalı Yapılandırma
|
||||
|
||||
Öz barındırmalı kurulumlarda `{your-workspace-url}` değerini sunucunuzun URL'siyle değiştirin. Ortamınızdaki `SERVER_URL` değerinin Twenty örneğinizin genel URL'siyle eşleştiğinden emin olun — bu, OAuth keşif üst verilerini oluşturmak için kullanılır.
|
||||
|
||||
```bash
|
||||
SERVER_URL=https://twenty.yourcompany.com
|
||||
```
|
||||
|
||||
MCP uç noktası, OAuth uç noktaları ve keşif üst verilerinin tümü bu değerden türetilir.
|
||||
|
||||
## Sorun Giderme
|
||||
|
||||
**"Unauthorized" veya 401 hataları**
|
||||
|
||||
* OAuth: MCP istemcinizde depolanan belirteçleri temizleyip yeniden bağlanarak yeniden yetkilendirin.
|
||||
* API Anahtarı: anahtarın geçerli olduğunu ve süresinin dolmadığını doğrulayın. Gerekirse yeniden oluşturun.
|
||||
|
||||
**OAuth akışı bir tarayıcı açmıyor**
|
||||
|
||||
* MCP istemcinizin MCP Yetkilendirmeyi desteklediğinden emin olun. Desteklemiyorsa API Anahtarı yöntemine geri dönün.
|
||||
|
||||
**Bağlantı zaman aşımı**
|
||||
|
||||
* MCP uç noktası URL'sine makinenizden erişilebildiğini doğrulayın. Öz barındırmalı kurulumlar için, sunucunun çalıştığını ve `SERVER_URL` değerinin doğru ayarlandığını kontrol edin.
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: MCP服务器
|
||||
description: 使用 Model Context Protocol 将 AI 助手连接到你的 Twenty 工作区。
|
||||
---
|
||||
|
||||
<Warning>
|
||||
MCP 目前处于**alpha**阶段,并且仅在部分工作区可用。 它可能尚未在你的工作区启用。
|
||||
</Warning>
|
||||
|
||||
Twenty 提供一个 [MCP](https://modelcontextprotocol.io/) 服务器,使 AI 助手——Claude Desktop、Claude Code、Cursor、ChatGPT 等——能够通过自然语言读取和写入您的 CRM 数据。
|
||||
|
||||
将您的**工作区 URL**(用于访问 Twenty 的 URL)用作 MCP 端点。 在 Twenty Cloud 上,您的工作区 URL 可能是 `https://{mycompany}.twenty.com`,也可能是自定义域名。 服务器可通过以下地址访问:
|
||||
|
||||
| 环境 | MCP 端点 |
|
||||
| ------- | -------------------------------------------------------------------------- |
|
||||
| **云端** | `https://{your-workspace-url}/mcp` (例如 `https://mycompany.twenty.com/mcp`) |
|
||||
| **自托管** | `https://{your-domain}/mcp` |
|
||||
|
||||
## 身份验证方法
|
||||
|
||||
您可以通过两种方式对 MCP 客户端进行身份验证:**OAuth**(推荐)或 **API 密钥**。
|
||||
|
||||
### 选项 A — OAuth(推荐)
|
||||
|
||||
使用 OAuth 时,您的 MCP 客户端会打开浏览器窗口供您登录。 不会在配置文件中存储任何机密,令牌会自动刷新。
|
||||
|
||||
<Note>
|
||||
OAuth 需要支持[MCP 授权规范](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization)的 MCP 客户端。 Claude Desktop、Claude Code、Cursor 和 ChatGPT 均支持它。
|
||||
</Note>
|
||||
|
||||
将以下内容添加到 MCP 客户端配置中,并将 `{your-workspace-url}` 替换为您的工作区主机(例如 `mycompany.twenty.com`):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
就这样——无需 API 密钥。 客户端首次连接时将:
|
||||
|
||||
1. 通过 `/.well-known/oauth-protected-resource` 和 `/.well-known/oauth-authorization-server` 发现 Twenty 的 OAuth 元数据
|
||||
2. 通过动态客户端注册(RFC 7591)将自身注册为 OAuth 客户端
|
||||
3. 打开您的浏览器以授权访问
|
||||
4. 接收令牌并连接到 MCP 服务器
|
||||
|
||||
后续连接会重用已存储的令牌并自动刷新。
|
||||
|
||||
### 选项 B — API 密钥
|
||||
|
||||
如果您的 MCP 客户端不支持 OAuth,或您更喜欢静态凭据,请在 `Authorization` 请求头中传递 API 密钥:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Warning>
|
||||
您的 API 密钥可访问工作区数据。 请不要将其纳入版本控制,也不要放入共享的 dotfiles。
|
||||
</Warning>
|
||||
|
||||
要创建 API 密钥,请前往 **Settings > APIs & Webhooks > + Create key**。 详见[API](/l/zh/developers/extend/api#create-an-api-key)。
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 复制配置
|
||||
|
||||
在 Twenty 中前往 **Settings > AI > More > MCP Server**。 选择您的身份验证方式(OAuth 或 API 密钥),复制 JSON 片段(其中已包含您的工作区 URL),并将其粘贴到 MCP 客户端的配置文件中。
|
||||
|
||||
| 客户端 | 配置文件位置 |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) 或 `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
|
||||
| **Claude Code** | `~/.claude.json` (用户) 或 `.mcp.json` (项目) |
|
||||
| **Cursor** | 在您的项目中为 `.cursor/mcp.json`,或全局为 `~/.cursor/mcp.json` |
|
||||
| **ChatGPT** | 在 **Settings > Apps & Connectors > Advanced settings** 中开启开发者模式,然后在 **Settings > Apps & Connectors** 中使用 **Create** 添加 MCP 服务器 |
|
||||
|
||||
### 2. 连接
|
||||
|
||||
重启您的 MCP 客户端(或重新加载配置)。 如果使用 OAuth,您将被重定向到 Twenty 以授权访问。 如果使用 API 密钥,连接会立即建立。
|
||||
|
||||
### 3. 开始使用
|
||||
|
||||
让您的 AI 助手与您的 CRM 交互:
|
||||
|
||||
* *"给我展示最近创建的 5 家公司"*
|
||||
* *"在 Acme Corp 新建一位名为 Jane Doe 的联系人"*
|
||||
* *"查找所有价值超过 $10k 的未关闭商机"*
|
||||
|
||||
## 可用工具
|
||||
|
||||
连接后,MCP 服务器会提供与 Twenty API 一一对应的工具。 推荐的工作流程是:
|
||||
|
||||
1. **`get_tool_catalog`** — 发现所有可用工具
|
||||
2. **`learn_tools`** — 获取特定工具的输入模式
|
||||
3. **`execute_tool`** — 运行工具
|
||||
|
||||
您无需记住工具名称。 询问您的 AI 助手它能做什么,它会自动调用 `get_tool_catalog`。
|
||||
|
||||
## 权限
|
||||
|
||||
MCP 连接将继承已通过身份验证的用户(OAuth)的权限,或继承分配给 API 密钥的角色。 要限制 MCP 服务器的操作范围:
|
||||
|
||||
* **OAuth**:生效的是该用户在工作区中的角色。
|
||||
* **API 密钥**:在 **Settings > Roles** 下为该 API 密钥分配角色。 参见[权限](/l/zh/user-guide/permissions-access/capabilities/permissions)。
|
||||
|
||||
## 自托管配置
|
||||
|
||||
对于自托管实例,请将 `{your-workspace-url}` 替换为您的服务器 URL。 请确保您环境中的 `SERVER_URL` 与 Twenty 实例的公共 URL 一致——该值用于生成 OAuth 发现元数据。
|
||||
|
||||
```bash
|
||||
SERVER_URL=https://twenty.yourcompany.com
|
||||
```
|
||||
|
||||
MCP 端点、OAuth 端点以及发现元数据都基于该值生成。
|
||||
|
||||
## 故障排除
|
||||
|
||||
**"Unauthorized" 或 401 错误**
|
||||
|
||||
* OAuth:清除 MCP 客户端中存储的令牌并重新连接以重新授权。
|
||||
* API 密钥:验证该密钥有效且未过期。 如有需要,请重新生成。
|
||||
|
||||
**OAuth 流程未打开浏览器**
|
||||
|
||||
* 确保您的 MCP 客户端支持 MCP 授权。 如果不支持,请改用 API 密钥方法。
|
||||
|
||||
**连接超时**
|
||||
|
||||
* 确认从您的机器可以访问 MCP 端点 URL。 对于自托管实例,请检查服务器是否正在运行,并确认 `SERVER_URL` 设置正确。
|
||||
@@ -0,0 +1,139 @@
|
||||
---
|
||||
title: MCP Server
|
||||
description: Connect AI assistants to your Twenty workspace using the Model Context Protocol.
|
||||
---
|
||||
|
||||
<Warning>
|
||||
MCP is currently in **alpha** and is only available on some workspaces. It may not be enabled for your workspace yet.
|
||||
</Warning>
|
||||
|
||||
Twenty exposes an [MCP](https://modelcontextprotocol.io/) server so that AI assistants — Claude Desktop, Claude Code, Cursor, ChatGPT, and others — can read and write your CRM data through natural language.
|
||||
|
||||
Use your **workspace URL** (the URL you use to access Twenty) as the MCP endpoint. On Twenty Cloud, your workspace URL might be `https://{mycompany}.twenty.com` or a custom domain. The server is available at:
|
||||
|
||||
| Environment | MCP Endpoint |
|
||||
|-------------|-------------|
|
||||
| **Cloud** | `https://{your-workspace-url}/mcp` (e.g. `https://mycompany.twenty.com/mcp`) |
|
||||
| **Self-Hosted** | `https://{your-domain}/mcp` |
|
||||
|
||||
## Authentication Methods
|
||||
|
||||
You have two ways to authenticate your MCP client: **OAuth** (recommended) or **API Key**.
|
||||
|
||||
### Option A — OAuth (Recommended)
|
||||
|
||||
With OAuth, your MCP client opens a browser window for you to log in. No secrets are stored in config files, and tokens refresh automatically.
|
||||
|
||||
<Note>
|
||||
OAuth requires an MCP client that supports the [MCP Authorization specification](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization). Claude Desktop, Claude Code, Cursor, and ChatGPT support it.
|
||||
</Note>
|
||||
|
||||
Add this to your MCP client configuration, replacing `{your-workspace-url}` with your workspace host (e.g. `mycompany.twenty.com`):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
That's it — no API key needed. When the client connects for the first time it will:
|
||||
|
||||
1. Discover Twenty's OAuth metadata via `/.well-known/oauth-protected-resource` and `/.well-known/oauth-authorization-server`
|
||||
2. Register itself as an OAuth client via dynamic client registration (RFC 7591)
|
||||
3. Open your browser to authorize access
|
||||
4. Receive tokens and connect to the MCP server
|
||||
|
||||
Subsequent connections reuse the stored tokens and refresh them automatically.
|
||||
|
||||
### Option B — API Key
|
||||
|
||||
If your MCP client does not support OAuth, or you prefer static credentials, pass an API key in the `Authorization` header:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"twenty": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://{your-workspace-url}/mcp",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Your API key grants access to workspace data. Keep it out of version control and shared dotfiles.
|
||||
</Warning>
|
||||
|
||||
To create an API key, go to **Settings > APIs & Webhooks > + Create key**. See [APIs](/developers/extend/api#create-an-api-key) for details.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Copy the config
|
||||
|
||||
Go to **Settings > AI > More > MCP Server** in Twenty. Choose your authentication method (OAuth or API Key), copy the JSON snippet (it will already use your workspace URL), and paste it into your MCP client's config file.
|
||||
|
||||
| Client | Config file location |
|
||||
|--------|---------------------|
|
||||
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
|
||||
| **Claude Code** | `~/.claude.json` (user) or `.mcp.json` (project) |
|
||||
| **Cursor** | `.cursor/mcp.json` in your project, or `~/.cursor/mcp.json` globally |
|
||||
| **ChatGPT** | Turn on Developer Mode in **Settings > Apps & Connectors > Advanced settings**, then use **Create** in **Settings > Apps & Connectors** to add the MCP server |
|
||||
|
||||
### 2. Connect
|
||||
|
||||
Restart your MCP client (or reload the config). If using OAuth you will be redirected to Twenty to authorize access. If using an API key the connection is immediate.
|
||||
|
||||
### 3. Start using it
|
||||
|
||||
Ask your AI assistant to interact with your CRM:
|
||||
|
||||
- *"Show me the 5 most recently created companies"*
|
||||
- *"Create a new person named Jane Doe at Acme Corp"*
|
||||
- *"Find all open opportunities worth more than $10k"*
|
||||
|
||||
## Available Tools
|
||||
|
||||
Once connected, the MCP server exposes tools that mirror the Twenty API. The recommended workflow is:
|
||||
|
||||
1. **`get_tool_catalog`** — discover all available tools
|
||||
2. **`learn_tools`** — get the input schema for specific tools
|
||||
3. **`execute_tool`** — run a tool
|
||||
|
||||
You don't need to remember tool names. Ask your AI assistant what it can do and it will call `get_tool_catalog` automatically.
|
||||
|
||||
## Permissions
|
||||
|
||||
MCP connections inherit the permissions of the authenticated user (OAuth) or the role assigned to the API key. To restrict what the MCP server can do:
|
||||
|
||||
- **OAuth**: The user's workspace role applies.
|
||||
- **API Key**: Assign a role to the API key under **Settings > Roles**. See [Permissions](/user-guide/permissions-access/capabilities/permissions).
|
||||
|
||||
## Self-Hosted Configuration
|
||||
|
||||
For self-hosted instances, replace `{your-workspace-url}` with your server URL. Make sure `SERVER_URL` in your environment matches the public URL of your Twenty instance — this is used to generate the OAuth discovery metadata.
|
||||
|
||||
```bash
|
||||
SERVER_URL=https://twenty.yourcompany.com
|
||||
```
|
||||
|
||||
The MCP endpoint, OAuth endpoints, and discovery metadata all derive from this value.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**"Unauthorized" or 401 errors**
|
||||
- OAuth: re-authorize by clearing the stored tokens in your MCP client and reconnecting.
|
||||
- API Key: verify the key is valid and hasn't expired. Regenerate it if needed.
|
||||
|
||||
**OAuth flow doesn't open a browser**
|
||||
- Ensure your MCP client supports MCP Authorization. Fall back to the API Key method if it doesn't.
|
||||
|
||||
**Connection timeout**
|
||||
- Confirm the MCP endpoint URL is reachable from your machine. For self-hosted instances, check that the server is running and `SERVER_URL` is set correctly.
|
||||
@@ -1,19 +1,23 @@
|
||||
/* oxlint-disable no-console */
|
||||
import { generateApiKeys } from './mock-data/generate-api-keys.js';
|
||||
import { generateBillingPlans } from './mock-data/generate-billing-plans.js';
|
||||
import { generateMetadata } from './mock-data/generate-metadata.js';
|
||||
import { generateObjectMetadata } from './mock-data/generate-object-metadata.js';
|
||||
import { generateMinimalMetadata } from './mock-data/generate-minimal-metadata.js';
|
||||
import { generateRecordData } from './mock-data/generate-record-data.js';
|
||||
import { generateRoles } from './mock-data/generate-roles.js';
|
||||
import { generateNavigationMenuItems } from './mock-data/generate-navigation-menu-items.js';
|
||||
import { generateViews } from './mock-data/generate-views.js';
|
||||
import { authenticate } from './mock-data/utils.js';
|
||||
|
||||
const main = async () => {
|
||||
const token = await authenticate();
|
||||
|
||||
const metadata = await generateMetadata(token);
|
||||
const metadata = await generateObjectMetadata(token);
|
||||
await generateMinimalMetadata(token);
|
||||
await generateRecordData(token, metadata);
|
||||
await generateRoles(token);
|
||||
await generateViews(token);
|
||||
await generateNavigationMenuItems(token);
|
||||
|
||||
try {
|
||||
await generateBillingPlans(token);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/* oxlint-disable no-console */
|
||||
import { graphqlRequest, writeGeneratedFile } from './utils.js';
|
||||
|
||||
const MINIMAL_METADATA_QUERY = `
|
||||
query FindMinimalMetadata {
|
||||
minimalMetadata {
|
||||
objectMetadataItems {
|
||||
id
|
||||
nameSingular
|
||||
namePlural
|
||||
labelSingular
|
||||
labelPlural
|
||||
icon
|
||||
isCustom
|
||||
isActive
|
||||
isSystem
|
||||
isRemote
|
||||
}
|
||||
views {
|
||||
id
|
||||
type
|
||||
key
|
||||
objectMetadataId
|
||||
}
|
||||
collectionHashes {
|
||||
collectionName
|
||||
hash
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const generateMinimalMetadata = async (token: string) => {
|
||||
console.log('Fetching minimal metadata from /metadata ...');
|
||||
|
||||
const data = (await graphqlRequest(
|
||||
'/metadata',
|
||||
MINIMAL_METADATA_QUERY,
|
||||
token,
|
||||
)) as {
|
||||
minimalMetadata: Record<string, unknown>;
|
||||
};
|
||||
|
||||
writeGeneratedFile(
|
||||
'metadata/minimal/mock-minimal-metadata.ts',
|
||||
'mockedMinimalMetadata',
|
||||
'MinimalMetadata',
|
||||
"import { type MinimalMetadata } from '@/metadata-store/types/MinimalMetadata';",
|
||||
data.minimalMetadata,
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
/* oxlint-disable no-console, lingui/no-unlocalized-strings */
|
||||
import { graphqlRequest, writeGeneratedFile } from './utils.js';
|
||||
|
||||
const FIND_MANY_NAVIGATION_MENU_ITEMS_QUERY = `
|
||||
query FindManyNavigationMenuItems {
|
||||
navigationMenuItems {
|
||||
id
|
||||
userWorkspaceId
|
||||
targetRecordId
|
||||
targetObjectMetadataId
|
||||
viewId
|
||||
folderId
|
||||
name
|
||||
link
|
||||
icon
|
||||
color
|
||||
position
|
||||
applicationId
|
||||
createdAt
|
||||
updatedAt
|
||||
targetRecordIdentifier {
|
||||
id
|
||||
labelIdentifier
|
||||
imageIdentifier
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const generateNavigationMenuItems = async (token: string) => {
|
||||
console.log('Fetching navigation menu items from /metadata ...');
|
||||
|
||||
const data = (await graphqlRequest(
|
||||
'/metadata',
|
||||
FIND_MANY_NAVIGATION_MENU_ITEMS_QUERY,
|
||||
token,
|
||||
)) as {
|
||||
navigationMenuItems: Record<string, unknown>[];
|
||||
};
|
||||
|
||||
console.log(` Got ${data.navigationMenuItems.length} navigation menu items.`);
|
||||
|
||||
writeGeneratedFile(
|
||||
'metadata/navigation-menu-items/mock-navigation-menu-items-data.ts',
|
||||
'mockedNavigationMenuItems',
|
||||
'NavigationMenuItem[]',
|
||||
"import { type NavigationMenuItem } from '~/generated-metadata/graphql';",
|
||||
data.navigationMenuItems,
|
||||
);
|
||||
};
|
||||
+1
-1
@@ -141,7 +141,7 @@ const METADATA_QUERY = `
|
||||
}
|
||||
`;
|
||||
|
||||
export const generateMetadata = async (token: string) => {
|
||||
export const generateObjectMetadata = async (token: string) => {
|
||||
console.log('Fetching object metadata from /metadata ...');
|
||||
|
||||
const metadata = await graphqlRequest('/metadata', METADATA_QUERY, token);
|
||||
@@ -1,9 +1,9 @@
|
||||
/* oxlint-disable no-console, lingui/no-unlocalized-strings */
|
||||
import { graphqlRequest, writeGeneratedFile } from './utils.js';
|
||||
|
||||
const FIND_ALL_CORE_VIEWS_QUERY = `
|
||||
query FindAllCoreViews {
|
||||
getCoreViews {
|
||||
const FIND_ALL_VIEWS_QUERY = `
|
||||
query FindAllViews {
|
||||
getViews {
|
||||
id
|
||||
name
|
||||
objectMetadataId
|
||||
@@ -101,19 +101,19 @@ export const generateViews = async (token: string) => {
|
||||
|
||||
const data = (await graphqlRequest(
|
||||
'/metadata',
|
||||
FIND_ALL_CORE_VIEWS_QUERY,
|
||||
FIND_ALL_VIEWS_QUERY,
|
||||
token,
|
||||
)) as {
|
||||
getCoreViews: Record<string, unknown>[];
|
||||
getViews: Record<string, unknown>[];
|
||||
};
|
||||
|
||||
console.log(` Got ${data.getCoreViews.length} views.`);
|
||||
console.log(` Got ${data.getViews.length} views.`);
|
||||
|
||||
writeGeneratedFile(
|
||||
'metadata/views/mock-views-data.ts',
|
||||
'mockedCoreViews',
|
||||
'CoreViewWithRelations[]',
|
||||
"import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations';",
|
||||
data.getCoreViews,
|
||||
'mockedViews',
|
||||
'ViewWithRelations[]',
|
||||
"import { type ViewWithRelations } from '@/views/types/ViewWithRelations';",
|
||||
data.getViews,
|
||||
);
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
+223
-223
@@ -1,4 +1,4 @@
|
||||
import { useIsLogged } from '@/auth/hooks/useIsLogged';
|
||||
import { useHasAccessTokenPair } from '@/auth/hooks/useHasAccessTokenPair';
|
||||
import { useDefaultHomePagePath } from '@/navigation/hooks/useDefaultHomePagePath';
|
||||
import { useOnboardingStatus } from '@/onboarding/hooks/useOnboardingStatus';
|
||||
import { useIsWorkspaceActivationStatusEqualsTo } from '@/workspace/hooks/useIsWorkspaceActivationStatusEqualsTo';
|
||||
@@ -39,9 +39,9 @@ const setupMockIsMatchingLocation = (pathname: string) => {
|
||||
);
|
||||
};
|
||||
|
||||
jest.mock('@/auth/hooks/useIsLogged');
|
||||
const setupMockIsLogged = (isLogged: boolean) => {
|
||||
jest.mocked(useIsLogged).mockReturnValueOnce(isLogged);
|
||||
jest.mock('@/auth/hooks/useHasAccessTokenPair');
|
||||
const setupMockHasAccessTokenPair = (hasAccessTokenPair: boolean) => {
|
||||
jest.mocked(useHasAccessTokenPair).mockReturnValueOnce(hasAccessTokenPair);
|
||||
};
|
||||
|
||||
const defaultHomePagePath = '/objects/companies';
|
||||
@@ -83,7 +83,7 @@ const setupMockState = (
|
||||
// prettier-ignore
|
||||
const testCases: {
|
||||
loc: AppPath;
|
||||
isLoggedIn: boolean;
|
||||
hasAccessTokenPair: boolean;
|
||||
isWorkspaceSuspended: boolean;
|
||||
onboardingStatus: OnboardingStatus | undefined;
|
||||
res: string | undefined;
|
||||
@@ -93,248 +93,248 @@ const testCases: {
|
||||
verifyEmailRedirectPath?: string;
|
||||
returnToPath?: string;
|
||||
}[] = [
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.Verify, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: undefined },
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.Verify, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.Verify, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.Verify, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: undefined },
|
||||
{ loc: AppPath.Verify, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.Verify, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.Verify, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.Verify, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.Verify, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.Verify, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: undefined },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.SignInUp, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.SignInUp, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.SignInUp, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: undefined },
|
||||
{ loc: AppPath.SignInUp, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.SignInUp, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.SignInUp, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.SignInUp, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.SignInUp, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.SignInUp, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: '/plan-required' },
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.Invite, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: undefined },
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: '/create/workspace' },
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: '/create/profile' },
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: '/sync/emails' },
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: '/invite-team' },
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.Invite, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: '/plan-required' },
|
||||
{ loc: AppPath.Invite, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.Invite, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: undefined },
|
||||
{ loc: AppPath.Invite, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: '/create/workspace' },
|
||||
{ loc: AppPath.Invite, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: '/create/profile' },
|
||||
{ loc: AppPath.Invite, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: '/sync/emails' },
|
||||
{ loc: AppPath.Invite, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: '/invite-team' },
|
||||
{ loc: AppPath.Invite, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.Invite, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: '/plan-required' },
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: undefined },
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: '/create/workspace' },
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: '/create/profile' },
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: '/sync/emails' },
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: '/invite-team' },
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.ResetPassword, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: '/plan-required' },
|
||||
{ loc: AppPath.ResetPassword, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.ResetPassword, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: undefined },
|
||||
{ loc: AppPath.ResetPassword, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: '/create/workspace' },
|
||||
{ loc: AppPath.ResetPassword, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: '/create/profile' },
|
||||
{ loc: AppPath.ResetPassword, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: '/sync/emails' },
|
||||
{ loc: AppPath.ResetPassword, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: '/invite-team' },
|
||||
{ loc: AppPath.ResetPassword, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.ResetPassword, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, verifyEmailRedirectPath: '/nextPath?key=value', res: '/nextPath?key=value' },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, verifyEmailRedirectPath: '/nextPath?key=value', res: undefined },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: undefined },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.VerifyEmail, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.VerifyEmail, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, verifyEmailRedirectPath: '/nextPath?key=value', res: '/nextPath?key=value' },
|
||||
{ loc: AppPath.VerifyEmail, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.VerifyEmail, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, verifyEmailRedirectPath: '/nextPath?key=value', res: undefined },
|
||||
{ loc: AppPath.VerifyEmail, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: undefined },
|
||||
{ loc: AppPath.VerifyEmail, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.VerifyEmail, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.VerifyEmail, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.VerifyEmail, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.VerifyEmail, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.VerifyEmail, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: undefined },
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.CreateWorkspace, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.CreateWorkspace, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.CreateWorkspace, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.CreateWorkspace, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: undefined },
|
||||
{ loc: AppPath.CreateWorkspace, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.CreateWorkspace, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.CreateWorkspace, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.CreateWorkspace, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.CreateWorkspace, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: undefined },
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.CreateProfile, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.CreateProfile, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.CreateProfile, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.CreateProfile, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.CreateProfile, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.CreateProfile, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: undefined },
|
||||
{ loc: AppPath.CreateProfile, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.CreateProfile, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.CreateProfile, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.CreateProfile, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: undefined },
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.SyncEmails, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.SyncEmails, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.SyncEmails, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.SyncEmails, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.SyncEmails, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.SyncEmails, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.SyncEmails, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: undefined },
|
||||
{ loc: AppPath.SyncEmails, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.SyncEmails, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.SyncEmails, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: undefined },
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.InviteTeam, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.InviteTeam, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.InviteTeam, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.InviteTeam, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.InviteTeam, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.InviteTeam, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.InviteTeam, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.InviteTeam, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: undefined },
|
||||
{ loc: AppPath.InviteTeam, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.InviteTeam, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: undefined },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: undefined },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: undefined },
|
||||
{ loc: AppPath.BookCallDecision, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.BookCallDecision, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: undefined },
|
||||
{ loc: AppPath.BookCallDecision, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.BookCallDecision, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.BookCallDecision, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: undefined },
|
||||
{ loc: AppPath.BookCallDecision, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.BookCallDecision, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.BookCallDecision, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.BookCallDecision, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: undefined },
|
||||
{ loc: AppPath.BookCallDecision, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: undefined },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: undefined },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: undefined },
|
||||
{ loc: AppPath.BookCall, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.BookCall, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: undefined },
|
||||
{ loc: AppPath.BookCall, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.BookCall, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.BookCall, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: undefined },
|
||||
{ loc: AppPath.BookCall, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.BookCall, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.BookCall, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.BookCall, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: undefined },
|
||||
{ loc: AppPath.BookCall, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: undefined },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.PlanRequired, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.PlanRequired, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: undefined },
|
||||
{ loc: AppPath.PlanRequired, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.PlanRequired, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.PlanRequired, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.PlanRequired, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.PlanRequired, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.PlanRequired, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.PlanRequired, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.PlanRequired, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: undefined },
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.PlanRequiredSuccess, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.PlanRequiredSuccess, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: undefined },
|
||||
{ loc: AppPath.PlanRequiredSuccess, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.PlanRequiredSuccess, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.PlanRequiredSuccess, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.PlanRequiredSuccess, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.PlanRequiredSuccess, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.PlanRequiredSuccess, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.PlanRequiredSuccess, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.PlanRequiredSuccess, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.Index, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
{ loc: AppPath.Index, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.Index, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.Index, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.Index, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.Index, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.Index, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.Index, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.Index, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.Index, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
|
||||
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.TasksPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.TasksPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.TasksPage, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.TasksPage, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.TasksPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.TasksPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.TasksPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.TasksPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.TasksPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.TasksPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.OpportunitiesPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.OpportunitiesPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.OpportunitiesPage, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.OpportunitiesPage, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.OpportunitiesPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.OpportunitiesPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.OpportunitiesPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.OpportunitiesPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.OpportunitiesPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.OpportunitiesPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined, objectNamePluralFromParams: 'existing-object', objectNamePluralFromMetadata: 'existing-object' },
|
||||
{ loc: AppPath.RecordIndexPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: AppPath.NotFound, objectNamePluralFromParams: 'non-existing-object', objectNamePluralFromMetadata: 'existing-object' },
|
||||
{ loc: AppPath.RecordIndexPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.RecordIndexPage, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.RecordIndexPage, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.RecordIndexPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.RecordIndexPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.RecordIndexPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.RecordIndexPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.RecordIndexPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.RecordIndexPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.RecordIndexPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined, objectNamePluralFromParams: 'existing-object', objectNamePluralFromMetadata: 'existing-object' },
|
||||
{ loc: AppPath.RecordIndexPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: AppPath.NotFound, objectNamePluralFromParams: 'non-existing-object', objectNamePluralFromMetadata: 'existing-object' },
|
||||
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.RecordShowPage, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.RecordShowPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.RecordShowPage, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.RecordShowPage, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.RecordShowPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.RecordShowPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.RecordShowPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.RecordShowPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.RecordShowPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.RecordShowPage, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.SettingsCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.SettingsCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.SettingsCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.SettingsCatchAll, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.SettingsCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.SettingsCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.SettingsCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.SettingsCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.SettingsCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.SettingsCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.DevelopersCatchAll, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.DevelopersCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.DevelopersCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.DevelopersCatchAll, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.DevelopersCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.DevelopersCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.DevelopersCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.DevelopersCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.DevelopersCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.DevelopersCatchAll, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.Authorize, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.Authorize, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.Authorize, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.Authorize, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.Authorize, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.Authorize, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.Authorize, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.Authorize, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.Authorize, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.Authorize, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.Authorize, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.NotFoundWildcard, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.NotFoundWildcard, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.NotFoundWildcard, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.NotFoundWildcard, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.NotFoundWildcard, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.NotFoundWildcard, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.NotFoundWildcard, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.NotFoundWildcard, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.NotFoundWildcard, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.NotFoundWildcard, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.NotFound, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.NotFound, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
{ loc: AppPath.NotFound, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
|
||||
{ loc: AppPath.NotFound, hasAccessTokenPair: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: getSettingsPath(SettingsPath.Billing) },
|
||||
{ loc: AppPath.NotFound, hasAccessTokenPair: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },
|
||||
{ loc: AppPath.NotFound, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WORKSPACE_ACTIVATION, res: AppPath.CreateWorkspace },
|
||||
{ loc: AppPath.NotFound, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: AppPath.CreateProfile },
|
||||
{ loc: AppPath.NotFound, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: AppPath.SyncEmails },
|
||||
{ loc: AppPath.NotFound, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: AppPath.InviteTeam },
|
||||
{ loc: AppPath.NotFound, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.BOOK_ONBOARDING, res: AppPath.BookCallDecision },
|
||||
{ loc: AppPath.NotFound, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
|
||||
|
||||
// returnToPath: should redirect to saved path instead of defaultHomePagePath
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, returnToPath: '/authorize?clientId=abc', res: '/authorize?clientId=abc' },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, returnToPath: '/objects/tasks', res: '/objects/tasks' },
|
||||
{ loc: AppPath.Index, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, returnToPath: '/settings/api-keys', res: '/settings/api-keys' },
|
||||
{ loc: AppPath.Verify, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, returnToPath: '/authorize?clientId=abc', res: '/authorize?clientId=abc' },
|
||||
{ loc: AppPath.SignInUp, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, returnToPath: '/objects/tasks', res: '/objects/tasks' },
|
||||
{ loc: AppPath.Index, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, returnToPath: '/settings/api-keys', res: '/settings/api-keys' },
|
||||
|
||||
// isOnAWorkspace:false — on default domain, don't redirect to returnToPath or defaultHomePagePath from auth pages
|
||||
{ loc: AppPath.Verify, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, isOnAWorkspace: false, res: undefined },
|
||||
{ loc: AppPath.SignInUp, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, isOnAWorkspace: false, res: undefined },
|
||||
{ loc: AppPath.Verify, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, isOnAWorkspace: false, res: undefined },
|
||||
{ loc: AppPath.SignInUp, hasAccessTokenPair: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, isOnAWorkspace: false, res: undefined },
|
||||
];
|
||||
|
||||
describe('usePageChangeEffectNavigateLocation', () => {
|
||||
@@ -344,7 +344,7 @@ describe('usePageChangeEffectNavigateLocation', () => {
|
||||
loc,
|
||||
onboardingStatus,
|
||||
isWorkspaceSuspended,
|
||||
isLoggedIn,
|
||||
hasAccessTokenPair,
|
||||
isOnAWorkspace,
|
||||
objectNamePluralFromParams,
|
||||
objectNamePluralFromMetadata,
|
||||
@@ -355,7 +355,7 @@ describe('usePageChangeEffectNavigateLocation', () => {
|
||||
setupMockIsMatchingLocation(loc);
|
||||
setupMockOnboardingStatus(onboardingStatus);
|
||||
setupMockIsWorkspaceActivationStatusEqualsTo(isWorkspaceSuspended);
|
||||
setupMockIsLogged(isLoggedIn);
|
||||
setupMockHasAccessTokenPair(hasAccessTokenPair);
|
||||
setupMockIsOnAWorkspace(isOnAWorkspace ?? true);
|
||||
setupMockUseParams(objectNamePluralFromParams);
|
||||
setupMockState(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { verifyEmailRedirectPathState } from '@/app/states/verifyEmailRedirectPathState';
|
||||
import { ONBOARDING_PATHS } from '@/auth/constants/OnboardingPaths';
|
||||
import { ONGOING_USER_CREATION_PATHS } from '@/auth/constants/OngoingUserCreationPaths';
|
||||
import { useIsLogged } from '@/auth/hooks/useIsLogged';
|
||||
import { useHasAccessTokenPair } from '@/auth/hooks/useHasAccessTokenPair';
|
||||
import { returnToPathState } from '@/auth/states/returnToPathState';
|
||||
import { calendarBookingPageIdState } from '@/client-config/states/calendarBookingPageIdState';
|
||||
import { useIsCurrentLocationOnAWorkspace } from '@/domain-manager/hooks/useIsCurrentLocationOnAWorkspace';
|
||||
@@ -26,7 +26,7 @@ const readReturnToPathFromUrlSearchParams = (): string | null => {
|
||||
};
|
||||
|
||||
export const usePageChangeEffectNavigateLocation = () => {
|
||||
const isLoggedIn = useIsLogged();
|
||||
const hasAccessTokenPair = useHasAccessTokenPair();
|
||||
const { isOnAWorkspace } = useIsCurrentLocationOnAWorkspace();
|
||||
const onboardingStatus = useOnboardingStatus();
|
||||
const isWorkspaceSuspended = useIsWorkspaceActivationStatusEqualsTo(
|
||||
@@ -54,7 +54,7 @@ export const usePageChangeEffectNavigateLocation = () => {
|
||||
: readReturnToPathFromUrlSearchParams();
|
||||
|
||||
if (
|
||||
(!isLoggedIn || (isLoggedIn && !isOnAWorkspace)) &&
|
||||
(!hasAccessTokenPair || (hasAccessTokenPair && !isOnAWorkspace)) &&
|
||||
!someMatchingLocationOf([
|
||||
...ONGOING_USER_CREATION_PATHS,
|
||||
AppPath.ResetPassword,
|
||||
@@ -140,13 +140,13 @@ export const usePageChangeEffectNavigateLocation = () => {
|
||||
...ONGOING_USER_CREATION_PATHS,
|
||||
]) &&
|
||||
!isMatchingLocation(location, AppPath.ResetPassword) &&
|
||||
isLoggedIn &&
|
||||
hasAccessTokenPair &&
|
||||
isOnAWorkspace
|
||||
) {
|
||||
return resolvedReturnToPath ?? defaultHomePagePath;
|
||||
}
|
||||
|
||||
if (isMatchingLocation(location, AppPath.Index) && isLoggedIn) {
|
||||
if (isMatchingLocation(location, AppPath.Index) && hasAccessTokenPair) {
|
||||
return resolvedReturnToPath ?? defaultHomePagePath;
|
||||
}
|
||||
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Oor hierdie werkruimte"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Kry toegang tot jou werksruimte data vanaf jou gunsteling MCP-kliënt soos Claude Desktop, Windsurf of Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webtuistes"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API-sleutel"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Magtiging"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Magtiging het misluk"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "عن مساحة العمل هذه"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "الوصول إلى بيانات مساحة العمل الخاصة بك من عميل MCP المفضل لديك مثل Claude Desktop و Windsurf أو Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "واجهة برمجة التطبيقات والويب هوك"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "مفتاح واجهة برمجة التطبيقات"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "المصادقة"
|
||||
msgid "Authentication failed"
|
||||
msgstr "فشل المصادقة"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Sobre aquest espai de treball"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Accediu a les dades del vostre espai de treball des del vostre client MCP preferit, com Claude Desktop, Windsurf o Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API i Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "Clau d'API"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Autenticació"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Error en l'autenticació"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "O tomto pracovním prostoru"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Přistupujte ke svým pracovním datům z vašeho oblíbeného MCP klienta, jako je Claude Desktop, Windsurf nebo Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API klíč"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Ověření"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Ověření selhalo"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Om dette arbejdsområde"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Adgang til dine arbejdsdata fra din foretrukne MCP-klient som Claude Desktop, Windsurf eller Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API-nøgle"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Godkendelse"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Godkendelse mislykkedes"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Über diesen Arbeitsbereich"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Greifen Sie auf Ihre Workspace-Daten von Ihrem bevorzugten MCP-Client wie Claude Desktop, Windsurf oder Cursor zu."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API-Schlüssel"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Authentifizierung"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Authentifizierung fehlgeschlagen"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Σχετικά με αυτό το χώρο εργασίας"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Πρόσβαση στα δεδομένα του χώρου εργασίας σας από τον αγαπημένο σας πελάτη MCP, όπως το Claude Desktop, το Windsurf ή το Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API Key"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Ταυτοποίηση"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Αποτυχία ταυτοποίησης"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -658,10 +658,10 @@ msgstr "About this workspace"
|
||||
msgid "Access workspace data"
|
||||
msgstr "Access workspace data"
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1676,6 +1676,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API Key"
|
||||
@@ -2126,6 +2127,11 @@ msgstr "Authentication"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Authentication failed"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr "Authentication method"
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9793,6 +9799,7 @@ msgstr "Numbered list"
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr "OAuth"
|
||||
|
||||
@@ -9801,6 +9808,11 @@ msgstr "OAuth"
|
||||
msgid "OAuth Credentials"
|
||||
msgstr "OAuth Credentials"
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr "OAuth or API Key"
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Sobre este espacio de trabajo"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Accede a los datos de tu espacio de trabajo desde tu cliente MCP favorito, como Claude Desktop, Windsurf o Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API y Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "Clave API"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Autenticación"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Autenticación fallida"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr "Lista numerada"
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Tietoa tästä työtilasta"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Käytä työtilan tietoja suosikki MCP-asiakkaasi, kuten Claude Desktop, Windsurf tai Cursor, kautta."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API-avain"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Todennus"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Todennus epäonnistui"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "À propos de cet espace de travail"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Accédez à vos données de l'espace de travail depuis votre client MCP préféré comme Claude Desktop, Windsurf ou Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "Clé API"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Authentification"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Authentification échouée"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -663,10 +663,10 @@ msgstr "אודות סביבת עבודה זו"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "גש לנתוני סביבת העבודה שלך מהלקוח MCP המועדף עליך כמו Claude Desktop, Windsurf או Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API ו-Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "מפתח API"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "אימות"
|
||||
msgid "Authentication failed"
|
||||
msgstr "האימות נכשל"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Erről a munkaterületről"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Hozzáférhet munkatéradataihoz a kedvenc MCP-klienséből, például a Claude Desktop, Windsurf vagy Cursor programokból."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API kulcs"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Hitelesítés"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Hitelesítés sikertelen"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Informazioni su questo spazio di lavoro"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Accedi ai dati del tuo spazio di lavoro dal tuo client MCP preferito come Claude Desktop, Windsurf o Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API e Webhook"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "Chiave API"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Autenticazione"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Autenticazione fallita"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "このワークスペースについて"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "お好みの MCP クライアント (Claude Desktop、Windsurf や Cursor など) からワークスペース データにアクセスしてください。"
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "APIキー"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "認証"
|
||||
msgid "Authentication failed"
|
||||
msgstr "認証に失敗しました"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "이 작업공간에 대해"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Claude Desktop, Windsurf 또는 Cursor와 같은 좋아하는 MCP 클라이언트에서 워크스페이스 데이터를 액세스하세요."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API 및 웹훅"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API 키"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "인증"
|
||||
msgid "Authentication failed"
|
||||
msgstr "인증 실패"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Over deze werkruimte"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Toegang tot uw werkruimtegegevens vanuit uw favoriete MCP-client zoals Claude Desktop, Windsurf of Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API-sleutel"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Authenticatie"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Authenticatie mislukt"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Om dette arbeidsområdet"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Tilgangen til arbeidsområde dataene dine fra din favoritt MCP klient som Claude Desktop, Windsurf eller Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API og webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API-nøkkel"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Autentisering"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Autentisering mislyktes"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "O tej przestrzeni roboczej"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Uzyskaj dostęp do danych ze swojego ulubionego klienta MCP, takiego jak Claude Desktop, Windsurf czy Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API i Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "Klucz API"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Uwierzytelnianie"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Uwierzytelnianie nie powiodło się"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -658,9 +658,9 @@ msgstr ""
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
@@ -1676,6 +1676,7 @@ msgstr ""
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr ""
|
||||
@@ -2126,6 +2127,11 @@ msgstr ""
|
||||
msgid "Authentication failed"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9793,6 +9799,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9801,6 +9808,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Sobre este espaço de trabalho"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Acesse seus dados de trabalho a partir do seu cliente MCP favorito, como Claude Desktop, Windsurf ou Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API e Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "Chave API"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Autenticação"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Falha na autenticação"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Sobre este espaço de trabalho"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Acesse os dados do seu espaço de trabalho de seu cliente MCP favorito como Claude Desktop, Windsurf ou Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API e Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "Chave API"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Autenticação"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Autenticação falhou"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Despre acest spațiu de lucru"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Accesați datele dvs. din spațiul de lucru de pe clientul MCP favorit, cum ar fi Claude Desktop, Windsurf sau Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "Cheie API"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Autentificare"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Autentificare eșuată"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
Binary file not shown.
@@ -663,10 +663,10 @@ msgstr "О овом радном простору"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Приступите вашим радним подацима са омиљеног MCP клијента као што су Claude Desktop, Windsurf или Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API и Вебхукси"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API кључ"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Аутентификација"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Аутентификација није успела"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Om den här arbetsytan"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Du får åtkomst till dina arbetsytedata från din favorit MCP-klient som Claude Desktop, Windsurf eller Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API-nyckel"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Autentisering"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Autentisering misslyckades"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9800,6 +9806,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9808,6 +9815,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Bu çalışma alanı hakkında"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Claude Desktop, Windsurf veya Cursor gibi en sevdiğiniz MCP istemcisinden çalışma alanı verilerinize erişin."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhook'lar"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API Anahtar"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Kimlik Doğrulama"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Kimlik doğrulama başarısız"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Про цей робочий простір"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Отримуйте доступ до даних робочого простору з улюбленого MCP клієнта, як-то Claude Desktop, Windsurf або Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API та Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API-ключ"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Аутентифікація"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Не вдалося пройти аутентифікацію"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "Giới thiệu về không gian làm việc này"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "Truy cập dữ liệu không gian làm việc của bạn từ khách hàng MCP yêu thích như Claude Desktop, Windsurf hoặc Cursor."
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API & Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "Khóa API"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "Xác thực"
|
||||
msgid "Authentication failed"
|
||||
msgstr "Xác thực thất bại"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "关于此工作区"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "从您喜欢的MCP客户端(例如Claude Desktop、Windsurf或Cursor)访问您的工作区数据。"
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API 和 Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API 密钥"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "身份验证"
|
||||
msgid "Authentication failed"
|
||||
msgstr "身份验证失败"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
@@ -663,10 +663,10 @@ msgstr "關於此工作區"
|
||||
msgid "Access workspace data"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: c2UA7k
|
||||
#. js-lingui-id: W5nhmk
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Windsurf or Cursor."
|
||||
msgstr "從您最喜歡的MCP客戶端訪問您的工作區數據,如Claude桌面版、Windsurf或Cursor。"
|
||||
msgid "Access your workspace data from your favorite MCP client like Claude Desktop, Claude Code, Cursor, or ChatGPT. Once connected, try: \"Show me the 5 most recently created companies\" or \"Create a new person named Jane Doe\"."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: u2Cycw
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionTabEnvironmentVariablesSection.tsx
|
||||
@@ -1681,6 +1681,7 @@ msgstr "API 和 Webhooks"
|
||||
#. js-lingui-id: yRnk5W
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
#: src/modules/settings/playground/components/PlaygroundSetupForm.tsx
|
||||
msgid "API Key"
|
||||
msgstr "API 密鑰"
|
||||
@@ -2131,6 +2132,11 @@ msgstr "身份驗證"
|
||||
msgid "Authentication failed"
|
||||
msgstr "身份驗證失敗"
|
||||
|
||||
#. js-lingui-id: TxT0ER
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "Authentication method"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: H7qgYQ
|
||||
#: src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx
|
||||
msgid "Authenticator app"
|
||||
@@ -9798,6 +9804,7 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: b/j06W
|
||||
#: src/pages/settings/applications/SettingsApplicationRegistrationDetails.tsx
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth"
|
||||
msgstr ""
|
||||
|
||||
@@ -9806,6 +9813,11 @@ msgstr ""
|
||||
msgid "OAuth Credentials"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: LNLTJB
|
||||
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
|
||||
msgid "OAuth or API Key"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: pNEViR
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "object"
|
||||
|
||||
+7
-1
@@ -29,7 +29,7 @@ export const getActivityTargetObjectRecords = ({
|
||||
|
||||
const isNote = isDefined(activityRecord) && 'noteTargets' in activityRecord;
|
||||
|
||||
const targets = activityTargets
|
||||
const rawTargets = activityTargets
|
||||
? activityTargets
|
||||
: 'noteTargets' in activityRecord && isDefined(activityRecord.noteTargets)
|
||||
? activityRecord.noteTargets
|
||||
@@ -37,6 +37,12 @@ export const getActivityTargetObjectRecords = ({
|
||||
? activityRecord.taskTargets
|
||||
: [];
|
||||
|
||||
if (!Array.isArray(rawTargets)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const targets = rawTargets;
|
||||
|
||||
const activityTargetObjectNameSingular = isNote
|
||||
? CoreObjectNameSingular.NoteTarget
|
||||
: CoreObjectNameSingular.TaskTarget;
|
||||
|
||||
@@ -15,7 +15,7 @@ import { recordStoreFamilySelector } from '@/object-record/record-store/states/s
|
||||
import { getTabListInstanceIdFromPageLayoutId } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutId';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||
import { useStore } from 'jotai';
|
||||
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
|
||||
import { viewFromViewIdFamilySelector } from '@/views/states/selectors/viewFromViewIdFamilySelector';
|
||||
|
||||
export const useGetBrowsingContext = () => {
|
||||
const store = useStore();
|
||||
@@ -102,7 +102,7 @@ export const useGetBrowsingContext = () => {
|
||||
);
|
||||
|
||||
const currentView = store.get(
|
||||
coreViewFromViewIdFamilySelector.selectorFamily({
|
||||
viewFromViewIdFamilySelector.selectorFamily({
|
||||
viewId: currentViewId ?? '',
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { AgentChatProvider } from '@/ai/components/AgentChatProvider';
|
||||
import { CommandMenuConfirmationModalManager } from '@/command-menu-item/confirmation-modal/components/CommandMenuConfirmationModalManager';
|
||||
import { ApolloProvider } from '@/apollo/components/ApolloProvider';
|
||||
import { MetadataGater } from '@/metadata-store/components/MetadataGater';
|
||||
import { IsAppMetadataReadyEffect } from '@/metadata-store/effect-components/IsAppMetadataReadyEffect';
|
||||
import { MinimalMetadataGater } from '@/metadata-store/components/MinimalMetadataGater';
|
||||
import { IsMinimalMetadataReadyEffect } from '@/metadata-store/effect-components/IsMinimalMetadataReadyEffect';
|
||||
|
||||
import { GotoHotkeysEffectsProvider } from '@/app/effect-components/GotoHotkeysEffectsProvider';
|
||||
import { MinimalMetadataLoadEffect } from '@/metadata-store/effect-components/MinimalMetadataLoadEffect';
|
||||
import { MetadataProviderInitialEffects } from '@/metadata-store/effect-components/MetadataProviderInitialEffects';
|
||||
import { UserMetadataProviderInitialEffect } from '@/metadata-store/effect-components/UserMetadataProviderInitialEffect';
|
||||
import { PageChangeEffect } from '@/app/effect-components/PageChangeEffect';
|
||||
import { AuthProvider } from '@/auth/components/AuthProvider';
|
||||
import { CaptchaProvider } from '@/captcha/components/CaptchaProvider';
|
||||
@@ -31,7 +31,6 @@ import { BaseThemeProvider } from '@/ui/theme/components/BaseThemeProvider';
|
||||
import { UserThemeProviderEffect } from '@/ui/theme/components/UserThemeProviderEffect';
|
||||
import { PageFavicon } from '@/ui/utilities/page-favicon/components/PageFavicon';
|
||||
import { PageTitle } from '@/ui/utilities/page-title/components/PageTitle';
|
||||
import { LazyMetadataLoadEffect } from '@/users/components/LazyMetadataLoadEffect';
|
||||
import { WorkspaceProviderEffect } from '@/workspace/components/WorkspaceProviderEffect';
|
||||
import { StrictMode } from 'react';
|
||||
import { Outlet, useLocation } from 'react-router-dom';
|
||||
@@ -45,16 +44,15 @@ export const AppRouterProviders = () => {
|
||||
<ApolloProvider>
|
||||
<BaseThemeProvider>
|
||||
<ClientConfigProviderEffect />
|
||||
<UserMetadataProviderInitialEffect />
|
||||
<MinimalMetadataLoadEffect />
|
||||
<MetadataProviderInitialEffects />
|
||||
<LazyMetadataLoadEffect />
|
||||
<IsAppMetadataReadyEffect />
|
||||
<IsMinimalMetadataReadyEffect />
|
||||
<WorkspaceProviderEffect />
|
||||
<ClientConfigProvider>
|
||||
<CaptchaProvider>
|
||||
<ChromeExtensionSidecarEffect />
|
||||
<ChromeExtensionSidecarProvider>
|
||||
<MetadataGater>
|
||||
<MinimalMetadataGater>
|
||||
<AuthProvider>
|
||||
<ApolloCoreProvider>
|
||||
<SSEProvider>
|
||||
@@ -88,7 +86,7 @@ export const AppRouterProviders = () => {
|
||||
</SSEProvider>
|
||||
</ApolloCoreProvider>
|
||||
</AuthProvider>
|
||||
</MetadataGater>
|
||||
</MinimalMetadataGater>
|
||||
</ChromeExtensionSidecarProvider>
|
||||
</CaptchaProvider>
|
||||
</ClientConfigProvider>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
|
||||
import { useIsLogged } from '@/auth/hooks/useIsLogged';
|
||||
import { useHasAccessTokenPair } from '@/auth/hooks/useHasAccessTokenPair';
|
||||
import { useVerifyLogin } from '@/auth/hooks/useVerifyLogin';
|
||||
import { clientConfigApiStatusState } from '@/client-config/states/clientConfigApiStatusState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
@@ -13,7 +13,7 @@ export const VerifyLoginTokenEffect = () => {
|
||||
const [searchParams] = useSearchParams();
|
||||
const loginToken = searchParams.get('loginToken');
|
||||
|
||||
const isLogged = useIsLogged();
|
||||
const hasAccessTokenPair = useHasAccessTokenPair();
|
||||
const navigate = useNavigateApp();
|
||||
const { verifyLoginToken } = useVerifyLogin();
|
||||
|
||||
@@ -28,7 +28,7 @@ export const VerifyLoginTokenEffect = () => {
|
||||
|
||||
if (isDefined(loginToken)) {
|
||||
verifyLoginToken(loginToken);
|
||||
} else if (!isLogged) {
|
||||
} else if (!hasAccessTokenPair) {
|
||||
navigate(AppPath.SignInUp);
|
||||
}
|
||||
// Verify only needs to run once at mount
|
||||
|
||||
@@ -5,11 +5,13 @@ export const AUTHORIZE_APP = gql`
|
||||
$clientId: String!
|
||||
$codeChallenge: String
|
||||
$redirectUrl: String!
|
||||
$state: String
|
||||
) {
|
||||
authorizeApp(
|
||||
clientId: $clientId
|
||||
codeChallenge: $codeChallenge
|
||||
redirectUrl: $redirectUrl
|
||||
state: $state
|
||||
) {
|
||||
redirectUrl
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,10 +4,10 @@ export const FIND_APPLICATION_REGISTRATION_BY_CLIENT_ID = gql`
|
||||
query FindApplicationRegistrationByClientId($clientId: String!) {
|
||||
findApplicationRegistrationByClientId(clientId: $clientId) {
|
||||
id
|
||||
logoUrl
|
||||
name
|
||||
oAuthScopes
|
||||
websiteUrl
|
||||
logoUrl
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -30,12 +30,6 @@ jest.mock('@/domain-manager/hooks/useRedirect', () => ({
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('@/object-metadata/hooks/useRefreshObjectMetadataItems', () => ({
|
||||
useRefreshObjectMetadataItems: jest.fn().mockImplementation(() => ({
|
||||
refreshObjectMetadataItems: jest.fn(),
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('@/domain-manager/hooks/useOrigin', () => ({
|
||||
useOrigin: jest.fn().mockImplementation(() => ({
|
||||
origin: 'http://localhost',
|
||||
|
||||
+6
-6
@@ -1,27 +1,27 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
|
||||
import { useIsLogged } from '@/auth/hooks/useIsLogged';
|
||||
import { useHasAccessTokenPair } from '@/auth/hooks/useHasAccessTokenPair';
|
||||
import { tokenPairState } from '@/auth/states/tokenPairState';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
|
||||
const renderHooks = () => {
|
||||
const { result } = renderHook(() => {
|
||||
const isLogged = useIsLogged();
|
||||
const hasAccessTokenPair = useHasAccessTokenPair();
|
||||
const setTokenPair = useSetAtomState(tokenPairState);
|
||||
|
||||
return {
|
||||
isLogged,
|
||||
hasAccessTokenPair,
|
||||
setTokenPair,
|
||||
};
|
||||
});
|
||||
return { result };
|
||||
};
|
||||
|
||||
describe('useIsLogged', () => {
|
||||
describe('useHasAccessTokenPair', () => {
|
||||
it('should return correct value', async () => {
|
||||
const { result } = renderHooks();
|
||||
|
||||
expect(result.current.isLogged).toBe(false);
|
||||
expect(result.current.hasAccessTokenPair).toBe(false);
|
||||
|
||||
await act(async () => {
|
||||
result.current.setTokenPair({
|
||||
@@ -36,6 +36,6 @@ describe('useIsLogged', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.isLogged).toBe(true);
|
||||
expect(result.current.hasAccessTokenPair).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -34,7 +34,7 @@ import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMembe
|
||||
import { currentWorkspaceMembersState } from '@/auth/states/currentWorkspaceMembersState';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { useSignUpInNewWorkspace } from '@/auth/sign-in-up/hooks/useSignUpInNewWorkspace';
|
||||
import { useReloadWorkspaceMetadata } from '@/metadata-store/hooks/useReloadWorkspaceMetadata';
|
||||
import { useLoadMockedMinimalMetadata } from '@/metadata-store/hooks/useLoadMockedMinimalMetadata';
|
||||
import { lastAuthenticatedMethodState } from '@/auth/states/lastAuthenticatedMethodState';
|
||||
import { loginTokenState } from '@/auth/states/loginTokenState';
|
||||
import {
|
||||
@@ -42,7 +42,6 @@ import {
|
||||
signInUpStepState,
|
||||
} from '@/auth/states/signInUpStepState';
|
||||
import { workspacePublicDataState } from '@/auth/states/workspacePublicDataState';
|
||||
import { coreViewsState } from '@/views/states/coreViewState';
|
||||
import { type BillingCheckoutSession } from '@/auth/types/billingCheckoutSession.type';
|
||||
import {
|
||||
countAvailableWorkspaces,
|
||||
@@ -88,8 +87,7 @@ export const useAuth = () => {
|
||||
const { loadCurrentUser } = useLoadCurrentUser();
|
||||
const { clearSseClient } = useClearSseClient();
|
||||
|
||||
const { reloadWorkspaceMetadata, resetToMockedMetadata } =
|
||||
useReloadWorkspaceMetadata();
|
||||
const { loadMockedMinimalMetadata } = useLoadMockedMinimalMetadata();
|
||||
const { createWorkspace } = useSignUpInNewWorkspace();
|
||||
|
||||
const setSignInUpStep = useSetAtomState(signInUpStepState);
|
||||
@@ -163,18 +161,17 @@ export const useAuth = () => {
|
||||
});
|
||||
store.set(loginTokenState.atom, null);
|
||||
store.set(signInUpStepState.atom, SignInUpStep.Init);
|
||||
store.set(coreViewsState.atom, []);
|
||||
|
||||
await client.clearStore();
|
||||
setLastAuthenticateWorkspaceDomain(null);
|
||||
await resetToMockedMetadata();
|
||||
await loadMockedMinimalMetadata();
|
||||
navigate(AppPath.SignInUp);
|
||||
store.set(isAppEffectRedirectEnabledState.atom, true);
|
||||
}, [
|
||||
clearSseClient,
|
||||
client,
|
||||
setLastAuthenticateWorkspaceDomain,
|
||||
resetToMockedMetadata,
|
||||
loadMockedMinimalMetadata,
|
||||
navigate,
|
||||
store,
|
||||
]);
|
||||
@@ -305,14 +302,10 @@ export const useAuth = () => {
|
||||
setIsAppEffectRedirectEnabled(false);
|
||||
|
||||
await loadCurrentUser();
|
||||
await reloadWorkspaceMetadata();
|
||||
|
||||
setIsAppEffectRedirectEnabled(true);
|
||||
},
|
||||
[
|
||||
loadCurrentUser,
|
||||
handleSetAuthTokens,
|
||||
reloadWorkspaceMetadata,
|
||||
setIsAppEffectRedirectEnabled,
|
||||
],
|
||||
[loadCurrentUser, handleSetAuthTokens, setIsAppEffectRedirectEnabled],
|
||||
);
|
||||
|
||||
const handleGetAuthTokensFromLoginToken = useCallback(
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { tokenPairState } from '@/auth/states/tokenPairState';
|
||||
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
|
||||
|
||||
export const useIsLogged = (): boolean => {
|
||||
export const useHasAccessTokenPair = (): boolean => {
|
||||
const [tokenPair] = useAtomState(tokenPairState);
|
||||
return !!tokenPair;
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { currentUserWorkspaceState } from '@/auth/states/currentUserWorkspaceState';
|
||||
import { objectMetadataItemsSelector } from '@/metadata-store/states/objectMetadataItemsSelector';
|
||||
import { flatObjectMetadataItemsSelector } from '@/object-metadata/states/flatObjectMetadataItemsSelector';
|
||||
import { createAtomFamilySelector } from '@/ui/utilities/state/jotai/utils/createAtomFamilySelector';
|
||||
|
||||
export const objectPermissionsFamilySelector = createAtomFamilySelector<
|
||||
@@ -14,7 +14,7 @@ export const objectPermissionsFamilySelector = createAtomFamilySelector<
|
||||
({ objectNameSingular }) =>
|
||||
({ get }) => {
|
||||
const currentUserWorkspace = get(currentUserWorkspaceState);
|
||||
const objectMetadataItems = get(objectMetadataItemsSelector);
|
||||
const objectMetadataItems = get(flatObjectMetadataItemsSelector);
|
||||
|
||||
const objectMetadataItem = objectMetadataItems.find(
|
||||
(item) => item.nameSingular === objectNameSingular,
|
||||
|
||||
+18
-11
@@ -6,7 +6,7 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat
|
||||
import { useShowAuthModal } from '@/ui/layout/hooks/useShowAuthModal';
|
||||
import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilyStateValue';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { coreViewsState } from '@/views/states/coreViewState';
|
||||
import { viewsSelector } from '@/views/states/selectors/viewsSelector';
|
||||
import { useLocation, useParams, useSearchParams } from 'react-router-dom';
|
||||
import { AppPath } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -38,6 +38,8 @@ const getViewId = (
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const SIGN_IN_BACKGROUND_OBJECT_NAME_PLURAL = 'companies';
|
||||
|
||||
export const MainContextStoreProvider = () => {
|
||||
const location = useLocation();
|
||||
const isRecordIndexPage = isMatchingLocation(
|
||||
@@ -46,16 +48,21 @@ export const MainContextStoreProvider = () => {
|
||||
);
|
||||
const isRecordShowPage = isMatchingLocation(location, AppPath.RecordShowPage);
|
||||
const isSettingsPage = useIsSettingsPage();
|
||||
const showAuthModal = useShowAuthModal();
|
||||
|
||||
const objectNamePlural = useParams().objectNamePlural ?? '';
|
||||
const objectNamePluralFromParams = useParams().objectNamePlural ?? '';
|
||||
const objectNameSingular = useParams().objectNameSingular ?? '';
|
||||
|
||||
const objectNamePlural = showAuthModal
|
||||
? SIGN_IN_BACKGROUND_OBJECT_NAME_PLURAL
|
||||
: objectNamePluralFromParams;
|
||||
|
||||
const [searchParams] = useSearchParams();
|
||||
const viewIdQueryParamRaw = searchParams.get('viewId');
|
||||
|
||||
const objectMetadataItems = useAtomStateValue(objectMetadataItemsState);
|
||||
const metadataStore = useAtomFamilyStateValue(metadataStoreState, 'views');
|
||||
const coreViews = useAtomStateValue(coreViewsState);
|
||||
const views = useAtomStateValue(viewsSelector);
|
||||
|
||||
const objectMetadataItem = objectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
@@ -65,7 +72,7 @@ export const MainContextStoreProvider = () => {
|
||||
|
||||
const { getLastVisitedViewIdFromObjectNamePlural } = useLastVisitedView();
|
||||
|
||||
const viewIdQueryParamView = coreViews.find(
|
||||
const viewIdQueryParamView = views.find(
|
||||
(view) => view.id === viewIdQueryParamRaw,
|
||||
);
|
||||
|
||||
@@ -79,7 +86,7 @@ export const MainContextStoreProvider = () => {
|
||||
objectMetadataItem?.namePlural ?? '',
|
||||
);
|
||||
|
||||
const lastVisitedView = coreViews.find(
|
||||
const lastVisitedView = views.find(
|
||||
(view) => view.id === lastVisitedViewIdRaw,
|
||||
);
|
||||
|
||||
@@ -89,13 +96,13 @@ export const MainContextStoreProvider = () => {
|
||||
? lastVisitedViewIdRaw
|
||||
: undefined;
|
||||
|
||||
const indexViewId = coreViews.find(
|
||||
const indexViewId = views.find(
|
||||
(view) =>
|
||||
view.objectMetadataId === objectMetadataItem?.id &&
|
||||
view.key === ViewKey.INDEX,
|
||||
)?.id;
|
||||
|
||||
const firstAvailableViewId = coreViews.find(
|
||||
const firstAvailableViewId = views.find(
|
||||
(view) =>
|
||||
view.objectMetadataId === objectMetadataItem?.id &&
|
||||
view.type !== ViewType.FIELDS_WIDGET,
|
||||
@@ -108,11 +115,11 @@ export const MainContextStoreProvider = () => {
|
||||
firstAvailableViewId,
|
||||
);
|
||||
|
||||
const showAuthModal = useShowAuthModal();
|
||||
|
||||
const shouldComputeContextStore =
|
||||
(isRecordIndexPage || isRecordShowPage || isSettingsPage) &&
|
||||
!showAuthModal &&
|
||||
(isRecordIndexPage ||
|
||||
isRecordShowPage ||
|
||||
isSettingsPage ||
|
||||
showAuthModal) &&
|
||||
metadataStore.status === 'up-to-date';
|
||||
|
||||
if (!shouldComputeContextStore) {
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ import { useSetLastVisitedViewForObjectMetadataNamePlural } from '@/navigation/h
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState';
|
||||
import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
|
||||
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
|
||||
import { viewFromViewIdFamilySelector } from '@/views/states/selectors/viewFromViewIdFamilySelector';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
type MainContextStoreProviderEffectProps = {
|
||||
@@ -52,7 +52,7 @@ export const MainContextStoreProviderEffect = ({
|
||||
MAIN_CONTEXT_STORE_INSTANCE_ID,
|
||||
);
|
||||
|
||||
const view = useAtomFamilySelectorValue(coreViewFromViewIdFamilySelector, {
|
||||
const view = useAtomFamilySelectorValue(viewFromViewIdFamilySelector, {
|
||||
viewId: viewId ?? '',
|
||||
});
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ export const getViewType = ({
|
||||
}
|
||||
|
||||
if (isRecordIndexPage) {
|
||||
return view?.type === ViewType.Kanban
|
||||
return view?.type === ViewType.KANBAN
|
||||
? ContextStoreViewType.Kanban
|
||||
: ContextStoreViewType.Table;
|
||||
}
|
||||
|
||||
+7
-10
@@ -1,9 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import { isAppMetadataReadyState } from '@/metadata-store/states/isAppMetadataReadyState';
|
||||
import { useIsLogged } from '@/auth/hooks/useIsLogged';
|
||||
import { isMinimalMetadataReadyState } from '@/metadata-store/states/isMinimalMetadataReadyState';
|
||||
import { useDateTimeFormat } from '@/localization/hooks/useDateTimeFormat';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { UserContext } from '@/users/contexts/UserContext';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
@@ -11,10 +9,8 @@ import { AppPath } from 'twenty-shared/types';
|
||||
import { UserOrMetadataLoader } from '~/loading/components/UserOrMetadataLoader';
|
||||
import { isMatchingLocation } from '~/utils/isMatchingLocation';
|
||||
|
||||
export const MetadataGater = ({ children }: React.PropsWithChildren) => {
|
||||
const isAppMetadataReady = useAtomStateValue(isAppMetadataReadyState);
|
||||
const objectMetadataItems = useAtomStateValue(objectMetadataItemsState);
|
||||
const isLoggedIn = useIsLogged();
|
||||
export const MinimalMetadataGater = ({ children }: React.PropsWithChildren) => {
|
||||
const isMinimalMetadataReady = useAtomStateValue(isMinimalMetadataReadyState);
|
||||
const location = useLocation();
|
||||
|
||||
const { dateFormat, timeFormat, timeZone } = useDateTimeFormat();
|
||||
@@ -22,11 +18,12 @@ export const MetadataGater = ({ children }: React.PropsWithChildren) => {
|
||||
const isOnExcludedPath =
|
||||
isMatchingLocation(location, AppPath.Verify) ||
|
||||
isMatchingLocation(location, AppPath.VerifyEmail) ||
|
||||
isMatchingLocation(location, AppPath.SignInUp) ||
|
||||
isMatchingLocation(location, AppPath.Invite) ||
|
||||
isMatchingLocation(location, AppPath.ResetPassword) ||
|
||||
isMatchingLocation(location, AppPath.CreateWorkspace);
|
||||
|
||||
const shouldShowLoader =
|
||||
(!isAppMetadataReady && isLoggedIn && !isOnExcludedPath) ||
|
||||
objectMetadataItems.length === 0;
|
||||
const shouldShowLoader = !isMinimalMetadataReady && !isOnExcludedPath;
|
||||
|
||||
if (shouldShowLoader) {
|
||||
return <UserOrMetadataLoader />;
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
import { useListenToMetadataOperationBrowserEvent } from '@/browser-event/hooks/useListenToMetadataOperationBrowserEvent';
|
||||
import { patchMetadataStoreFromSSEEvent } from '@/metadata-store/utils/patchMetadataStoreFromSSEEvent';
|
||||
import { useListenToEventsForQuery } from '@/sse-db-event/hooks/useListenToEventsForQuery';
|
||||
import { useStore } from 'jotai';
|
||||
import { AllMetadataName } from '~/generated-metadata/graphql';
|
||||
|
||||
export const FieldMetadataSSEEffect = () => {
|
||||
const queryId = 'field-metadata-sse-effect';
|
||||
|
||||
const store = useStore();
|
||||
|
||||
useListenToEventsForQuery({
|
||||
queryId,
|
||||
operationSignature: {
|
||||
metadataName: AllMetadataName.fieldMetadata,
|
||||
variables: {},
|
||||
},
|
||||
});
|
||||
|
||||
useListenToMetadataOperationBrowserEvent({
|
||||
metadataName: AllMetadataName.fieldMetadata,
|
||||
onMetadataOperationBrowserEvent: (eventDetail) => {
|
||||
patchMetadataStoreFromSSEEvent(
|
||||
store,
|
||||
'fieldMetadataItems',
|
||||
eventDetail.operation,
|
||||
eventDetail.updatedCollectionHash,
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return null;
|
||||
};
|
||||
+18
-13
@@ -1,7 +1,7 @@
|
||||
import { useIsLogged } from '@/auth/hooks/useIsLogged';
|
||||
import { useHasAccessTokenPair } from '@/auth/hooks/useHasAccessTokenPair';
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { isAppMetadataReadyState } from '@/metadata-store/states/isAppMetadataReadyState';
|
||||
import { isMinimalMetadataReadyState } from '@/metadata-store/states/isMinimalMetadataReadyState';
|
||||
import { metadataStoreState } from '@/metadata-store/states/metadataStoreState';
|
||||
import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilyStateValue';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
@@ -10,8 +10,8 @@ import { useEffect } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { isWorkspaceActiveOrSuspended } from 'twenty-shared/workspace';
|
||||
|
||||
export const IsAppMetadataReadyEffect = () => {
|
||||
const isLoggedIn = useIsLogged();
|
||||
export const IsMinimalMetadataReadyEffect = () => {
|
||||
const hasAccessTokenPair = useHasAccessTokenPair();
|
||||
const currentUser = useAtomStateValue(currentUserState);
|
||||
const currentWorkspace = useAtomStateValue(currentWorkspaceState);
|
||||
const metadataStore = useAtomFamilyStateValue(
|
||||
@@ -23,7 +23,9 @@ export const IsAppMetadataReadyEffect = () => {
|
||||
metadataStoreState,
|
||||
'views',
|
||||
);
|
||||
const setIsAppMetadataReady = useSetAtomState(isAppMetadataReadyState);
|
||||
const setIsMinimalMetadataReady = useSetAtomState(
|
||||
isMinimalMetadataReadyState,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const hasActiveWorkspace = isWorkspaceActiveOrSuspended(currentWorkspace);
|
||||
@@ -31,23 +33,26 @@ export const IsAppMetadataReadyEffect = () => {
|
||||
const areObjectsLoaded = metadataStore.status === 'up-to-date';
|
||||
const areViewsLoaded = metadataStoreViews.status === 'up-to-date';
|
||||
|
||||
const isReady = !areObjectsLoaded
|
||||
? false
|
||||
: !hasAccessTokenPair ||
|
||||
(isDefined(currentUser) && (!hasActiveWorkspace || areViewsLoaded));
|
||||
|
||||
if (!areObjectsLoaded) {
|
||||
setIsAppMetadataReady(false);
|
||||
setIsMinimalMetadataReady(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const isReady =
|
||||
!isLoggedIn ||
|
||||
(isDefined(currentUser) && (!hasActiveWorkspace || areViewsLoaded));
|
||||
|
||||
setIsAppMetadataReady(isReady);
|
||||
if (isReady) {
|
||||
setIsMinimalMetadataReady(true);
|
||||
}
|
||||
}, [
|
||||
isLoggedIn,
|
||||
hasAccessTokenPair,
|
||||
currentUser,
|
||||
currentWorkspace,
|
||||
metadataStore.status,
|
||||
metadataStoreViews.status,
|
||||
setIsAppMetadataReady,
|
||||
setIsMinimalMetadataReady,
|
||||
]);
|
||||
|
||||
return null;
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
import { ObjectMetadataProviderInitialEffect } from '@/metadata-store/effect-components/ObjectMetadataProviderInitialEffect';
|
||||
import { UserMetadataProviderInitialEffect } from '@/metadata-store/effect-components/UserMetadataProviderInitialEffect';
|
||||
import { ViewMetadataProviderInitialEffect } from '@/metadata-store/effect-components/ViewMetadataProviderInitialEffect';
|
||||
|
||||
export const MetadataProviderInitialEffects = () => (
|
||||
<>
|
||||
<UserMetadataProviderInitialEffect />
|
||||
<ObjectMetadataProviderInitialEffect />
|
||||
<ViewMetadataProviderInitialEffect />
|
||||
</>
|
||||
);
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import { useListenToMetadataOperationBrowserEvent } from '@/browser-event/hooks/useListenToMetadataOperationBrowserEvent';
|
||||
import { patchMetadataStoreFromSSEEvent } from '@/metadata-store/utils/patchMetadataStoreFromSSEEvent';
|
||||
import { mapAllMetadataNameToEntityKey } from '@/metadata-store/utils/mapAllMetadataNameToEntityKey';
|
||||
import { useStore } from 'jotai';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const MetadataStoreSSEEffect = () => {
|
||||
const store = useStore();
|
||||
|
||||
useListenToMetadataOperationBrowserEvent({
|
||||
onMetadataOperationBrowserEvent: (eventDetail) => {
|
||||
const entityKey = mapAllMetadataNameToEntityKey(eventDetail.metadataName);
|
||||
|
||||
if (!isDefined(entityKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
patchMetadataStoreFromSSEEvent({
|
||||
store,
|
||||
entityKey,
|
||||
operation: eventDetail.operation,
|
||||
updatedCollectionHash: eventDetail.updatedCollectionHash,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return null;
|
||||
};
|
||||
+45
-34
@@ -1,62 +1,73 @@
|
||||
import { useIsLogged } from '@/auth/hooks/useIsLogged';
|
||||
import { useHasAccessTokenPair } from '@/auth/hooks/useHasAccessTokenPair';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { isCurrentUserLoadedState } from '@/auth/states/isCurrentUserLoadedState';
|
||||
import { useLoadMinimalMetadata } from '@/metadata-store/hooks/useLoadMinimalMetadata';
|
||||
import { metadataStoreState } from '@/metadata-store/states/metadataStoreState';
|
||||
import { useLoadMockedMinimalMetadata } from '@/metadata-store/hooks/useLoadMockedMinimalMetadata';
|
||||
import { useLoadStaleMetadataEntities } from '@/metadata-store/hooks/useLoadStaleMetadataEntities';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useStore } from 'jotai';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { isWorkspaceActiveOrSuspended } from 'twenty-shared/workspace';
|
||||
|
||||
type LoadedState = 'none' | 'mocked' | 'real';
|
||||
|
||||
const computeDesiredLoadState = (
|
||||
hasAccessTokenPair: boolean,
|
||||
isActiveWorkspace: boolean,
|
||||
): LoadedState => {
|
||||
if (hasAccessTokenPair && isActiveWorkspace) {
|
||||
return 'real';
|
||||
}
|
||||
|
||||
return 'mocked';
|
||||
};
|
||||
|
||||
export const MinimalMetadataLoadEffect = () => {
|
||||
const isLoggedIn = useIsLogged();
|
||||
const hasAccessTokenPair = useHasAccessTokenPair();
|
||||
const isCurrentUserLoaded = useAtomStateValue(isCurrentUserLoadedState);
|
||||
const currentWorkspace = useAtomStateValue(currentWorkspaceState);
|
||||
const store = useStore();
|
||||
const [hasLoaded, setHasLoaded] = useState(false);
|
||||
const [loadedState, setLoadedState] = useState<LoadedState>('none');
|
||||
|
||||
const { loadMinimalMetadata } = useLoadMinimalMetadata();
|
||||
const { loadMockedMinimalMetadata } = useLoadMockedMinimalMetadata();
|
||||
const { loadStaleMetadataEntities } = useLoadStaleMetadataEntities();
|
||||
|
||||
const isActiveWorkspace = isWorkspaceActiveOrSuspended(currentWorkspace);
|
||||
|
||||
const desiredLoadState = computeDesiredLoadState(
|
||||
hasAccessTokenPair,
|
||||
isActiveWorkspace,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (hasLoaded) {
|
||||
if (!isCurrentUserLoaded || loadedState === desiredLoadState) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isCurrentUserLoaded || !isLoggedIn) {
|
||||
return;
|
||||
}
|
||||
setLoadedState(desiredLoadState);
|
||||
|
||||
if (!isWorkspaceActiveOrSuspended(currentWorkspace)) {
|
||||
return;
|
||||
}
|
||||
const performLoad = async () => {
|
||||
if (desiredLoadState === 'mocked') {
|
||||
await loadMockedMinimalMetadata();
|
||||
return;
|
||||
}
|
||||
|
||||
const objectsEntry = store.get(
|
||||
metadataStoreState.atomFamily('objectMetadataItems'),
|
||||
);
|
||||
const viewsEntry = store.get(metadataStoreState.atomFamily('views'));
|
||||
const result = await loadMinimalMetadata();
|
||||
|
||||
const hasObjectsFromStorage = objectsEntry.status === 'up-to-date';
|
||||
const hasViewsFromStorage = viewsEntry.status === 'up-to-date';
|
||||
|
||||
if (hasObjectsFromStorage && hasViewsFromStorage) {
|
||||
setHasLoaded(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const load = async () => {
|
||||
await loadMinimalMetadata();
|
||||
setHasLoaded(true);
|
||||
if (result?.staleEntityKeys && result.staleEntityKeys.length > 0) {
|
||||
await loadStaleMetadataEntities(result.staleEntityKeys);
|
||||
}
|
||||
};
|
||||
|
||||
load();
|
||||
performLoad();
|
||||
}, [
|
||||
hasLoaded,
|
||||
isCurrentUserLoaded,
|
||||
isLoggedIn,
|
||||
currentWorkspace,
|
||||
store,
|
||||
hasAccessTokenPair,
|
||||
isActiveWorkspace,
|
||||
desiredLoadState,
|
||||
loadedState,
|
||||
loadMinimalMetadata,
|
||||
loadMockedMinimalMetadata,
|
||||
loadStaleMetadataEntities,
|
||||
]);
|
||||
|
||||
return null;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user