Compare commits

...
Author SHA1 Message Date
ehconitin 1ffc244fae fix 2026-02-25 15:52:05 +05:30
martmullandGitHub e365b546d9 Deploy new cli version (#18216)
as title
2026-02-25 10:58:21 +01:00
martmullandGitHub f080b952eb Add manifest integration tests (#18203)
- add integration test on sync manifest endpoint
- fix invalid standard uuid + migration command
2026-02-25 10:37:50 +01:00
martmullandGitHub b84a8588be Fix function logs (#18215)
as title
2026-02-25 10:36:19 +01:00
martmullandGitHub e6a415b438 Fix twenty zapier (#18191)
as title
2026-02-25 10:35:46 +01:00
Charles BochetandGitHub d81f006979 Rename Jotai state hooks and utilities to consistent Atom-based naming (#18209)
## Summary

Rename all Jotai-based state management hooks and utilities to a
consistent naming convention that:
1. Removes legacy Recoil naming (`useRecoilXxxV2`, `createXxxV2`)
2. Always includes `Atom` in the name to distinguish from jotai native
hooks
3. Follows a consistent ordering: `Atom` → `Component` → `Family` →
`Type` (`State`/`Selector`)
4. Includes the type qualifier (`State` or `Selector`) in all
value-reading hooks to avoid naming conflicts with jotai's native
`useAtomValue`

## Naming Convention

**Hooks**:
`use[Set]Atom[Component][Family][State|Selector][Value|State|CallbackState]`
**Utils**: `createAtom[Component][Family][State|Selector]`

## Changes

### Hooks renamed (definition files + all usages across ~1,500 files):

| Old Name (Recoil) | Intermediate (Atom) | Final Name |
|---|---|---|
| `useRecoilValueV2` | `useAtomValue` | **`useAtomStateValue`** |
| `useRecoilStateV2` | `useAtomState` | `useAtomState` |
| `useSetRecoilStateV2` | `useSetAtomState` | `useSetAtomState` |
| `useFamilyRecoilValueV2` | `useFamilyAtomValue` |
**`useAtomFamilyStateValue`** |
| `useSetFamilyRecoilStateV2` | `useSetFamilyAtomState` |
**`useSetAtomFamilyState`** |
| `useFamilySelectorValueV2` | `useFamilySelectorValue` |
**`useAtomFamilySelectorValue`** |
| `useFamilySelectorStateV2` | `useFamilySelectorState` |
**`useAtomFamilySelectorState`** |
| `useRecoilComponentValueV2` | `useAtomComponentValue` |
**`useAtomComponentStateValue`** |
| `useRecoilComponentStateV2` | `useAtomComponentState` |
`useAtomComponentState` |
| `useSetRecoilComponentStateV2` | `useSetAtomComponentState` |
`useSetAtomComponentState` |
| `useRecoilComponentFamilyValueV2` | `useAtomComponentFamilyValue` |
**`useAtomComponentFamilyStateValue`** |
| `useRecoilComponentFamilyStateV2` | `useAtomComponentFamilyState` |
`useAtomComponentFamilyState` |
| `useSetRecoilComponentFamilyStateV2` |
`useSetAtomComponentFamilyState` | `useSetAtomComponentFamilyState` |
| `useRecoilComponentSelectorValueV2` | `useAtomComponentSelectorValue`
| `useAtomComponentSelectorValue` |
| `useRecoilComponentFamilySelectorValueV2` |
`useAtomComponentFamilySelectorValue` |
`useAtomComponentFamilySelectorValue` |
| `useRecoilComponentStateCallbackStateV2` |
`useAtomComponentStateCallbackState` |
`useAtomComponentStateCallbackState` |
| `useRecoilComponentSelectorCallbackStateV2` |
`useAtomComponentSelectorCallbackState` |
`useAtomComponentSelectorCallbackState` |
| `useRecoilComponentFamilyStateCallbackStateV2` |
`useAtomComponentFamilyStateCallbackState` |
`useAtomComponentFamilyStateCallbackState` |
| `useRecoilComponentFamilySelectorCallbackStateV2` |
`useAtomComponentFamilySelectorCallbackState` |
`useAtomComponentFamilySelectorCallbackState` |

### Utilities renamed:

| Old Name (Recoil) | Final Name |
|---|---|
| `createStateV2` | **`createAtomState`** |
| `createFamilyStateV2` | **`createAtomFamilyState`** |
| `createSelectorV2` | **`createAtomSelector`** |
| `createFamilySelectorV2` | **`createAtomFamilySelector`** |
| `createWritableSelectorV2` | **`createAtomWritableSelector`** |
| `createWritableFamilySelectorV2` |
**`createAtomWritableFamilySelector`** |
| `createComponentStateV2` | **`createAtomComponentState`** |
| `createComponentFamilyStateV2` | **`createAtomComponentFamilyState`**
|
| `createComponentSelectorV2` | **`createAtomComponentSelector`** |
| `createComponentFamilySelectorV2` |
**`createAtomComponentFamilySelector`** |

## Details

- All definition files renamed to match new convention
- All import paths and usages updated across the entire `twenty-front`
package
- Jotai's native `useAtomValue` is aliased as `useJotaiAtomValue` in the
wrapper hook to avoid collision
- Legacy Recoil files in `state/utils/` and `component-state/utils/`
left untouched (separate naming scope)
- Typecheck passes cleanly
2026-02-25 01:55:46 +01:00
Charles BochetandGitHub eaf9fe27b2 Improve Jotai work (#18205) 2026-02-24 20:38:30 +01:00
Baptiste DevessierandGitHub b339c93699 Fix app env var fetching (#18199) 2026-02-24 20:20:33 +01:00
nitinandGitHub 887371054a Host-remote refresh token implementation (#18044) 2026-02-24 19:37:29 +01:00
Raphaël BosiandGitHub b56f85f36a Allow video, audio and iFrame in front components (#18200)
Allow video, audio and iFrame in front components

+ fix css style properties starting with `--`
2026-02-24 19:04:52 +01:00
1ed13182d0 i18n - translations (#18197)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-24 18:10:28 +01:00
20d997bc5a Fix: Password validation requires data and hash arguments (#18189)
## Automated fix for [bug 5360](https://sonarly.com/issue/5360?type=bug)

**Severity:** `critical`

### Summary
When an existing user created via OAuth (with no password hash) attempts
to sign in through the signInUp password flow, their null passwordHash
is passed directly to bcrypt.compare, which throws an unhandled 'data
and hash arguments required' error instead of a user-friendly message.

### User Impact
Users who originally registered via Google or Microsoft OAuth and then
attempt to sign in using email/password through the signInUp flow cannot
authenticate. They see a server error instead of a helpful message like
'User was not created with email/password'. This blocks the user from
accessing the CRM entirely.

### Root Cause
Proximate cause: bcrypt.compare() at auth.util.ts:19 throws 'data and
hash arguments required' because the passwordHash argument is null.

1. Why did bcrypt throw? Because compareHash() was called with a null
passwordHash value. The compareHash function at auth.util.ts:19 passes
its arguments directly to bcrypt.compare without any null check.

2. Why was passwordHash null? Because SignInUpService.validatePassword()
at sign-in-up.service.ts:154 received a null passwordHash from
AuthService.validatePassword() at auth.service.ts:232. The value
userData.existingUser.passwordHash is null for users who were originally
created via an OAuth provider (Google, Microsoft) and never set a
password.

3. Why was there no null check before calling bcrypt? Because
AuthService.validatePassword() at line 229-233 does not check whether
userData.existingUser.passwordHash is null before passing it to
signInUpService.validatePassword(). The TypeScript type annotation says
passwordHash is string, but the UserEntity column is declared nullable:
true (user.entity.ts:73), so the runtime value can be null despite the
type system.

4. Why does this code path lack the null check when another path has it?
The validateLoginWithPassword() method at auth.service.ts:177 correctly
checks if (!user.passwordHash) and throws a user-friendly AuthException
'Incorrect login method'. This guard was added by Thomas Trompette on
2024-08-07 (commit 2abb6adb61). However, the signInUp flow's
validatePassword() method was introduced later by Antoine Moreaux on
2025-03-17 (commit bda835b9f8) without replicating this same defensive
check.

5. Why was this not caught? The signInUp validatePassword method was
written assuming the existingUser would always have a passwordHash when
the auth provider is Password. This assumption is incorrect because the
signInUp flow can match an existing OAuth-created user (who has no
passwordHash) when someone tries to sign up with email/password using an
email already registered via OAuth. No test covers this cross-provider
scenario in the signInUp path.

Root cause: The AuthService.validatePassword() method
(auth.service.ts:229-233) in the signInUp code path is missing a null
guard on userData.existingUser.passwordHash before passing it to
bcrypt.compare. The fix should check for null/undefined passwordHash and
throw a descriptive AuthException, mirroring the existing guard in
validateLoginWithPassword at line 177.

**Introduced by:** Antoine Moreaux on 2025-03-17 in commit
[`bda835b`](https://github.com/twentyhq/twenty/commit/bda835b9f82)

### Suggested Fix
Added a null check on userData.existingUser.passwordHash inside the
validatePassword private method of AuthService, immediately before
calling signInUpService.validatePassword. When passwordHash is null or
undefined (i.e. the user was created via OAuth and never set a
password), an AuthException with code INVALID_INPUT is thrown with the
user-friendly message 'User was not created with email/password'. This
mirrors the identical guard that already exists in
validateLoginWithPassword at line 177, preventing bcrypt.compare from
receiving a null argument and crashing with an unhandled error.

### Evidence
- **Code:**
[packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts:229
- if (userData.type === 'existingUser')
{](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts#L229)

---
*Generated by [Sonarly](https://sonarly.com)*

Co-authored-by: Sonarly Claude Code <claude-code@sonarly.com>
2026-02-24 17:52:53 +01:00
Charles BochetandGitHub 0f2af6a6cb Jotai 13 (#18178)
## Recoil to Jotai Migration — PR 13: Workflow, Page Layout, AI,
Activities, Settings, SSE & Remaining Modules

### Summary

This is the 13th PR in the [14-PR migration
series](packages/twenty-front/src/modules/ui/utilities/state/jotai/MIGRATION_PLAN.md)
to replace Recoil with Jotai as the state management library in
`twenty-front`. This PR migrates the remaining consumer code across all
modules — updating ~1,076 files with ~10k insertions/deletions.

### What changed

**New Jotai infrastructure (13 new files):**
- `createComponentSelectorV2` and `createComponentFamilySelectorV2` —
instance-scoped derived atoms, replacing Recoil's component selectors
- 6 new hooks: `useRecoilComponentSelectorValueV2`,
`useRecoilComponentFamilySelectorValueV2`,
`useRecoilComponentSelectorCallbackStateV2`,
`useRecoilComponentFamilySelectorCallbackStateV2`,
`useRecoilComponentStateCallbackStateV2`,
`useRecoilComponentFamilyStateCallbackStateV2`
- New types: `ComponentSelectorV2`, `ComponentFamilySelectorV2`,
`SelectorCallbacksV2`
- Extended `buildGetHelper` to support the new selector patterns

**State definition migrations:**
- `createState()` → `createStateV2()` (Jotai `atom()`)
- `createFamilyState()` → `createFamilyStateV2()` (Jotai `atom()` with
family cache)
- Recoil `selector`/`selectorFamily` → Jotai derived `atom()` via V2
utilities

**Hook migrations (~2,400 removed, ~1,545 added V2 equivalents):**
- `useRecoilValue` → `useRecoilValueV2`
- `useRecoilState` → `useRecoilStateV2`
- `useSetRecoilState` → `useSetRecoilStateV2`
- `useRecoilCallback` → `useCallback` + `jotaiStore.get/set`
- `useRecoilComponentValue` → `useRecoilComponentValueV2`
- `useSetRecoilComponentState` → `useSetRecoilComponentStateV2`
- `useRecoilComponentFamilyValue` → `useRecoilComponentFamilyValueV2` /
`useFamilySelectorValueV2`
- ~397 direct `import from 'recoil'` removed

**Deleted files (9 files):**
- `dateLocaleState.ts` — consolidated
- `currentAIChatThreadTitleStateV2.ts` — renamed to replace the original
- `isCommandMenuOpenedState.ts` — removed
- `filesFieldUploadState.ts` — replaced by V2
- `recordStoreFamilySelector.ts`, `recordStoreFieldValueSelector.ts`,
`recordStoreRecordsSelector.ts` — replaced by V2 equivalents
- `settingsAllRolesSelector.ts` — replaced by `useSettingsAllRoles` hook
- `settingsRoleIdsStateV2.ts` — consolidated

**Modules migrated:**
- Workflow (diagram, steps, variables, filters)
- Page Layout (widgets, fields, graph, tabs)
- AI (chat, agents, browsing context)
- Activities (rich text editor, targets, timeline)
- Action Menu (single/multiple record actions)
- Command Menu (navigation, history, pages, workflow)
- Context Store
- Record Board, Record Table, Record Calendar, Record Index
- Record Field, Record Filter, Record Sort, Record Group
- Record Drag, Record Picker, Record Store
- Views (view bar, view picker, filters, sorts)
- Settings (roles, permissions, SSO, security, data model, developers,
domains)
- SSE (event streams, subscriptions)
- Spreadsheet Import
- Auth, Favorites, Front Components, Information Banner
2026-02-24 17:37:01 +01:00
Paul RastoinandGitHub c6ec764b23 Fix ci-server ci (#18180) 2026-02-24 12:51:46 +01:00
959cbfb725 i18n - translations (#18183)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-24 12:08:42 +01:00
Félix MalfaitandGitHub 458a61ed30 Change runner from depot-ubuntu-24.04 to ubuntu-latest (#18182) 2026-02-24 10:17:38 +01:00
9a3852bf04 feat: add two-layer AI model availability filtering (#18170)
## Summary

- **Admin-level filtering**: New AI tab in admin panel with server-wide
model availability controls (whitelist/blacklist via
`AI_AUTO_ENABLE_NEW_MODELS`, `AI_DISABLED_MODEL_IDS`,
`AI_ENABLED_MODEL_IDS` config variables). Dedicated
`setAdminAiModelEnabled` mutation replaces frontend config-variable
manipulation. Filter dropdown to show/hide unconfigured and deprecated
models.
- **Workspace-level filtering**: Per-workspace controls with "Use best
models only" mode (curated list backed by `isRecommended` flag), or
custom whitelist/blacklist. Separate Smart/Fast model selectors with
"Best (...)" virtual options.
- **Security enforcement**: Both layers enforced at every backend
execution point — workspace update, agent create/update, chat execution.
Model ID validated against known models before config mutation. All
admin endpoints protected by `AdminPanelGuard`.

## Changes

### Backend (`twenty-server`)
- New config variables for admin-level model filtering
- `AiModelRegistryService`: `getAllModelsWithStatus()`,
`setModelAdminEnabled()` with model ID validation,
`isModelAdminAllowed()`
- `AdminPanelResolver`: `getAdminAiModels` query,
`setAdminAiModelEnabled` mutation
- `WorkspaceEntity`: new fields (`autoEnableNewAiModels`,
`disabledAiModelIds`, `enabledAiModelIds`, `useRecommendedModels`)
- `WorkspaceService`: model validation on `smartModel`/`fastModel`
updates
- `AgentResolver`: model availability checks on create/update
- `isModelAllowedByWorkspace` centralized utility
- `isRecommended` flag on model definitions
- Two TypeORM migrations

### Frontend (`twenty-front`)
- New `SettingsAdminAI` component with search, filter dropdown
(unconfigured/deprecated), and model toggle cards
- AI tab added to admin panel navigation
- `useWorkspaceAiModelAvailability` hook for workspace-level filtering
- `SettingsAIModelsTab` redesigned: merged sections, "Use best models
only" toggle, conditional available models list
- `getModelIcon`/`getModelProviderLabel` shared utilities with GraphQL
enum casing normalization
- Updated generated GraphQL types and mock data

## Test plan
- [ ] Toggle models on/off in admin panel AI tab and verify they
appear/disappear in workspace settings
- [ ] Enable "Use best models only" in workspace settings and verify
only recommended models are selectable
- [ ] Disable recommended mode and verify whitelist/blacklist toggles
work correctly
- [ ] Verify deprecated models hidden by default, shown greyed out when
filter enabled
- [ ] Verify unconfigured models hidden by default, shown disabled when
filter enabled
- [ ] Try setting a disabled model as Smart/Fast model — should be
rejected
- [ ] Try creating an agent with a disabled model — should be rejected
- [ ] Verify admin panel AI tab requires admin access


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-24 10:14:24 +01:00
c369baf63a i18n - translations (#18176)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-24 10:07:16 +01:00
Paul RastoinandGitHub 9e8024a07a Restore depot (#18179) 2026-02-24 09:59:54 +01:00
a827681306andGitHub df196b4a03 fix: use default Apollo client for AI chat file upload (#18158)
## Summary

Fix file uploads in AI chat (Agent Chat) failing with "Failed to upload
file" for all file types.

## Root Cause

`useAIChatFileUpload.ts` was using `useApolloCoreClient()` which points
to the `/graphql` (workspace) endpoint. However, `FileUploadResolver` is
decorated with `@MetadataResolver()`, meaning `uploadFile` is only
registered on the `/metadata` endpoint.

## Fix

Replace `useApolloCoreClient()` with `useApolloClient()` from
`@apollo/client`, which is the default Apollo client pointing to the
`/metadata` endpoint. This is consistent with how
`useUploadAttachmentFile.tsx` handles file uploads.

## Changes

- Replaced `useApolloCoreClient` import with `useApolloClient` from
`@apollo/client`
- Updated the client variable to use the default Apollo client
- Removed unused `useApolloCoreClient` import

Fixes #18153
2026-02-24 09:54:29 +01:00
Paul RastoinandGitHub af0af0a237 Fix cross app installation (#18151)
# Introduction
- Fixing app dependencyFlatEntityMaps load ( to load current app +
dependent app )
- Fix empty flat entity maps and undefined optimistic override
- Refactor the optimistic rendering to be mutation oriented at
orchestrator level
2026-02-23 19:58:06 +01:00
Charles BochetandGitHub 0d4fe4575b Various SDK improvements (#18115)
## Summary

- **Refactor frontend metadata loading architecture**: Split the
monolithic `EagerMetadataLoadEffect` into focused provider effects
(`UserMetadataProviderEffect`, `ObjectMetadataProviderEffect`,
`ViewMetadataProviderEffect`) orchestrated by `MetadataProviderEffects`.
Replaced `UserProvider` + `ObjectMetadataItemsProvider` with a single
`MetadataGater` that gates rendering on `isAppMetadataReadyState`. The
metadata store now validates view-object consistency before promoting
views, and `updateDraft` skips no-op updates via deep equality checks.

- **SDK CLI improvements**: Added `app:typecheck` command, improved
error handling in API sync (extracts GraphQL error messages), added
`serializeError` utility for human-readable error output, added `error`
file status to dev mode orchestrator with UI support, and fixed
ClickHouse migration/seed commands to use `transpile-only`.
2026-02-23 19:57:02 +01:00
Thomas TrompetteandGitHub ccddd105d8 Add generate key command (#18171)
Will be useful to auto log users on app creation
2026-02-23 19:56:44 +01:00
e21a7e11b2 i18n - translations (#18175)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-23 19:56:31 +01:00
WeikoandGitHub 1ac87d106e With RLS predicates on Select, only show possible values in option picker (#18166)
## Context
Removing SELECT/MULTI_SELECT options that can't be selected due to RLS
(see https://github.com/twentyhq/core-team-issues/issues/2226)

<img width="521" height="276" alt="Screenshot 2026-02-23 at 11 30 21"
src="https://github.com/user-attachments/assets/238ff596-cd8c-4660-a709-3eb2486e23b4"
/>
<img width="279" height="200" alt="Screenshot 2026-02-23 at 11 30 03"
src="https://github.com/user-attachments/assets/7a627d74-7519-4314-9a0e-0890cb8cbf30"
/>
2026-02-23 19:25:58 +01:00
CopilotGitHubcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>DevessierBaptiste Devessier
9a0295fd3d feat: add atomic upsertFieldsWidget mutation to replace multiple view field group/field API calls (#18137)
The `useSaveFieldsWidgetGroups` hook was making multiple sequential API
calls per widget (create groups, delete groups, update groups, update
fields) — non-atomic, chatty, and with heavy diff computation on the
frontend.

## Backend

- **New input DTOs**: `UpsertFieldsWidgetInput` /
`UpsertFieldsWidgetGroupInput` / `UpsertFieldsWidgetFieldInput` — caller
passes the full desired state of groups + fields for a widget
- **`FieldsWidgetUpsertService`**: looks up widget → resolves `viewId`,
diffs against existing flat entity maps, builds optimistic group maps so
newly-created groups can be referenced by field updates in the same
pass, then runs creates/updates/deletes in a single
`validateBuildAndRunWorkspaceMigration` call
- **`upsertFieldsWidget` mutation** added to `ViewFieldGroupResolver`;
new `FIELDS_WIDGET_NOT_FOUND` exception code added and wired into the
GraphQL exception filter

## Frontend

- New `UPSERT_FIELDS_WIDGET` GQL document
- `useSaveFieldsWidgetGroups` replaces all per-operation calls with a
single mutation per widget, passing the full draft state — diff logic
moves entirely to the backend

```graphql
mutation UpsertFieldsWidget($input: UpsertFieldsWidgetInput!) {
  upsertFieldsWidget(input: $input) {
    id
    name
    position
    isVisible
    viewId
    viewFields { id isVisible position ... }
  }
}
```

Widget IDs are collected from both draft **and** persisted state so
widgets whose draft groups were cleared still trigger deletion of their
server-side groups.

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

Start implementation

The user has attached the following file paths as relevant context:
 - CLAUDE.md

<analysis>
[Chronological Review: The conversation began with the user requesting a
review of how updates on views are stored in the frontend of record page
layouts. The user expressed a desire to migrate heavy computations and
multiple requests from the frontend to the backend. They proposed
creating a custom upsertFieldsWidget mutation to handle updates
atomically. The conversation has focused on this migration strategy and
its implementation.]

[Intent Mapping: The user explicitly requested to "check how we store
updates on views in the frontend of record page layouts" and indicated a
need to "migrate this task to the backend" by creating a custom mutation
for atomic updates.]

[Technical Inventory: The conversation involves the following technical
concepts:
- Frontend and backend architecture for handling page layout updates.
- Custom GraphQL mutation (upsertFieldsWidget) for atomic updates.
- The file in focus is page-layout-update.service.ts, which is likely
responsible for handling updates related to page layouts in the
backend.]

[Code Archaeology: The specific file being worked on is
/Users/devessier/Web/twenty/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts.
The user is likely looking to modify or enhance this service to
accommodate the new mutation for handling updates.]

[Progress Assessment: The user has identified the need for a backend
migration strategy but has not yet implemented any changes. The focus is
on planning the transition from frontend to backend processing.]

[Context Validation: All critical information for continuation is
captured, including the user's intent to migrate computations to the
backend and the specific file being modified.]

[Recent Commands Analysis: The last agent commands involved checking the
current file context and the user's request to summarize the
conversation. No specific tool results were generated as the focus was
on summarizing the conversation history. The agent was actively working
on summarizing the conversation when the token budget was exceeded,
which was triggered by the user's request for a summary.]

</analysis>

<summary>
1. Conversation Overview:
- Primary Objectives: The user requested to "check how we store updates
on views in the frontend of record page layouts" and expressed a desire
to "migrate this task to the backend" by creating a custom
upsertFieldsWidget mutation for atomic updates.
- Session Context: The conversation has focused on the need to shift
heavy computations from the frontend to the backend, with an emphasis on
implementing a new mutation to streamline updates.
- User Intent Evolution: The user's needs have remained consistent,
focusing on backend migration for efficiency and atomicity in updates.

2. Technical Foundation:
- Core Technology: The conversation involves a backend service likely
built with Node.js and TypeScript, as indicated by the file path.
- Framework/Library: The use of GraphQL for handling mutations is
implied through the mention of a custom mutation.
- Architectural Pattern: The user is looking to implement a
service-oriented architecture where the backend handles complex
computations instead of the frontend.
- Environment Detail: The current working file is located in a server
package of the twenty repository.

3. Codebase Status:
- File Name: page-layout-update.service.ts
- Purpose: This file is responsible for managing updates related to page
layouts in the backend.
- Current State: The user is considering modifications to implement a
new mutation for handling updates.
- Key Code Segments: Specific functions or classes have not been
detailed yet, as the focus is on planning changes.
- Dependencies: This service likely interacts with other components in
the metadata-modules related to page layouts.

4. Problem Resolution:
- Issues Encountered: The current challenge is the inefficiency of
handling updates in the frontend.
- Solutions Implemented: The proposed solution is to create a custom
mutation to handle updates atomically in the backend.
- Debugging Context: No ongoing troubleshooting efforts have been
mentioned yet.
- Lessons Learned: The need for backend processing to improve
performance has been highlighted.

5. Progress Tracking:
- Completed Tasks: No tasks have been completed yet; the user is in the
planning phase.
- Partially Complete Work: The user is preparing to implement a new
mutation for backend updates.
- Validated Outcomes: No features have been confirmed working through
testing at this stage.

6. Active Work State:
- Current Focus: The user is focused on modifying the
page-layout-update.service.ts to implement the new mutation.
- Recent Context: The last few exchanges involved discussing the
migration of update tasks from the frontend to the backend.
- Working Code: No specific code snippets have been modified yet, as the
co...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

Created from [VS
Code](https://code.visualstudio.com/docs/copilot/copilot-coding-agent).

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
Co-authored-by: Baptiste Devessier <baptiste@devessier.fr>
2026-02-23 19:25:47 +01:00
a0c0e7de25 [FRONT COMPONENTS] Add snackbar to the API (#18136)
## PR description

- Adds `enqueueSnackbar` to the front component host communication API,
allowing front components to display snack bar notifications (success,
error, info, warning) to the user.
- Introduces `frontComponentId` to the `FrontComponentExecutionContext`
and a `useFrontComponentId` hook, enabling front components to identify
themselves (used for dedupe keys).
- Wires error/success notifications into the `Action`, `ActionLink`, and
`ActionOpenSidePanelPage` SDK components -> actions now catch errors and
display them as snack bars, and `Action` supports an optional
`notifyOnEnd` prop for success feedback.

## Video QA

### Success example


https://github.com/user-attachments/assets/8cc53d31-d9eb-49a8-9220-f7866ec1b415

### Error example


https://github.com/user-attachments/assets/a37d65b8-0b5f-4adb-bcdb-571bb2b997c3

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-02-23 12:25:05 +01:00
EtienneGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
7cbbd082e3 Billing - Fix (#18135)
Context : https://github.com/twentyhq/private-issues/issues/425
Try to fix https://github.com/twentyhq/core-team-issues/issues/2158

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-23 12:13:19 +01:00
Charles BochetandGitHub 7944ca29fa Fix CI (#18168)
Fix 2 issues on CI:
- website still using ubuntu-latest
- linter that cannot use more than 2GB
2026-02-23 12:05:53 +01:00
b51eb6471f Jotai 12 (#18160)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-23 12:01:37 +01:00
Raphaël BosiandGitHub 22bc3004b9 [FRONT COMPONENTS] Add loader to command menu items (#18165)
## PR description

- Add a loader to the command menu items when the action is running.
- Add a new method `closeSidePanel` to the front component host api.

## Video QA


https://github.com/user-attachments/assets/c20b592a-6e4c-4cab-b5da-4cb2316acc7c
2026-02-23 11:15:45 +01:00
Charles BochetandGitHub 129d1ede86 Change runners temp (#18163)
Temporarily moving all ubuntu-latest 1 core to depot except ci-website
2026-02-23 10:53:31 +01:00
a2e3af5625 i18n - translations (#18156)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-22 15:40:35 +01:00
41f09c5a4c Add AI model pricing, Bedrock provider, and InferenceProvider/ModelFamily split (#18155)
## Summary

- **Model pricing overhaul**: All model constants updated with accurate
pricing in dollars per 1M tokens, including cached input rates, cache
creation rates, and tiered >200k context pricing
- **New providers**: Added Google (Gemini 3.x), Mistral, and AWS Bedrock
as inference providers. Bedrock serves Claude Opus 4.6 and Sonnet 4.6
via AWS, with proper credential handling following the existing S3/SES
pattern
- **InferenceProvider/ModelFamily split**: Refactored `ModelProvider`
into two orthogonal enums — `InferenceProvider` (who serves the model:
auth, SDK, metadata format) and `ModelFamily` (who created it: token
counting semantics). This eliminates growing `||` chains for token
normalization checks like `excludesCachedTokens`
- **Billing improvements**: Reasoning tokens charged at output rate,
cache token discounts applied accurately, real errors thrown to Sentry
on billing failures

## Test plan

- [x] All existing unit tests updated and passing (23 tests across 3
test files)
- [x] Lint passes for both twenty-server and twenty-front
- [ ] CI checks pass


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-22 14:39:04 +01:00
a900b4a4b4 i18n - docs translations (#18141)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-22 12:36:36 +01:00
020cf7f3e0 i18n - translations (#18146)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-22 12:36:23 +01:00
0bccdedb4f feat: design the ai-models tab on settings ai page (#18147)
Remove AI model selectors from the settings tab on AI settings page,
rename that tab to "More" and create a separate "Models" tab as per the
design.


https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=91311-278313&m=dev

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-02-22 11:41:26 +01:00
martmullandGitHub 088be4c47b Expose standard universal identifiers (#18152)
as title
2026-02-21 23:53:55 +00:00
ad88108b28 Update README: add E2B logo and improve heading (#18144)
## Summary
- Add E2B logo to the Thanks section (after Crowdin, same height)
- Rename section heading from "Does the world need another CRM?" to "Why
Twenty" for a more confident, direct tone

## Test plan
- [ ] Verify E2B logo renders correctly on GitHub README
- [ ] Confirm all other logos still display properly

Made with [Cursor](https://cursor.com)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-21 15:02:11 +01:00
Raphaël BosiandGitHub 58e8b466f3 Fix frontComponentHostCommunicationApi is not defined error (#18145)
Fix missing import
2026-02-20 18:49:03 +01:00
martmullandGitHub ba59ab8094 Add upload file in twenty client (#18129)
This function 

```typescript
import { defineLogicFunction } from 'twenty-sdk';
import TwentyClient from 'twenty-sdk/generated';

import { v4 } from 'uuid';

export const POST_INSTALL_UNIVERSAL_IDENTIFIER =
  '1312be5c-4fd6-44b3-afd0-567352616c7c';

const handler = async (): Promise<any> => {
  const client = new TwentyClient();

  const seedResult = await client.mutation({
    createCompany: {
      id: true,
      name: true,
      __args: {
        data: {
          name: `toto + ${v4()}`,
        },
      },
    },
  });

  const companyFieldUniversalIdentifier =
    '20202020-15db-460e-8166-c7b5d87ad4be';

  const uploadFileResult = await client.uploadFile(
    Buffer.from('hello world', 'utf-8'),
    'test.txt',
    undefined,
    companyFieldUniversalIdentifier,
  );

  await client.mutation({
    createAttachment: {
      id: true,
      __args: {
        data: {
          file: [{ fileId: uploadFileResult.id, label: 'hello-world.txt' }],
          fullPath: uploadFileResult.path,
          targetCompanyId: seedResult.createCompany?.id,
        },
      },
    },
  });

  return;
};

export default defineLogicFunction({
  universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
  name: 'post-install',
  description: 'Add a description for your logic function',
  timeoutSeconds: 30,
  handler,
});

```

produces this record below 

<img width="1512" height="859" alt="image"
src="https://github.com/user-attachments/assets/57dc3a6b-fd2c-4f21-8331-8f1f05403826"
/>
2026-02-20 17:11:59 +00:00
Thomas TrompetteandGitHub cd1a2712d5 Add server health check every 2 secs on app:dev (#18142)
https://github.com/user-attachments/assets/ff10503f-ebc0-417b-b0f3-8aa40dee74e2
2026-02-20 17:01:45 +00:00
Thomas TrompetteandGitHub 932adf8e4b Create view and navigation item on add-object command - to be tested (#18134)
<img width="580" height="141" alt="Capture d’écran 2026-02-20 à 15 52
11"
src="https://github.com/user-attachments/assets/40254d3a-f7f9-4f2a-a51f-c37dc1f5d167"
/>
2026-02-20 16:41:16 +00:00
Lucas BordeauandGitHub 26fabdc3d0 Minor fixes following up Temporal refactor (#18139)
Fixes https://github.com/twentyhq/core-team-issues/issues/2034
2026-02-20 15:54:38 +00:00
82617727a2 i18n - docs translations (#18131)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-20 16:33:06 +01:00
Raphaël BosiandGitHub 87922253f3 Fix front component cleanup (#18132)
Fix front component cleanup
2026-02-20 15:03:10 +00:00
Raphaël BosiandGitHub 7da8450075 [FRONT COMPONENTS] Headless components (#18096)
## Description

- Add `isHeadless` field to `FrontComponent` entity so front components
can run without rendering UI in the command menu
- Introduce headless front component mounting logic:
`HeadlessFrontComponentMountRoot` at the application root,
`useMountHeadlessFrontComponent`, and `useUnmountHeadlessFrontComponent`
hooks to mount/unmount headless components
- Expand the SDK with new action components (`Action`, `ActionLink`,
`ActionOpenSidePanelPage`) and host communication functions
(`openSidePanelPage`, `unmountFrontComponent`)
- Move `CommandMenuPages` type to twenty-shared so the SDK can reference
it for side panel navigation

## Video QA



https://github.com/user-attachments/assets/4f9e3bb1-fcd1-42be-b3f4-a97e80c2add2
2026-02-20 14:14:42 +00:00
d444648cc0 i18n - translations (#18127)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-20 14:41:58 +01:00
ec57d3fe0f Fix flaky 2FA encryption test for AES-256-CBC wrong-key behavior (#18126)
## Summary

- Fixes a flaky test in `simple-secret-encryption.util.spec.ts` that
fails ~1 in 256 runs
- AES-256-CBC doesn't guarantee wrong-key decryption throws — PKCS7
padding validation is probabilistic. When padding accidentally looks
valid, decryption silently returns garbage instead of throwing.
- Changed the test to verify the correct security property: wrong-key
decryption must never return the original secret (both throw and garbage
are acceptable)
- Audited both production `decryptSecret` call sites in
`two-factor-authentication.service.ts` — they always use the correct
key, so end users are not affected

## Test plan

- [x] Test passes 5/5 consecutive runs locally
- [x] Lint passes


Made with [Cursor](https://cursor.com)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-20 14:41:31 +01:00
Baptiste DevessierandGitHub 00209f7e2c Wire fields widget to backend + basic edition (#17965)
Closes https://github.com/twentyhq/core-team-issues/issues/2215
Closes https://github.com/twentyhq/core-team-issues/issues/2216
Closes https://github.com/twentyhq/core-team-issues/issues/2218

## Fields widget edition demo


https://github.com/user-attachments/assets/08626d70-8fcb-4ae2-9222-10ef57e75f90

## Dashboards still work


https://github.com/user-attachments/assets/aa9a9c45-a0a2-481e-b132-bc52254778da
2026-02-20 13:18:00 +00:00
b107020ad3 Fix search edge case with permissions (#18123)
Fix E2E tests

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-20 14:08:20 +01:00
9f3f2e21d8 i18n - docs translations (#18122)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-20 13:51:43 +01:00
21472da38f i18n - translations (#18120)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-20 13:51:34 +01:00
Paul RastoinandGitHub bf1e0d0811 Typecheck main sdk (#18124) 2026-02-20 13:47:57 +01:00
Abdullah.andGitHub 917a36821a fix: hover appearing on not shared for junction relations (#18058)
Hovering over "Not Shared" in junction relations shows the placeholder
text.

<img width="1039" height="862" alt="image"
src="https://github.com/user-attachments/assets/a9523f51-c417-41b0-9926-d154c9601fd8"
/>

<br />
<br />

This PR fixes it.

<img width="1040" height="860" alt="image"
src="https://github.com/user-attachments/assets/09d5fecf-1faa-449d-86d9-a105464d31c3"
/>
2026-02-20 13:16:49 +01:00
66da296799 Unify MCP into single endpoint with lazy tool discovery (#18113)
## Summary

- Consolidates the MCP server from two endpoints (`/mcp` +
`/mcp/metadata`) into a **single `POST /mcp`** endpoint exposing five
high-level tools: `get_tool_catalog`, `learn_tools`, `execute_tool`,
`load_skills`, and `search_help_center`
- Fixes **DATABASE_CRUD tools not accessible via API key auth** by
removing an unnecessary `userId`/`userWorkspaceId` guard in
`DatabaseToolProvider` and threading `ApiKeyWorkspaceAuthContext`
through the tool context chain
- Improves tool descriptions with **STEP 1/2/3 workflow guidance** so AI
clients follow the correct discovery flow (catalog → learn → execute)
instead of guessing tool names
- Simplifies the **frontend AI settings** by removing the schema picker
dropdown (no more "Core Schema" vs "Metadata Schema" choice)

## Changes

### Backend
- **Deleted**: `mcp-metadata.controller.ts`, `mcp-metadata.service.ts`
(merged into core)
- **New**: `get-tool-catalog.tool.ts` — browsable, categorized tool
discovery
- **Fixed**: `DatabaseToolProvider.generateDescriptors` — removed guard
that blocked API key access to CRUD tools
- **Fixed**: `ToolContext` type + `ToolRegistryService` — `authContext`
now flows through so API key CRUD execution works end-to-end
- **Updated**: `McpProtocolService` — builds
`ApiKeyWorkspaceAuthContext` for API key requests
- **Updated**: All MCP tool descriptions with explicit step numbering

### Frontend
- **Simplified**: `SettingsAIMCP.tsx` — removed schema selector
dropdown, shows single MCP config

## Test plan
- [x] All 19 MCP unit tests pass (controller + protocol service)
- [x] Server and frontend lint clean
- [x] Server and frontend typecheck pass
- [x] Live-tested on localhost:3000 with API key: `get_tool_catalog`
returns 236 tools including 196 DATABASE_CRUD tools
- [x] Live-tested `execute_tool` with `find_companies` via API key —
returns real data
- [x] Tested MCP connection from Cursor IDE via project-level
`.cursor/mcp.json`

Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-20 13:09:54 +01:00
3bc887e12e Add default relation to standard object on custom object in manifest (#18033)
add default relation fields when creating an object from an application

---------

Co-authored-by: prastoin <paul@twenty.com>
2026-02-20 11:49:06 +01:00
Thomas TrompetteandGitHub d060c843d1 Remove sse feature flag (#18114)
As title
2026-02-20 11:46:03 +01:00
Paul RastoinandGitHub 175df59c21 Support Skill in manifest (#18092)
# Introduction
Support skill in manifest, pre-requisite for the twenty standard app
migration
2026-02-20 11:45:42 +01:00
6ad581d178 Fix global search for CJK and non-tokenizable text (#18030)
## Summary

Fixes #12962

- Adds a two-pass ILIKE fallback to the global search service
(`search.service.ts`)
- **Fast path**: runs the tsvector query first (uses GIN index,
sub-millisecond)
- **Fallback**: only if tsvector returns fewer results than the limit,
runs an ILIKE query on `searchVector::text` to catch cases where
PostgreSQL's `simple` text search config fails to tokenize (continuous
CJK text, etc.)
- Zero performance impact for the common case (Latin text where tsvector
works)
- Also adds `escapeForIlike` utility to properly escape `%`, `_`, `\` in
user input

### Why tsvector fails for CJK

PostgreSQL's `simple` config treats continuous CJK text as a single
lexeme:
- `to_tsvector('simple', '示例商业线索')` → `'示例商业线索':1`
- Searching `商业:*` only prefix-matches from the start, so it misses `商业`
in the middle

The ILIKE fallback catches these substring matches when the tsvector
path can't.

### What this fixes

- Global search (command menu / sidebar)
- Relation picker (single and multi-object)
- Morph relation picker

All three use `search.service.ts` under the hood.

Co-authored-by: mykh-hailo (original direction in #18021)

## Test plan

- [ ] Search `示例` with records `示例商业线索` and `示例-商业-线索` → both should
appear
- [ ] Search `商业` → both should appear (previously only the hyphenated
one did)
- [ ] Search for Latin text (e.g. `john`) → same performance, results
unchanged
- [ ] Relation picker search with CJK text → results appear
- [ ] Search input with special chars like `%` or `_` → no SQL
injection, results correct


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: mykh-hailo <mykh-hailo@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-20 11:02:09 +01:00
neo773andGitHub 712b1553bd Fix participant matching failing due to updating all columns instead of only changed fields (#18105)
The updateMany in matchParticipants was spreading the entire participant
object into the SET clause, which included generated columns
(searchVector) and composite field columns (createdBySource) that can't
be written to. Narrowed the update to only set personId and
workspaceMemberId.
```
[1] query failed: UPDATE "workspace_3ixj3i1a5avy16ptijtb3lae3"."calendarEventParticipant" SET "id" = $1, "createdAt" = $2, "updatedAt" = $3, "deletedAt" = $4, "createdBySource" = $5, "createdByWorkspaceMemberId" = $6, "createdByName" = $7, "createdByContext" = $8, "updatedBySource" = $9, "updatedByWorkspaceMemberId" = $10, "updatedByName" = $11, "updatedByContext" = $12, "position" = $13, "searchVector" = $14, "handle" = $15, "displayName" = $16, "isOrganizer" = $17, "responseStatus" = $18, "calendarEventId" = $19, "personId" = $20, "workspaceMemberId" = $21 WHERE "id" = $22 RETURNING * -- PARAMETERS: ["f1526103-451a-429f-9743-3a81c3a3e3aa","2026-02-19T22:23:32.354Z","2026-02-19T22:23:32.354Z",null,"MANUAL",null,"System",null,"MANUAL",null,"System",null,0,"'test@test.com':1","test@test.com","",false,"NEEDS_ACTION","fb1892a8-6daf-435b-a43b-e8fe8693eb99","60bf9e82-f1b7-4bed-a1af-7039fb9c32f5",null,"f1526103-451a-429f-9743-3a81c3a3e3aa"]
[1] error: error: column "searchVector" can only be updated to DEFAULT
[1] Exception Captured
[1]   undefined
[1]   [
[1]     PostgresException [Error]: Data validation error.
[1]         at computeTwentyORMException (/Users/huzef/Documents/bounties/twenty/packages/twenty-server/dist/engine/twenty-orm/error-handling/compute-twenty-orm-exception.js:35:19)
[1]         at WorkspaceUpdateQueryBuilder.executeMany (/Users/huzef/Documents/bounties/twenty/packages/twenty-server/dist/engine/twenty-orm/repository/workspace-update-query-builder.js:269:82)
[1]         at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
[1]         at async WorkspaceRepository.updateMany (/Users/huzef/Documents/bounties/twenty/packages/twenty-server/dist/engine/twenty-orm/repository/workspace.repository.js:234:25)
[1]         at async MatchParticipantService.matchParticipants (/Users/huzef/Documents/bounties/twenty/packages/twenty-server/dist/modules/match-participant/match-participant.service.js:93:13)
[1]         at async /Users/huzef/Documents/bounties/twenty/packages/twenty-server/dist/modules/match-participant/match-participant.service.js:160:13
[1]         at async MatchParticipantService.matchParticipantsForPeople (/Users/huzef/Documents/bounties/twenty/packages/twenty-server/dist/modules/match-participant/match-participant.service.js:130:9)
[1]         at async CalendarEventParticipantMatchParticipantJob.handle (/Users/huzef/Documents/bounties/twenty/packages/twenty-server/dist/modules/calendar/calendar-event-participant-manager/jobs/calendar-event-participant-match-participant.job.js:45:13)
[1]         at async MessageQueueExplorer.invokeProcessMethods (/Users/huzef/Documents/bounties/twenty/packages/twenty-server/dist/engine/core-modules/message-queue/message-queue.explorer.js:113:17)
[1]         at async MessageQueueExplorer.handleProcessor (/Users/huzef/Documents/bounties/twenty/packages/twenty-server/dist/engine/core-modules/message-queue/message-queue.explorer.js:104:13) {
[1]       code: '428C9'
[1]     }
[1]   ]
```
2026-02-20 10:25:10 +01:00
sonarly[bot]GitHubSonarly Claude Codeclaude[bot] <41898282+claude[bot]@users.noreply.github.com>Etienne
cc1145c701 Fix: Person avatar upload fails with unknown field error (#18109)
## Automated fix for [bug None](https://sonarly.com/issue/None?type=bug)

**Severity:** `critical`

### Summary
When uploading a person avatar with the new FILES field migration
enabled, the optimistic record validation in
computeOptimisticRecordFromInput throws because the avatarFile field may
not be recognized in the person object metadata, crashing the upload
flow.

### User Impact
Users with the IS_FILES_FIELD_MIGRATED feature flag enabled cannot
upload or change a person's avatar photo. The upload operation throws an
unhandled error, preventing the avatar update from completing.

### Root Cause
The usePersonAvatarUpload hook passes avatarFile as a field in
updateOneRecordInput when calling updateOneRecord. This input goes
through computeOptimisticRecordFromInput, which validates that every
field in the record input exists in objectMetadataItem.fields. The
avatarFile field (type FILES) was recently added as a standard field on
the person object, but may not yet be present in the frontend's cached
object metadata for all workspaces (e.g., workspaces where the metadata
has not been synced after the migration, or SSE events arriving before
metadata refresh). When avatarFile is not found in the metadata fields
array, the validation throws. The useUpdateOneRecord hook supports an
optimisticRecord parameter that bypasses this validation entirely, but
usePersonAvatarUpload did not provide it.

Introduced by Etienne in commit d0c1841f0f on 2026-02-11, which added
the avatar file migration and upload logic but did not supply an
optimisticRecord to bypass the strict field validation in
computeOptimisticRecordFromInput.

**Introduced by:** Etienne on 2026-02-11 in commit
[`d0c1841`](https://github.com/twentyhq/twenty/commit/d0c1841f0f8a6a9069bbe2e9cafacf4ff6137f82)

### Suggested Fix
Pass an explicit optimisticRecord parameter when calling updateOneRecord
from usePersonAvatarUpload. The useUpdateOneRecord hook uses
optimisticRecord via nullish coalescing (optimisticRecord ??
computeOptimisticRecordFromInput(...)), so providing it bypasses the
strict field validation in computeOptimisticRecordFromInput entirely.
The avatarFile value is extracted into a shared variable to avoid
duplication between updateOneRecordInput and optimisticRecord.

---
*Generated by [Sonarly](https://sonarly.com)*

---------

Co-authored-by: Sonarly Claude Code <claude-code@sonarly.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Etienne <etiennejouan@users.noreply.github.com>
2026-02-20 08:27:53 +00:00
Félix MalfaitGitHubCursorclaude[bot] <41898282+claude[bot]@users.noreply.github.com>
726b1373d9 fix: convert metered tier upTo from internal to display credits in listPlans (#18108)
## Summary
- The `listPlans` GraphQL query was returning metered tier `upTo` values
in internal credit units (1000x the display value), causing "Credits by
period" and "Credit Plan" dropdowns to show "50M" instead of "50k"
- Applied the existing `INTERNAL_CREDITS_PER_DISPLAY_CREDIT` (1000)
divisor in `formatBillingDatabasePriceToMeteredPriceDTO`, matching the
conversion already used in `getMeteredProductsUsage` resolver
- Updated frontend mock data to reflect the corrected display-unit
values

## Test plan
- [x] Unit tests pass for `format-database-product-to-graphql-dto.util`
- [x] Unit tests pass for `metered-credit.service` and
`billing-credit-rollover.service`
- [ ] Verify billing page shows correct credit amounts (50k, not 50M)
for "Credits by period" and "Credit Plan"


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-02-20 09:44:11 +01:00
783e57f5d8 i18n - translations (#18100)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-19 21:14:57 +01:00
163254baef fix: laggy edition of FormNumberFieldInput (#18011)
### What this PR do ?

Stops the delay fields from updating the workflow on every keystroke by
keeping values locally and saving them on blur, which fixes the cached
relation error

Fixed #15709

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2026-02-19 17:16:25 +00:00
aaa6511007 feat: added workspace member filter for actor fields (#16628)
Closes #16619

This PR adds support for filtering ACTOR fields by `Workspace Member`
subfield, enabling users to filter records by who created them with a
`Me` option.

I replicated the same UX and code structure as the Relation field filter
for consistency.

Each filter selection triggers a server-side GraphQL call. But there is
client-side filtering in `isRecordMatchingFilter.ts` which instantly
filters already-loaded records while the server is fetching new results.
I replicated this behaviour from how `FULL_NAME` and other composite
fields handle filtering.


UX decision that were taken by me (Let me know if changes are needed) : 
- The filter shows comma separated selected workspace member names until
3 members are selected. After that it shows [no of selected members]
workspace members.

<img width="643" height="283" alt="Screenshot 2025-12-17 at 8 01 23 PM"
src="https://github.com/user-attachments/assets/18d524f4-979b-4d92-ad64-aa7b63be7897"
/>
<img width="774" height="309" alt="Screenshot 2025-12-17 at 8 01 33 PM"
src="https://github.com/user-attachments/assets/779f374f-1501-48f9-afa2-a78628e067b1"
/>
<img width="737" height="397" alt="Screenshot 2025-12-17 at 8 01 40 PM"
src="https://github.com/user-attachments/assets/4e8b963e-8a0f-467d-91ae-48bca4e1d842"
/>
<img width="697" height="334" alt="Screenshot 2025-12-17 at 8 01 53 PM"
src="https://github.com/user-attachments/assets/c9a0e4bb-48b4-486b-a4f9-d7c49ff3852c"
/>
<img width="684" height="343" alt="Screenshot 2025-12-17 at 8 02 04 PM"
src="https://github.com/user-attachments/assets/d5c45eba-06a3-40fc-b9d0-d585dc8bc136"
/>

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2026-02-19 16:56:40 +00:00
WeikoandGitHub 2a670520b9 Add page layout backfill command (#18095)
## Context
Command to backfill record page layouts and related entities for legacy
workspaces.

## Test
Set SHOULD_SEED_STANDARD_RECORD_PAGE_LAYOUTS=false, reset DB then run
the command and compare with Set
SHOULD_SEED_STANDARD_RECORD_PAGE_LAYOUTS=true on a different workspace
2026-02-19 16:24:20 +00:00
Charles BochetandGitHub 10bd005021 Rework types for logic function (#18074)
## Summary

- **Consolidate logic function services**: Remove
`LogicFunctionMetadataService` and consolidate all logic function CRUD
operations into `LogicFunctionFromSourceService`, with a new
`LogicFunctionFromSourceHelperService` for shared validation/migration
logic
- **Introduce typed conversion utils following the skill pattern**: Add
`fromCreateLogicFunctionFromSourceInputToUniversalFlatLogicFunctionToCreate`
and `fromUpdateLogicFunctionFromSourceInputToFlatLogicFunctionToUpdate`
that convert DTO inputs directly to flat entities
(`UniversalFlatLogicFunction` / `FlatLogicFunction`), replacing the
previous intermediate `UpdateLogicFunctionMetadataParams` indirection
- **Simplify `CodeStepBuildService`**: Remove ~100 lines of manual
duplication logic by delegating to
`LogicFunctionFromSourceService.duplicateOneWithSource`
- **Remove completed 1-17 migration**: Delete
`MigrateWorkflowCodeStepsCommand` and associated utils that migrated
workflow code steps from serverless functions to logic functions
2026-02-19 17:25:08 +01:00
0e25aeb5be chore: upgrade @swc/core to 1.15.11 and align SWC ecosystem (#18088)
## Summary

- Upgrades `@swc/core` from 1.13.3 to **1.15.11** (swc_core v56), which
introduces CBOR-based plugin serialization replacing rkyv, eliminating
strict version-matching between SWC core and Wasm plugins
- Upgrades `@lingui/swc-plugin` from ^5.6.0 to **^5.11.0** (swc_core
50.2.3, built with `--cfg=swc_ast_unknown` for cross-version
compatibility)
- Upgrades `@swc/plugin-emotion` from 10.0.4 to **14.6.0** (swc_core 53,
also with backward-compat feature)
- Upgrades companion packages: `@swc-node/register` 1.8.0 → 1.11.1,
`@swc/helpers` ~0.5.2 → ~0.5.18, `@vitejs/plugin-react-swc` 3.11.0 →
4.2.3

### Why this is safe now

Starting from `@swc/core v1.15.0`, SWC replaced the rkyv serialization
scheme with CBOR (a self-describing format) and added `Unknown` AST enum
variants. Plugins built with `swc_core >= 47` and
`--cfg=swc_ast_unknown` are now forward-compatible across `@swc/core`
versions. Both `@lingui/swc-plugin@5.10.1+` and
`@swc/plugin-emotion@14.0.0+` have this support, meaning the old
version-matching nightmare between Lingui and SWC is largely solved.

Reference: https://github.com/lingui/swc-plugin/issues/179

## Test plan

- [x] `yarn install` resolves without errors
- [x] `npx nx build twenty-shared` succeeds
- [x] `npx nx build twenty-ui` succeeds (validates
@swc/plugin-emotion@14.6.0)
- [x] `npx nx typecheck twenty-front` succeeds
- [x] `npx nx build twenty-front` succeeds (validates vite + swc +
lingui pipeline)
- [x] `npx nx build twenty-emails` succeeds (validates lingui plugin)
- [x] Frontend jest tests pass (validates @swc/jest +
@lingui/swc-plugin)
- [x] Server jest tests pass (validates server-side SWC + lingui)

Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-19 15:27:56 +00:00
BugIsGodandGitHub e051cce24f Fix: add a new style to the target text box (#18065)
### Approach
I add some new rules for the style of the target text box. (Fix: #13229
)
<img width="842" height="545" alt="target class"
src="https://github.com/user-attachments/assets/7cd0a615-392a-493b-831f-77ddb93de5fc"
/>


**This is what it looks like now.**
<img width="320" height="224" alt="image"
src="https://github.com/user-attachments/assets/26514102-e684-49ce-915d-43e5677520a5"
/>
2026-02-19 13:59:11 +00:00
Raphaël BosiandGitHub bd03073b6d [FRONT COMPONENTS] Declare command menu items in front components (#18047)
## Description

- Adds support for declaring command menu items directly within
`defineFrontComponent` via an optional command config property
- Introduces a new `CommandMenuItemManifest` type in twenty-shared and
wires it through the manifest build pipeline

## Example Of usage

```tsx
import { defineFrontComponent } from "twenty-sdk";

const TestAction = () => {
  return <div>Test Action</div>;
};

export default defineFrontComponent({
  universalIdentifier: "6c289461-0007-4a62-a99f-69e5c11a4ce7",
  name: "test-action",
  description: "Test Action",
  component: TestAction,
  command: {
    universalIdentifier: "c07df864-495f-46f3-9f5b-9d3ce2589e9b",
    label: "Run My Action",
    icon: "IconBolt",
    isPinned: false,
  },
});

```

## Video QA


https://github.com/user-attachments/assets/f910fc6a-44a9-45d1-87c5-f0ce64bb3878
2026-02-19 15:23:46 +01:00
EtienneandGitHub b3d8f8813f Remove non positive integer constraint on Nav Menu Item 2/2 (#18090)
Follow up https://github.com/twentyhq/twenty/pull/18081
2026-02-19 15:17:25 +01:00
WeikoandGitHub 37d9828458 Fix google compose scope not gated by feature flag (#18093)
## Context
New google api scope has been introduced in
https://github.com/twentyhq/twenty/pull/17793 without being gated behind
a feature flag

Microsoft is using pre-existing Mail.ReadWrite scope there is nothing to
gate

## Before
<img width="553" height="445" alt="Screenshot 2026-02-19 at 14 57 58"
src="https://github.com/user-attachments/assets/59a4f76b-d38d-492f-b013-b6cad4091a7f"
/>


## After
<img width="535" height="392" alt="Screenshot 2026-02-19 at 14 58 44"
src="https://github.com/user-attachments/assets/0337bf15-ec30-4549-bb9d-571a982dffd8"
/>
2026-02-19 15:16:54 +01:00
Thomas TrompetteGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
e16b6d6485 Create LLMS.md on create-twenty-app (#18091)
Managed to create a many to many app with minimal instructions. File
will need to be enriched with more pitfalls.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-19 14:51:31 +01:00
Paul RastoinandGitHub 9626c7ce02 Twenty standard app static options id (#18089)
# Introduction
While preparing the twenty-standard as code migration to twenty-app
through sdk I've faced permanent field enum update as the id was
generated dynamically at each twenty standard app construction
Making them deterministic in order to avoid having this noise

Won't backfill this on existing workspace as it's not critical and that
we will rework the options in the future
2026-02-19 13:19:09 +00:00
martmullandGitHub 754de411fe Factorize and add public-assets/*path endpoint (#18080)
as title
2026-02-19 14:00:52 +01:00
Charles BochetandGitHub 530f74e28c Migrate more to Jotai (#18087)
Continue jotai migration
2026-02-19 13:50:21 +01:00
Paul RastoinandGitHub 5a46cf7bd3 Refactor message backfill command (#18078)
# Introduction
Atomically create the field and object to be created
And avoid synchronizing unrelated non up to date object and fields 
Followup https://github.com/twentyhq/twenty/pull/17398
2026-02-19 12:18:42 +00:00
7b10202c69 i18n - translations (#18086)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-19 13:17:01 +01:00
EtienneandGitHub 9e54a8082c Remove non positive integer constraint on Nav Menu Item (#18081)
To fit with position typed field logic + Ease favorite to nav menu item
migration (which have negative and float position)
2026-02-19 11:24:14 +00:00
Charles BochetandGitHub 1a13258302 Keep migrating to jotai (#18064)
And we continue!
2026-02-19 12:10:02 +01:00
Abdullah.andGitHub c0ea049ad7 fix: remove the error message for test failure in ci-front (#18076)
Introduced an error message on twenty-front CI earlier to try and inform
the user that test failure could be a coverage issue if no individual
test was failing. However, it led to the assumption that it must be
coverage failure in all cases even when it was test failure leading to
the CI being red.

This PR reverts the change.
2026-02-19 11:57:01 +01:00
b33f86fbf5 i18n - translations (#18079)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-19 11:56:21 +01:00
Paul RastoinandGitHub 88424611ec Refactor and standardize isSystem field and object (#17992)
# Introduction

## Centralize system field definitions
- Extract a single `PARTIAL_SYSTEM_FLAT_FIELD_METADATAS` constant as the
source of truth for all 8 system fields (`id`, `createdAt`, `updatedAt`,
`deletedAt`, `createdBy`, `updatedBy`, `position`, `searchVector`),
eliminating duplication across custom object and standard app field
builders
- Refactor `buildDefaultFlatFieldMetadatasForCustomObject` to use the
shared constant via a new `buildObjectSystemFlatFieldMetadatas` helper

## Mark system fields as `isSystem: true`
- Fields `id`, `createdAt`, `updatedAt`, `deletedAt`, `createdBy`,
`updatedBy`, `position`, `searchVector` are now properly flagged as
system fields across all standard objects and custom object creation
- Standard app field builders for all ~30 standard objects updated to
set `isSystem: true` on `createdAt`, `updatedAt`, `deletedAt`,
`createdBy`, `updatedBy`
- System-only standard objects (blocklist, calendar channels, message
threads, etc.) now also include `createdBy`, `updatedBy`, `position`,
`searchVector` field definitions that were previously missing

## Validate system fields on object creation
- New transversal validation (`crossEntityTransversalValidation`) runs
after all atomic entity validations in the build orchestrator, ensuring
all 8 system fields are present with correct `type` and `isSystem: true`
when an object is created
- New `buildUniversalFlatObjectFieldByNameAndJoinColumnMaps` utility to
resolve field names to universal identifiers for a given object
- New exception codes: `MISSING_SYSTEM_FIELD` and `INVALID_SYSTEM_FIELD`
on `ObjectMetadataExceptionCode`

## Protect system fields and objects from mutation
- Field validators now block update/delete of `isSystem` fields by
non-system callers (`FIELD_MUTATION_NOT_ALLOWED`)
- Object validators now block update/delete of `isSystem` objects by
non-system callers
- `POSITION` and `TS_VECTOR` field type validators replaced: instead of
rejecting creation outright, they now validate that the field is named
correctly (`position` / `searchVector`) and has `isSystem: true`

## Distinguish `isSystemBuild` from `isCallerTwentyStandardApp`
- New `isCallerTwentyStandardApp` utility checks whether the caller's
`applicationUniversalIdentifier` matches the twenty standard app
- Name-sync logic (`isFlatFieldMetadataNameSyncedWithLabel`,
`areFlatObjectMetadataNamesSyncedWithLabels`) refactored to use
`isCallerTwentyStandardApp` for custom suffix decisions, keeping
`isSystemBuild` for mutation permission checks
- `WorkspaceMigrationBuilderOptions` type updated to include
`applicationUniversalIdentifier`

## Adapt frontend filtering
- New `HIDDEN_SYSTEM_FIELD_NAMES` constant (`id`, `position`,
`searchVector`) and `isHiddenSystemField` utility to only hide truly
internal fields while keeping user-facing system fields (`createdAt`,
`updatedAt`, `deletedAt`, `createdBy`, `updatedBy`) visible in the UI
- ~20 frontend files updated to replace `!field.isSystem` checks with
`!isHiddenSystemField(field)` across record index, settings, data model,
charts, workflows, spreadsheet import, aggregations, and role
permissions

## Add 1.19 upgrade commands
- **`backfill-system-fields-is-system`**: Raw SQL command to set
`isSystem = true` on existing workspace fields matching system field
names, and fix `position` field type from `NUMBER` to `POSITION` for
`favorite`/`favoriteFolder` objects. Includes proper cache invalidation.
- **`add-missing-system-fields-to-standard-objects`**: Codegen'd
workspace migration to create missing `position`, `searchVector`,
`createdBy`, `updatedBy` fields on standard objects that didn't
previously have them. Runs via `WorkspaceMigrationRunnerService` in a
single transaction with idempotency check. **Known limitation**: assumes
all standard objects exist and are valid in the target workspace.

## Add `universalIdentifier` for system fields in standard object
constants
- `standard-object.constant.ts` updated to include `universalIdentifier`
for `createdBy`, `updatedBy`, `position`, and `searchVector` across all
standard objects
- `fieldManifestType.ts` updated to support the new field manifest shape

## System relation
Completely removed and backfilled all `isSystem` relation to be false
false
As we won't require an object to have any relation system fields

## Add integration tests
- New test suite `failing-sync-application-object-system-fields`
covering: missing system fields, wrong field types (`id` as TEXT,
`createdAt` as TEXT, `position` as TEXT), system field deletion
attempts, and system field update attempts
- New test utilities: `buildDefaultObjectManifest` (builds an object
manifest with all 8 system fields) and `setupApplicationForSync`
(centralizes application setup)
- Existing successful sync test updated to verify system fields are
created with correct properties

## Next step
Make the builder scope the compared entity to be the currently built app
+ nor twenty standard app
2026-02-19 10:13:50 +00:00
082400f751 Add objectRecordCounts query to /metadata endpoint (#18054)
## Summary

- Adds an `objectRecordCounts` query on the `/metadata` GraphQL endpoint
that returns approximate record counts for all objects in the workspace
- Uses PostgreSQL's `pg_class.reltuples` catalog stats — a single
instant query instead of N `COUNT(*)` table scans
- Replaces the previous `CombinedFindManyRecords` approach which hit the
server's 20 root resolver limit and silently showed 0 for all counts on
the settings Data Model page

### Server
- `ObjectRecordCountDTO` — GraphQL type with `objectNamePlural` and
`totalCount`
- `ObjectRecordCountService` — reads `pg_class` catalog for the
workspace schema
- Query added to `ObjectMetadataResolver` with `@MetadataResolver()` +
`NoPermissionGuard`

### Frontend
- `OBJECT_RECORD_COUNTS` query added to
`object-metadata/graphql/queries.ts`
- `useCombinedGetTotalCount` simplified to a zero-argument hook using
the new query
- `SettingsObjectTable` simplified to a single hook call

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-19 09:02:31 +00:00
EtienneandGitHub a14b0ab6ca FILES field - Attachment name display fix (#18073)
with new 'file' FILES field on attachment, UI should display attachment
name from file field value.
Issue with API users updating only 'file' FILES field (and not name
field anymore)
2026-02-19 10:04:05 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
6e29f66ce8 Bump @emotion/is-prop-valid from 1.3.0 to 1.4.0 (#18068)
Bumps [@emotion/is-prop-valid](https://github.com/emotion-js/emotion)
from 1.3.0 to 1.4.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/emotion-js/emotion/releases"><code>@​emotion/is-prop-valid</code>'s
releases</a>.</em></p>
<blockquote>
<h2><code>@​emotion/is-prop-valid</code><a
href="https://github.com/1"><code>@​1</code></a>.4.0</h2>
<h3>Minor Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/emotion-js/emotion/pull/3306">#3306</a>
<a
href="https://github.com/emotion-js/emotion/commit/dfae1cbd98d3ebe449ce322b38cbf4a7fbfbfe96"><code>dfae1cb</code></a>
Thanks <a
href="https://github.com/EnzoAlbornoz"><code>@​EnzoAlbornoz</code></a>!
- Adds <code>popover</code>, <code>popoverTarget</code> and
<code>popoverTargetAction</code> to the list of allowed props.</li>
</ul>
<h2><code>@​emotion/is-prop-valid</code><a
href="https://github.com/1"><code>@​1</code></a>.3.1</h2>
<h3>Patch Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/emotion-js/emotion/pull/3093">#3093</a>
<a
href="https://github.com/emotion-js/emotion/commit/532ff57cafd8ba04f3b624074556ea47ec76fc9a"><code>532ff57</code></a>
Thanks <a href="https://github.com/codejet"><code>@​codejet</code></a>,
<a href="https://github.com/DustinBrett"><code>@​DustinBrett</code></a>!
- Adds <code>fetchpriority</code> and <code>fetchPriority</code> to the
list of allowed props.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/emotion-js/emotion/commit/38db311adf024fe8a24b57c687824c47abbd0957"><code>38db311</code></a>
Version Packages (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3347">#3347</a>)</li>
<li><a
href="https://github.com/emotion-js/emotion/commit/dfae1cbd98d3ebe449ce322b38cbf4a7fbfbfe96"><code>dfae1cb</code></a>
Adds <code>popover</code>, <code>popoverTarget</code> and
<code>popoverTargetAction</code> to the list of allo...</li>
<li><a
href="https://github.com/emotion-js/emotion/commit/49229553967b6050c92d9602eb577bdc48167e91"><code>4922955</code></a>
Version Packages (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3335">#3335</a>)</li>
<li><a
href="https://github.com/emotion-js/emotion/commit/0facbe47bd9099ae4ed22dc201822d910ac3dec5"><code>0facbe4</code></a>
Renamed default-exported variable in <code>@emotion/styled</code> to aid
inferred import...</li>
<li><a
href="https://github.com/emotion-js/emotion/commit/cce67ec6b2fc94261028b4f4778aae8c3d6c5fd6"><code>cce67ec</code></a>
Bump parcel (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3258">#3258</a>)</li>
<li><a
href="https://github.com/emotion-js/emotion/commit/3c19ce5997f73960679e546af47801205631dfde"><code>3c19ce5</code></a>
Version Packages (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3280">#3280</a>)</li>
<li><a
href="https://github.com/emotion-js/emotion/commit/a19d019bd418ebc3b9cba0e58f58b36ac2862a42"><code>a19d019</code></a>
Convert <code>@emotion/styled</code>'s source code to TypeScript (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3284">#3284</a>)</li>
<li><a
href="https://github.com/emotion-js/emotion/commit/5974e33fcb5e7aee177408684ac6fe8b38b3e353"><code>5974e33</code></a>
Fix JSX namespace <a
href="https://github.com/ts-ignores"><code>@​ts-ignores</code></a> (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3282">#3282</a>)</li>
<li><a
href="https://github.com/emotion-js/emotion/commit/fc4d7bd744c205f55513dcd4e4e5134198c219de"><code>fc4d7bd</code></a>
Convert <code>@emotion/react</code>'s source code to TypeScript (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3281">#3281</a>)</li>
<li><a
href="https://github.com/emotion-js/emotion/commit/8dc1a6dd19d2dc9ce435ef0aff85ccf5647f5d2e"><code>8dc1a6d</code></a>
Convert <code>@emotion/cache</code>'s source code to TypeScript (<a
href="https://redirect.github.com/emotion-js/emotion/issues/3277">#3277</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/emotion-js/emotion/compare/@emotion/is-prop-valid@1.3.0...@emotion/is-prop-valid@1.4.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@emotion/is-prop-valid&package-manager=npm_and_yarn&previous-version=1.3.0&new-version=1.4.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-19 08:10:11 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
9bcc2fc5d9 Bump eslint-config-next from 14.2.33 to 14.2.35 (#18069)
Bumps
[eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next)
from 14.2.33 to 14.2.35.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vercel/next.js/commit/7b940d9ce96faddb9f92ff40f5e35c34ace04eb2"><code>7b940d9</code></a>
v14.2.35</li>
<li><a
href="https://github.com/vercel/next.js/commit/f3073688ce18878a674fdb9954da68e9d626a930"><code>f307368</code></a>
v14.2.34</li>
<li>See full diff in <a
href="https://github.com/vercel/next.js/commits/v14.2.35/packages/eslint-config-next">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=eslint-config-next&package-manager=npm_and_yarn&previous-version=14.2.33&new-version=14.2.35)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-19 08:09:59 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
01e203a70b Bump @xyflow/react from 12.4.2 to 12.10.0 (#18070)
Bumps
[@xyflow/react](https://github.com/xyflow/xyflow/tree/HEAD/packages/react)
from 12.4.2 to 12.10.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/xyflow/xyflow/releases"><code>@​xyflow/react</code>'s
releases</a>.</em></p>
<blockquote>
<h2><code>@​xyflow/react</code><a
href="https://github.com/12"><code>@​12</code></a>.10.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5637">#5637</a> <a
href="https://github.com/xyflow/xyflow/commit/0c7261a6dc94f1aa58333a6aebcaca8ced9b5ad2"><code>0c7261a6d</code></a>
Thanks <a href="https://github.com/moklick"><code>@​moklick</code></a>!
- Add <code>zIndexMode</code> to control how z-index is calculated for
nodes and edges</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5484">#5484</a> <a
href="https://github.com/xyflow/xyflow/commit/a523919d6789995e9d0f3dd29b0b47fc3b8d8439"><code>a523919d6</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@​peterkogo</code></a>! - Add
<code>experimental_useOnNodesChangeMiddleware</code> hook</p>
</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5629">#5629</a> <a
href="https://github.com/xyflow/xyflow/commit/9030fab2df8285fdfb649bda6e1e885dfd228d45"><code>9030fab2d</code></a>
Thanks <a
href="https://github.com/AlaricBaraou"><code>@​AlaricBaraou</code></a>!
- Prevent unnecessary re-render in <code>FlowRenderer</code></p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5592">#5592</a> <a
href="https://github.com/xyflow/xyflow/commit/38dbf41c464550cc803b946a4ad1f46982385a03"><code>38dbf41c4</code></a>
Thanks <a
href="https://github.com/svilen-ivanov-kubit"><code>@​svilen-ivanov-kubit</code></a>!
- Always create a new measured object in apply changes.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5635">#5635</a> <a
href="https://github.com/xyflow/xyflow/commit/2d7fa40e2684a0fcdd4eca7800ccf2c34338e549"><code>2d7fa40e2</code></a>
Thanks <a
href="https://github.com/tornado-softwares"><code>@​tornado-softwares</code></a>!
- Update an ongoing connection when user moves node with keyboard.</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/xyflow/xyflow/commit/0c7261a6dc94f1aa58333a6aebcaca8ced9b5ad2"><code>0c7261a6d</code></a>,
<a
href="https://github.com/xyflow/xyflow/commit/8598b6bc2a9d052b12d5215706382da0aa84827b"><code>8598b6bc2</code></a>,
<a
href="https://github.com/xyflow/xyflow/commit/2d7fa40e2684a0fcdd4eca7800ccf2c34338e549"><code>2d7fa40e2</code></a>]:</p>
<ul>
<li><code>@​xyflow/system</code><a
href="https://github.com/0"><code>@​0</code></a>.0.74</li>
</ul>
</li>
</ul>
<h2><code>@​xyflow/react</code><a
href="https://github.com/12"><code>@​12</code></a>.9.3</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5621">#5621</a> <a
href="https://github.com/xyflow/xyflow/commit/c1304dba7a20bb8d74c7aceb23cd80b56e4c0482"><code>c1304dba7</code></a>
Thanks <a href="https://github.com/moklick"><code>@​moklick</code></a>!
- Set <code>paneClickDistance</code> default value to
<code>1</code>.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5578">#5578</a> <a
href="https://github.com/xyflow/xyflow/commit/00bcb9f5f45f49814b9ac19b3f55cfe069ee3773"><code>00bcb9f5f</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@​peterkogo</code></a>! - Pass
current pointer position to connection</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/xyflow/xyflow/commit/00bcb9f5f45f49814b9ac19b3f55cfe069ee3773"><code>00bcb9f5f</code></a>]:</p>
<ul>
<li><code>@​xyflow/system</code><a
href="https://github.com/0"><code>@​0</code></a>.0.73</li>
</ul>
</li>
</ul>
<h2><code>@​xyflow/react</code><a
href="https://github.com/12"><code>@​12</code></a>.9.2</h2>
<h3>Patch Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/xyflow/xyflow/pull/5593">#5593</a> <a
href="https://github.com/xyflow/xyflow/commit/a8ee089d7689d9a58113690c8e90e1c1e109602a"><code>a8ee089d7</code></a>
Thanks <a href="https://github.com/moklick"><code>@​moklick</code></a>!
- Reset selection box when user selects a node</li>
</ul>
<h2><code>@​xyflow/react</code><a
href="https://github.com/12"><code>@​12</code></a>.9.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5572">#5572</a> <a
href="https://github.com/xyflow/xyflow/commit/5ec0cac7fad21109b74839969c0818f88ddc87d9"><code>5ec0cac7f</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@​peterkogo</code></a>! - Fix
onPaneClick events being suppressed when selectionOnDrag=true</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/xyflow/xyflow/commit/5ec0cac7fad21109b74839969c0818f88ddc87d9"><code>5ec0cac7f</code></a>]:</p>
<ul>
<li><code>@​xyflow/system</code><a
href="https://github.com/0"><code>@​0</code></a>.0.72</li>
</ul>
</li>
</ul>
<h2><code>@​xyflow/react</code><a
href="https://github.com/12"><code>@​12</code></a>.9.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5544">#5544</a> <a
href="https://github.com/xyflow/xyflow/commit/c17b49f4c16167da3f791430163edd592159d27d"><code>c17b49f4c</code></a>
Thanks <a
href="https://github.com/0x0f0f0f"><code>@​0x0f0f0f</code></a>! - Add
<code>EdgeToolbar</code> component</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5550">#5550</a> <a
href="https://github.com/xyflow/xyflow/commit/6ffb9f7901c32f5b335aee2517f41bf87f274f32"><code>6ffb9f790</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@​peterkogo</code></a>! -
Prevent child nodes of different parents from overlapping</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5551">#5551</a> <a
href="https://github.com/xyflow/xyflow/commit/6bb64b3ed60f26c9ea8bc01c8d62fb9bf74cd634"><code>6bb64b3ed</code></a>
Thanks <a href="https://github.com/moklick"><code>@​moklick</code></a>!
- Allow to start a selection above a node</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/xyflow/xyflow/blob/main/packages/react/CHANGELOG.md"><code>@​xyflow/react</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>12.10.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5637">#5637</a> <a
href="https://github.com/xyflow/xyflow/commit/0c7261a6dc94f1aa58333a6aebcaca8ced9b5ad2"><code>0c7261a6d</code></a>
Thanks <a href="https://github.com/moklick"><code>@​moklick</code></a>!
- Add <code>zIndexMode</code> to control how z-index is calculated for
nodes and edges</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5484">#5484</a> <a
href="https://github.com/xyflow/xyflow/commit/a523919d6789995e9d0f3dd29b0b47fc3b8d8439"><code>a523919d6</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@​peterkogo</code></a>! - Add
<code>experimental_useOnNodesChangeMiddleware</code> hook</p>
</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5629">#5629</a> <a
href="https://github.com/xyflow/xyflow/commit/9030fab2df8285fdfb649bda6e1e885dfd228d45"><code>9030fab2d</code></a>
Thanks <a
href="https://github.com/AlaricBaraou"><code>@​AlaricBaraou</code></a>!
- Prevent unnecessary re-render in <code>FlowRenderer</code></p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5592">#5592</a> <a
href="https://github.com/xyflow/xyflow/commit/38dbf41c464550cc803b946a4ad1f46982385a03"><code>38dbf41c4</code></a>
Thanks <a
href="https://github.com/svilen-ivanov-kubit"><code>@​svilen-ivanov-kubit</code></a>!
- Always create a new measured object in apply changes.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5635">#5635</a> <a
href="https://github.com/xyflow/xyflow/commit/2d7fa40e2684a0fcdd4eca7800ccf2c34338e549"><code>2d7fa40e2</code></a>
Thanks <a
href="https://github.com/tornado-softwares"><code>@​tornado-softwares</code></a>!
- Update an ongoing connection when user moves node with keyboard.</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/xyflow/xyflow/commit/0c7261a6dc94f1aa58333a6aebcaca8ced9b5ad2"><code>0c7261a6d</code></a>,
<a
href="https://github.com/xyflow/xyflow/commit/8598b6bc2a9d052b12d5215706382da0aa84827b"><code>8598b6bc2</code></a>,
<a
href="https://github.com/xyflow/xyflow/commit/2d7fa40e2684a0fcdd4eca7800ccf2c34338e549"><code>2d7fa40e2</code></a>]:</p>
<ul>
<li><code>@​xyflow/system</code><a
href="https://github.com/0"><code>@​0</code></a>.0.74</li>
</ul>
</li>
</ul>
<h2>12.9.3</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5621">#5621</a> <a
href="https://github.com/xyflow/xyflow/commit/c1304dba7a20bb8d74c7aceb23cd80b56e4c0482"><code>c1304dba7</code></a>
Thanks <a href="https://github.com/moklick"><code>@​moklick</code></a>!
- Set <code>paneClickDistance</code> default value to
<code>1</code>.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5578">#5578</a> <a
href="https://github.com/xyflow/xyflow/commit/00bcb9f5f45f49814b9ac19b3f55cfe069ee3773"><code>00bcb9f5f</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@​peterkogo</code></a>! - Pass
current pointer position to connection</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/xyflow/xyflow/commit/00bcb9f5f45f49814b9ac19b3f55cfe069ee3773"><code>00bcb9f5f</code></a>]:</p>
<ul>
<li><code>@​xyflow/system</code><a
href="https://github.com/0"><code>@​0</code></a>.0.73</li>
</ul>
</li>
</ul>
<h2>12.9.2</h2>
<h3>Patch Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/xyflow/xyflow/pull/5593">#5593</a> <a
href="https://github.com/xyflow/xyflow/commit/a8ee089d7689d9a58113690c8e90e1c1e109602a"><code>a8ee089d7</code></a>
Thanks <a href="https://github.com/moklick"><code>@​moklick</code></a>!
- Reset selection box when user selects a node</li>
</ul>
<h2>12.9.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/xyflow/xyflow/pull/5572">#5572</a> <a
href="https://github.com/xyflow/xyflow/commit/5ec0cac7fad21109b74839969c0818f88ddc87d9"><code>5ec0cac7f</code></a>
Thanks <a
href="https://github.com/peterkogo"><code>@​peterkogo</code></a>! - Fix
onPaneClick events being suppressed when selectionOnDrag=true</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/xyflow/xyflow/commit/5ec0cac7fad21109b74839969c0818f88ddc87d9"><code>5ec0cac7f</code></a>]:</p>
<ul>
<li><code>@​xyflow/system</code><a
href="https://github.com/0"><code>@​0</code></a>.0.72</li>
</ul>
</li>
</ul>
<h2>12.9.0</h2>
<h3>Minor Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/xyflow/xyflow/pull/5544">#5544</a> <a
href="https://github.com/xyflow/xyflow/commit/c17b49f4c16167da3f791430163edd592159d27d"><code>c17b49f4c</code></a>
Thanks <a
href="https://github.com/0x0f0f0f"><code>@​0x0f0f0f</code></a>! - Add
<code>EdgeToolbar</code> component</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/xyflow/xyflow/commit/c0ed3c33a3498877ab2a5755299ff84ee659782e"><code>c0ed3c3</code></a>
chore(packages): bump</li>
<li><a
href="https://github.com/xyflow/xyflow/commit/83a312b2e1691a44223536653689f8f99f0d5b24"><code>83a312b</code></a>
chore(zIndexMode): use basic as default</li>
<li><a
href="https://github.com/xyflow/xyflow/commit/14fd41b1f153406f1a21a61bf98ea07ad8275ec6"><code>14fd41b</code></a>
change default back to elevateEdgesOnSelect=false and
zIndexMode=basic</li>
<li><a
href="https://github.com/xyflow/xyflow/commit/3680a6a0e623e19d1f983515273f11bdd355ec86"><code>3680a6a</code></a>
Merge branch 'main' into feat/zindexmode</li>
<li><a
href="https://github.com/xyflow/xyflow/commit/a523919d6789995e9d0f3dd29b0b47fc3b8d8439"><code>a523919</code></a>
chore(middleware): cleanup</li>
<li><a
href="https://github.com/xyflow/xyflow/commit/e4e3605d62c8c710fe7ddb2ec3929af0a7962a6b"><code>e4e3605</code></a>
Merge branch 'main' into middlewares</li>
<li><a
href="https://github.com/xyflow/xyflow/commit/2c05b3224a13e896dfb9a0c93f3af7bb592afc45"><code>2c05b32</code></a>
Merge branch 'feat/zindexmode' of github.com:xyflow/xyflow into
feat/zindexmode</li>
<li><a
href="https://github.com/xyflow/xyflow/commit/ddbb9280f6242794187205a207e993e2c721c244"><code>ddbb928</code></a>
chore(examples): add zindexmode</li>
<li><a
href="https://github.com/xyflow/xyflow/commit/9faca3357d5db68fdad6c96de06fd66dd1d0ba64"><code>9faca33</code></a>
Merge branch 'main' into feat/zindexmode</li>
<li><a
href="https://github.com/xyflow/xyflow/commit/4eb42952f01b947c9d36c25e6b30b7bd98224632"><code>4eb4295</code></a>
feat(svelte): add zIndexMode</li>
<li>Additional commits viewable in <a
href="https://github.com/xyflow/xyflow/commits/@xyflow/react@12.10.0/packages/react">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@xyflow/react&package-manager=npm_and_yarn&previous-version=12.4.2&new-version=12.10.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-19 08:09:48 +00:00
db9636bd9e i18n - docs translations (#18067)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-19 02:07:09 +01:00
Charles BochetandGitHub 36c2b0e23b Migrate dropdown to jotai (#18063)
Here we go again
2026-02-19 00:58:26 +01:00
66deb8be63 i18n - docs translations (#18062)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 23:34:46 +01:00
Charles BochetandGitHub 01d2269bd0 Fix website build (#18061)
As per title
2026-02-18 23:34:36 +01:00
04502e5abb Messages Message Folder Association (#17398)
This PR adds Message folder association for message channel messages,
Currently under testing phase, not ready yet.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 23:13:47 +01:00
Charles BochetandGitHub 549c7a613b Fix website build (#18057) 2026-02-18 22:40:54 +01:00
743b733e70 i18n - translations (#18056)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 22:40:10 +01:00
Thomas des FrancsGitHubclaude[bot] <41898282+claude[bot]@users.noreply.github.com>Charles BochetCharles Bochet
612f7c37a5 Improve security settings card grouping and description overflow (#17928)
# After

- Added a separtor between the two audit logs cards
- Rename the audit log card to avoid repetition
- Grouped "Invite by link" and "2 factor auth" in one group
- Changed the card component description to always be one line max with
truncation & tooltips

<img width="777" height="1278" alt="CleanShot 2026-02-13 at 17 02 36"
src="https://github.com/user-attachments/assets/685c792a-c85b-4521-8c1b-bd9adedc75d9"
/>

<img width="976" height="690"
alt="b49f2eb043b6712d013618bb0a4ef7f011cf2316e1163fbdee4c293bed036ac9"
src="https://github.com/user-attachments/assets/6e17aa11-ecdb-4f98-ba50-5cd9b9c5def6"
/>

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-02-18 22:33:37 +01:00
42108e0611 i18n - translations (#18053)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 22:20:32 +01:00
Charles BochetandGitHub 9a2dc45eb7 Fix website build (#18052) 2026-02-18 22:15:30 +01:00
neo773andGitHub 7de565f70c Prevent SSRF via IMAP/SMTP/CalDAV (#17973)
Prevents leaking of internal services by filtering out private IPs, same
way we do for webhooks
2026-02-18 22:15:10 +01:00
Félix MalfaitGitHubCursorclaude[bot] <41898282+claude[bot]@users.noreply.github.com>
67074a7581 Harden server-side input validation and auth defaults (#18018)
## Summary

- **File storage (LocalDriver):** Add realpath resolution and symlink
rejection to `writeFile`, `downloadFile`, and `downloadFolder` — brings
them in line with the existing `readFile` protections. Includes unit
tests.
- **JWT:** Pin signing/verification to HS256 explicitly.
- **Auth:** Revoke active refresh tokens when a user changes their
password.
- **Logic functions:** Validate `handlerName` as a safe JS identifier at
both DTO and runtime level, preventing injection into the generated
runner script.
- **User entity:** Remove `passwordHash` from the GraphQL schema
(`@Field` decorator removed, column stays).
- **Query params:** Use `crypto.randomBytes` instead of `Math.random`
for SQL parameter name generation.
- **Exception filter:** Mirror the request `Origin` header instead of
sending `Access-Control-Allow-Origin: *`.

## Test plan

- [x] `local.driver.spec.ts` — writeFile rejects symlinks, downloadFile
rejects paths outside storage
- [ ] Verify JWT auth flow still works (login, token refresh)
- [ ] Verify password change invalidates existing sessions
- [ ] Verify logic function creation with valid/invalid handler names
- [ ] Verify file upload/download in dev environment


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-02-18 21:41:01 +01:00
Charles BochetandGitHub 330737aa2e Fix impossible scroll in sdk app:dev (#18051)
Issue is that we are refreshing the terminal because of icons animations
2026-02-18 21:39:21 +01:00
4cb64c6aa5 Restore old favorite design (#18049)
Issue : With IS_NAVIGATION_MENU_ITEM_ENABLED:true +
IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED:false, nav menu design is
changed after 1.18.0 release : views expansion removed, system object
displayed, position re-ordered

We prefer keeping the same "old" favorite behaviour and design state

- After 1.18.0 all workspaces have up-to-date navigation menu items
(migrated)
- IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED becomes the FF for nav menu
new design

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-02-18 21:35:17 +01:00
6b3ef404b0 i18n - docs translations (#18050)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 21:31:54 +01:00
6aaafb76b6 fix: show "Not shared" for junction relation fields when target or intermediate object is not readable (#18025)
When a user's role lacks read permission on the target object (e.g.,
Company) or the intermediate junction object (e.g., EmploymentHistory),
junction relation fields like "Previous Companies" displayed as blank
instead of showing "Not shared."

- In RecordFieldList, junction fields now check the junction object's
read permission and set isForbidden on the field context so FieldDisplay
renders "Not shared" instead of an empty field.
- In RelationFromManyFieldDisplay, if junction records exist but all
nested target records are null (permission-denied by the API), the
component renders "Not shared" instead of an empty list.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2026-02-18 21:05:45 +01:00
Thomas des FrancsandGitHub 7ec4508d5f Add currency hover tooltip in CurrencyDisplay (#18045)
https://github.com/user-attachments/assets/af768ecb-b5e9-4e8d-a9f9-fee1a08ea9a0

Fixes https://github.com/twentyhq/twenty/issues/17756
2026-02-18 20:25:34 +01:00
Thomas des FrancsandGitHub a05a9c8f79 refactor workflow action messaging with callout (#18038)
## Summary
- remove the dedicated `WorkflowMessage` component and story
- update workflow action editor components to use the shared callout
patterns
- adjust `Callout` and its stories to support the new usage in workflow
actions

## Before/After

<img width="525" height="548" alt="image"
src="https://github.com/user-attachments/assets/ce57a84f-f070-4149-85ef-a4d162b2d878"
/>


<img width="518" height="593" alt="image"
src="https://github.com/user-attachments/assets/f7249cd0-221f-496d-9deb-d9966ee43382"
/>
2026-02-18 20:23:38 +01:00
Charles BochetandGitHub ce1ffa8550 Refactor page layout types (#18042)
## Refactor page layout widget types into shared package and expose from
SDK

### Why

Widget configuration types were defined only on the server, forcing SDK
consumer apps to import from deep internal `twenty-shared/dist` paths —
fragile and breaks on structural changes. Server DTOs also had no
compile-time guarantee they matched the canonical types.

### What changed

- **`twenty-shared`**: Migrated `ChartFilter`, `GridPosition`,
`RatioAggregateConfig` and all 20 widget configuration variants into
`twenty-shared/types`. `PageLayoutWidgetConfiguration` (base, with
`SerializedRelation`) and `PageLayoutWidgetUniversalConfiguration`
(derived via `FormatRecordSerializedRelationProperties`) are now the
single source of truth.
- **`twenty-sdk`**: Re-exported `AggregateOperations`,
`ObjectRecordGroupByDateGranularity`, `PageLayoutTabLayoutMode`, and
`PageLayoutWidgetUniversalConfiguration` so consumer apps import from
`twenty-sdk` directly.
- **`twenty-server`**: All widget DTOs now `implements` their shared
type for compile-time enforcement. Added helpers to convert nested
`fieldMetadataId` ↔ `fieldMetadataUniversalIdentifier` inside chart
filters. Removed redundant local type re-exports.
2026-02-18 20:17:40 +01:00
martmullandGitHub 2cc3c75c7e Add example in create-twenty-app (#18043)
- add interactive mode to create-twenty-app
- by default create an example for each entities

<img width="1181" height="168" alt="image"
src="https://github.com/user-attachments/assets/a2490d8f-66a1-4cd5-bf41-57166cc20a1e"
/>
2026-02-18 18:04:19 +00:00
Thomas TrompetteandGitHub 9733ff1b8e Add missing objects to rich app integration tests (#18039)
Updating rich app so it also create:
- a many to many relation
- views
- navigation items

The app was built successfully.

Will still be missing front component examples

<img width="1498" height="660" alt="Capture d’écran 2026-02-18 à 17 47
25"
src="https://github.com/user-attachments/assets/acd5193f-3a36-4eb7-8276-3154e4e60f5e"
/>
2026-02-18 18:01:14 +00:00
e4075caa65 i18n - docs translations (#18048)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 19:42:34 +01:00
Charles BochetandGitHub c3781e87cc Sync page Layout (#18034)
## Sync page layouts, tabs, and widgets

Adds the ability for SDK applications to synchronize `pageLayout`,
`pageLayoutTab`, and `pageLayoutWidget` entities, following the same
pattern established in #18003 for views and navigation menu items.

### Changes

**`twenty-shared`**
- New `PageLayoutManifest`, `PageLayoutTabManifest`, and
`PageLayoutWidgetManifest` types with a hierarchical structure (page
layout → tabs → widgets)
- Added `pageLayouts: PageLayoutManifest[]` to the `Manifest` type

**`twenty-sdk`**
- New `definePageLayout()` SDK function with validation for
universalIdentifier, name, and nested tabs/widgets
- Wired into the manifest extraction and build pipeline
(`DefinePageLayout` target function, `PageLayouts` entity key)
- Exported from the SDK entry point

**`twenty-server`**
- Added `pageLayout`, `pageLayoutTab`, `pageLayoutWidget` to
`APPLICATION_MANIFEST_METADATA_NAMES`
- New conversion utilities: manifest → universal flat entity for all
three entity types
- Updated `computeApplicationManifestAllUniversalFlatEntity
2026-02-18 17:55:04 +01:00
e9b5cb830c i18n - docs translations (#18040)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 17:54:40 +01:00
EtienneandGitHub e40c758aa6 Nav Menu Item Migration command fix (#18041) 2026-02-18 17:45:21 +01:00
martmullandGitHub 53c314d0fa 2094 extensibility define postinstall orand preinstall function to run in application (#18037)
- add a new optional key `postInstallLogicFunctionUniversalIdentifier`
in applicationConfig
- seed postInstall function in create-twenty-app
- update execute:function options
- update doc
2026-02-18 15:38:22 +00:00
618df704e6 [Chore] : Generate migration for DATE_TIME to DATE for DATE_TIME + IS operand filters (#17564)
migration command in response to the fix :
https://github.com/twentyhq/twenty/pull/17529 for the issue
https://github.com/twentyhq/core-team-issues/issues/2027

---------

Co-authored-by: Arun kumar <arunkumar@Aruns-MacBook-Air.local>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2026-02-18 15:15:38 +00:00
EtienneandGitHub 058489b5cc Fixes - Workspace logo migration (#18035)
- Update migration command to handle case where workspace logo is
originated from workspace email and point to twenty-icons.com
- Update same logic for new workspaces
- Add feature-flag for all newly created workspaces
2026-02-18 16:35:48 +01:00
3bd431e95d Use proper PostgreSQL identifier/literal escaping in workspace DDL (#18024)
## Summary

- Replace the character-stripping approach (`removeSqlDDLInjection`)
with standard PostgreSQL `escapeIdentifier` and `escapeLiteral`
functions across all workspace schema manager services
- Add missing identifier escaping to `createForeignKey` (was the only
method in the FK manager without it)
- Add allowlist validation for index WHERE clauses and FK action types
- Harden tsvector expression builder with proper identifier quoting

## Context

The workspace schema managers build DDL dynamically from metadata (table
names, column names, enum values, etc.). The previous approach stripped
all non-alphanumeric characters — safe but lossy (silently corrupts
values with legitimate special characters). The new approach uses
PostgreSQL's standard escaping:

- **Identifiers**: double internal `"` and wrap → `"my""table"` (same
algorithm as `pg` driver's `escapeIdentifier`)
- **Literals**: double internal `'` and wrap → `'it''s a value'` (same
algorithm as `pg` driver's `escapeLiteral`)

`removeSqlDDLInjection` is kept only for name generation (e.g.,
`computePostgresEnumName`) where stripping to `[a-zA-Z0-9_]` is the
correct behavior.

## Files changed

| File | What |
|------|------|
| `remove-sql-injection.util.ts` | Added `escapeIdentifier` +
`escapeLiteral` |
| `validate-index-where-clause.util.ts` | New — allowlist for partial
index WHERE clauses |
| 5 schema manager services | Replaced strip+manual-quote with
`escapeIdentifier`/`escapeLiteral` |
| `build-sql-column-definition.util.ts` | `escapeIdentifier` for column
names, validated `generatedType` |
| `sanitize-default-value.util.ts` | `escapeLiteral` instead of
stripping |
| `serialize-default-value.util.ts` | `escapeLiteral` for values,
`escapeIdentifier` for enum casts |
| `get-ts-vector-column-expression.util.ts` | `escapeIdentifier` for
field names in expressions |
| `sanitize-default-value.util.spec.ts` | Updated tests for escape
behavior |

## Test plan

- [x] All 64 existing tests pass across 6 test suites
- [x] `lint:diff-with-main` passes
- [x] TypeScript typecheck — no new errors
- [ ] Verify workspace sync-metadata still works end-to-end
- [ ] Verify custom object/field creation works
- [ ] Verify enum field option changes work


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-18 14:24:10 +00:00
f4a61f26c0 Replace generic "Unknown error" messages with descriptive error details (#18019)
## Summary

- Replace all generic `"Unknown error"` fallback messages across the
server codebase with messages that include the actual error details
- The most impactful change is in `guard-redirect.service.ts`, which
handles OAuth redirect errors — non-`AuthException` errors (e.g.,
passport state verification failures) now show `"Authentication error:
<actual message>"` instead of the opaque `"Unknown error"`
- Gmail/Google error handler services now include the error message in
the thrown exception instead of discarding it
- Other catch blocks (workflow delay resume, migration runner rollback,
code interpreter, marketplace) now use `String(error)` for non-Error
objects instead of a static fallback

Fixes the class of issues reported in
https://github.com/twentyhq/twenty/issues/17812, where a user saw
"Unknown error" during Google OAuth and had no way to diagnose the root
cause (which turned out to be a session cookie / SSL configuration
issue).

## Test plan

- [ ] Verify OAuth error flows (e.g., Google Auth with misconfigured
callback URL) now display the actual error message on the `/verify` page
instead of "Unknown error"
- [ ] Verify Gmail sync error handling still correctly classifies and
re-throws errors with descriptive messages
- [ ] Verify workflow delay resume failures include the error details in
the workflow run status


Made with [Cursor](https://cursor.com)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-18 14:12:47 +00:00
8e6b267ff3 Allow DATE_TIME IS operand to filter on a whole day (#17529)
Fixes:  https://github.com/twentyhq/core-team-issues/issues/2027

We've replaced the DATE_TIME picker with DATE picker, and changed the
logic to filter for complete day period.



https://github.com/user-attachments/assets/ba7e1078-bab3-4c62-a803-d6a851f14b7d

---------

Co-authored-by: Arun kumar <arunkumar@Aruns-MacBook-Air.local>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2026-02-18 13:44:05 +00:00
neo773andGitHub 88146c2170 Fix Gmail thread awareness for custom labels (#18031)
This fixes two edge cases for Gmail

- When policy was set to `SELECTED_FOLDERS` excluding root INBOX, it
missed label changes, so messages with newly applied labels weren't
imported until a full resync.

- Gmail thread replies by default by default do no inherit parent
message's label properties so thread context was also lost because only
individually labeled messages were returned, dropping earlier parts of
the conversation.

Fixed by subscribing to `labelAdded`/`labelRemoved` history events and
fetching full thread context when at least one message in a thread
carries a synced label. `ALL_FOLDERS` path is untouched.
2026-02-18 14:10:38 +01:00
EtienneandGitHub 3706da9bcb v1.18 - Fix command (#18032)
Same as here https://github.com/twentyhq/twenty/pull/18016
2026-02-18 13:52:13 +01:00
9bac8f15d4 i18n - translations (#18029)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 13:26:54 +01:00
Charles BochetandGitHub 7332379d26 Improve API Client usage and add Typescript check (#18023)
## Summary


https://github.com/user-attachments/assets/1e75cc9d-d9d2-4ef2-99f9-34450f5d8de7



Add background incremental type checking (`tsc --watch`) to the SDK dev
mode, so type regressions are caught when the generated API client
changes — without requiring a full rebuild of source files.

Previously, removing a field from the data model would regenerate the
API client, but existing front components/logic functions referencing
the removed field wouldn't surface type errors (since their source
didn't change, esbuild wouldn't rebuild them).

## What changed

- **Background `tsc --watch`**: a long-lived TypeScript watcher runs
alongside esbuild watchers, incrementally re-checking all files when the
generated client changes. Only logs on state transitions (errors appear
/ errors clear) to stay quiet.
- **Atomic client generation**: API client is now generated into a temp
directory and swapped in atomically, avoiding a race condition where
`tsc --watch` could see an empty `generated/` directory
mid-regeneration.
- **Step decoupling**: orchestrator steps no longer receive
`uploadFilesStep` directly. Instead, they use callbacks (`onFileBuilt`,
`onApiClientGenerated`), and each step manages its own `builtFileInfos`
state.
- **`apiClientChecksum` omitted from `ApplicationConfig`**: it's a
build-time computed value, same as `packageJsonChecksum`.
<img width="327" height="177" alt="image"
src="https://github.com/user-attachments/assets/02bd25bb-fa41-42b0-8d96-01c51bd4580c"
/>

<img width="529" height="452" alt="image"
src="https://github.com/user-attachments/assets/61f6e968-365b-4a5b-8f2b-a8419d6b1bd3"
/>
2026-02-18 13:26:30 +01:00
Raphaël BosiandGitHub 2455c859b4 Add SSE for metadata and plug front components (#17998)
Create the necessary tooling to listen to metadata events and plug it to
the front components. Now we have a hot reload like experience when we
edit a component in an app.

## Backend

- Split `EventWithQueryIds` into `ObjectRecordEventWithQueryIds` and
`MetadataEventWithQueryIds`
- Publish metadata event batches to active SSE streams in
`MetadataEventsToDbListener`

## Frontend

- Create a metadata event dispatching pipeline: SSE metadata events are
grouped by metadata name, transformed into
`MetadataOperationBrowserEventDetail` objects, and dispatched as browser
`CustomEvents`
- Add `useListenToMetadataOperationBrowserEvent` hook for consuming
metadata operation events filtered by metadata name and operation type
- Rename `useListenToObjectRecordEventsForQuery` to
`useListenToEventsForQuery`, now accepting both
`RecordGqlOperationSignature` and `MetadataGqlOperationSignature`
- Implement `useOnFrontComponentUpdated` which subscribes to front
component metadata events and updates the Apollo cache when the
component is modified
- Add `builtComponentChecksum` to the front component query and appends
it to the component URL for browser cache invalidation
2026-02-18 11:26:20 +00:00
martmullandGitHub e3753bf822 App feedbacks (#18028)
as title
2026-02-18 11:04:54 +00:00
WeikoandGitHub f3faa11dd2 New field creates fields widget field (#18022)
## Context
Introducing "NewFieldDefaultConfiguration" to FIELDS widget
configurations
```typescript
{
  isVisible: boolean;
  viewFieldGroupId: string | null;
}
```

This configuration will define where a new field should be added (which
section) and its default visibility inside FIELDS widget views.
The new field position should always be at the end (meaning the last
position for the view fields OR the last position of a viewFieldGroup)

See "New fields" on this screenshot
<img width="401" height="724" alt="Layout V1"
src="https://github.com/user-attachments/assets/4969bcaa-f244-4504-8947-778a02c24c47"
/>
2026-02-18 11:03:27 +00:00
nitinandGitHub 477fbc0865 fixes: loosen up front validation, add resolveEntityRelationUniversalIdentifiers to update and restore (#18015)
closes https://github.com/twentyhq/private-issues/issues/419
2026-02-18 10:35:08 +00:00
EtienneGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
08a3d983cb Date & DateTime validation fixes / improvements (#18009)
Fixes https://github.com/twentyhq/twenty/issues/17138

- Backend should have strict date/dateTime format validation
- FE in import csv is more permissive

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-18 10:13:18 +00:00
EtienneandGitHub ee15e034b5 Files command - fixes (#18016)
- Fixed "property entity not found" error when updating/creating a new
field and querying the same object repository just after
- Downgraded log type for unnecessary migration
2026-02-18 09:09:52 +00:00
b7274da8fa i18n - docs translations (#18020)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 08:12:20 +01:00
4a485aecb0 i18n - docs translations (#18017)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-18 01:06:14 +01:00
BOHEUSGitHubneo773neo773greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
5ae1d94f23 Fix connected account permissions (#17598)
Fixes #17411

---------

Co-authored-by: neo773 <neo773@protonmail.com>
Co-authored-by: neo773 <62795688+neo773@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-18 01:05:56 +01:00
Abdul RahmanGitHubCopilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>DevessierFélix Malfait
015ccbf0a7 Navbar customization improvements (#17863)
- Add folder icon editing support
- And other navbar customization fixes/improvements.

---------

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Devessier <baptiste@devessier.fr>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-02-17 19:53:52 +00:00
3d362e6e01 i18n - docs translations (#18014)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 19:33:21 +01:00
Charles BochetGitHubclaude[bot] <41898282+claude[bot]@users.noreply.github.com>
d7f025157b Migrate more to Jotai (#17968)
As per title

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-02-17 19:24:36 +01:00
98482f3a01 i18n - translations (#18013)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 19:18:53 +01:00
BOHEUSandGitHub 171efe2a19 New onboarding plan (#17776)
Fixes github.com/twentyhq/core-team-issues/issues/637
2026-02-17 19:11:47 +01:00
Baptiste DevessierandGitHub 7512b9f9bb Load view field groups (#18010) 2026-02-17 17:22:48 +00:00
Charles BochetandGitHub c0cc0689d6 Add Client Api generation (#17961)
## Add API client generation to SDK dev mode and refactor orchestrator
into step-based pipeline

### Why

The SDK dev mode lacked typed API client generation, forcing developers
to work without auto-generated GraphQL types when building applications.
Additionally, the orchestrator was a monolithic class that mixed watcher
management, token handling, and sync logic — making it difficult to
extend with new steps like client generation.

### How

- **Refactored the orchestrator** into a step-based pipeline with
dedicated classes: `CheckServer`, `EnsureValidTokens`,
`ResolveApplication`, `BuildManifest`, `UploadFiles`,
`GenerateApiClient`, `SyncApplication`, and `StartWatchers`. Each step
has typed input/output/status, managed by a new `OrchestratorState`
class.
- **Added `GenerateApiClientOrchestratorStep`** that detects
object/field schema changes and regenerates a typed GraphQL client (via
`@genql/cli`) into `node_modules/twenty-sdk/generated` for seamless
imports.
- **Replaced `checkApplicationExist`** with `findOneApplication` on both
server resolver and SDK API service, returning the entity data instead
of a boolean.
- **Added application token pair mutations**
(`generateApplicationToken`, `renewApplicationToken`) to the API
service, with the server now returning `ApplicationTokenPairDTO`
containing both access and refresh tokens.
- **Restructured the dev UI** into `dev/ui/components/` with dedicated
panel, section, and event log components.
- **Simplified `AppDevCommand`** from ~180 lines of watcher management
down to ~40 lines that delegate entirely to the orchestrator.
2026-02-17 18:45:52 +01:00
0891886aa0 i18n - translations (#18012)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 18:35:35 +01:00
Thomas TrompetteandGitHub f768bbe512 Replace country code by calling code in workflows (#18008)
Long overdue PR: replacing deprecated country code in workflows.
Will allow to use variables.

We keep storing the country code since it allows to display the right
flag in picker when there are multiple countries for one calling code.
But we do not store country for variables.

<img width="477" height="254" alt="Capture d’écran 2026-02-17 à 17 25
23"
src="https://github.com/user-attachments/assets/dc67c41c-33cf-4021-b7bb-490827b2aa3c"
/>
2026-02-17 17:06:09 +00:00
610c0ebc9d Move secure HTTP client IP validation to connection level (#18006)
## Summary
- Refactors SSRF protection from a request-level adapter to
connection-level agents, validating resolved IPs in `createConnection` +
socket `lookup` events
- Sets both `httpAgent` and `httpsAgent` so validation applies
regardless of protocol switches during redirects
- Caps `maxRedirects` to 10 as defense in depth

## Test plan
- [x] All 59 existing + new unit tests pass (agent util, isPrivateIp,
service)
- [x] No linter errors
- [ ] Verify webhook delivery still works with URLs that redirect
- [ ] Verify image upload from external URLs still works (relies on
redirect following)


Made with [Cursor](https://cursor.com)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes core outbound HTTP security behavior and redirect handling,
which could impact webhook/image-fetch flows and connection semantics
despite improved SSRF coverage.
> 
> **Overview**
> Refactors outbound SSRF protection from a custom axios `adapter` to
connection-level `httpAgent`/`httpsAgent` created by new
`createSsrfSafeAgent`, which blocks private IP literals up front and
validates DNS-resolved IPs via the socket `lookup` event.
> 
> When safe mode is enabled, `SecureHttpClientService.getHttpClient` now
always installs both agents and enforces a capped `maxRedirects`
(default `5`), and the old `getSecureAxiosAdapter`
implementation/tests/types are removed. `isPrivateIp` is
tightened/expanded to treat `0.0.0.0/8` as private and avoid
misclassifying bare IPv4 decimals as IPv6.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8261da4ff0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-17 16:59:38 +00:00
Lucas BordeauandGitHub e4aad7751f Fixed group by query order by inside group (#18005)
Fixes https://github.com/twentyhq/core-team-issues/issues/2229

This PR fixes a bug on board, that we thought was due to dev seeds, but
that was in fact a conflict of `ORDER BY` clauses at the SQL level in
group by queries.

The problem was that an ORDER BY was applied on top of a sub-query ORDER
BY, thus breaking the initial ordering of each group.

# Before

<img width="1117" height="1033" alt="Capture d’écran 2026-02-17 à 16
32 56"
src="https://github.com/user-attachments/assets/764183ae-4058-498b-9fe0-919e9511e67d"
/>

# After 

<img width="1101" height="1007" alt="Capture d’écran 2026-02-17 à 16
32 27"
src="https://github.com/user-attachments/assets/b3100b30-25b5-4568-a9cf-0760f42ceb88"
/>
2026-02-17 16:18:23 +00:00
7c5a13852b i18n - translations (#18007)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 17:27:50 +01:00
EtienneandGitHub 163c1175cb File - Migrate core pictures (workspace and member logo) + workflow attachments (#17924)
- Create a common file-by-id download controller
- Create core picture module with resolver and logic to handle
workspaceLogo and workspaceMemberProfilePicture update
- Create workflow file module (same)
- Data migration
2026-02-17 15:42:50 +00:00
Baptiste DevessierandGitHub 963f2de864 Translate page layout tab title (#17975)
> [!NOTE]
> The improvement will only fully work once all tabs get translated. 

## When using the front-end mocks


https://github.com/user-attachments/assets/cf7dc0fb-9438-4e18-841e-47558ff71474

## When loading page layout information from database


https://github.com/user-attachments/assets/d2c9d98b-97e2-4629-aa6c-53f3f3713733

## When editing dashboard


https://github.com/user-attachments/assets/c6ae3a7a-f05f-48ea-8b33-8f689e3f71f7

Closes
https://github.com/twentyhq/twenty/issues/17950#issuecomment-3902782952
2026-02-17 15:26:28 +00:00
martmullandGitHub e3fcff00b0 Fix initial code step functionInput (#18002)
At code step creation

## before
<img width="623" height="816" alt="image"
src="https://github.com/user-attachments/assets/0aed5ed8-8d56-4988-9d31-fe80942191bb"
/>

## after
<img width="627" height="528" alt="image"
src="https://github.com/user-attachments/assets/9e2a5cb9-7480-4734-8e41-25b45edcec07"
/>
2026-02-17 16:45:00 +01:00
Thomas TrompetteandGitHub b4e924b671 Sync views and navigation items (#18003)
Both objects are necessary to fully enjoy objects within applications

<img width="770" height="311" alt="Capture d’écran 2026-02-17 à 15 19
43"
src="https://github.com/user-attachments/assets/48c51fa4-63f4-45b2-a40a-df73f3aa79be"
/>
2026-02-17 16:32:41 +01:00
Lakshay ManchandaandGitHub 63a3f93a78 Emitting the correct event based on whether the record is being soft deleted or restored. (#17953)
fix for #17262 
This change ensures that when the record is restored, instead of
emitting a database event of "DELETED", a database event of "RESTORED"
will be emitted, as it is happening in the inner working of TypeORM.

This ensures that the DELETED event are not fired on RESTORED, for
example, triggering a workflow.

The screen recording shows that restoring the soft deleted records does
not trigger the workflow set to to run on "Record Deleted"


https://github.com/user-attachments/assets/90e0184f-2e08-466c-a40d-1592b60e64ff
2026-02-17 15:05:44 +00:00
Lucas BordeauandGitHub 8938dd637f Added relations to SSE events (#17683)
Fixes https://github.com/twentyhq/core-team-issues/issues/2192

This PR implements what is necessary to re-create the query that we
build on the frontend to obtain the returned object record from a
mutation, but on the backend, which was only partially implemented for
REST API.

Usually we want to have relations with only their id and label
identifier field to have lighter payloads.

In the event we only had depth 0 fields, with this PR we have all events
with depth 1 relations.

We have depth 2 for many-to-many cases, like updateOne or updateMany
result :
- Junction tables
- Activity target tables
2026-02-17 13:57:26 +00:00
WeikoandGitHub 20977428a1 Page layout various fixes (#17996)
## Context
- Add missing fields widget and FIELDS_WIDGET view for workflow run and
workflow version standard objects
- Fix FIELDS_WIDGET configuration fieldId universalIdentifier not being
converted to id when migration is executed.
2026-02-17 15:12:04 +01:00
Baptiste DevessierandGitHub 347298902d Fix dashboard new tab creation (#17971)
## Before


https://github.com/user-attachments/assets/cbc60013-8a5e-4af8-b02c-7dfbaf0c15e5


## After 


https://github.com/user-attachments/assets/1fd6f9f7-e774-4c63-aa80-50b33d2a4c59
2026-02-17 14:46:19 +01:00
5750c9be0c i18n - translations (#17997)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 14:36:47 +01:00
08feb6f651 i18n - translations (#17995)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 14:29:21 +01:00
Félix MalfaitGitHubclaude[bot] <41898282+claude[bot]@users.noreply.github.com>Charles Bochet
c9c3b2b691 fix: improve clipboard copy for non-HTTPS self-hosted deployments (#17989)
Closes #8305

The Clipboard API (`navigator.clipboard`) requires a secure context
(HTTPS or localhost). Self-hosted deployments on plain HTTP silently
fail when copying.

This PR:
- Adds a `document.execCommand('copy')` fallback for insecure contexts
- Shows a descriptive error message explaining HTTPS is required when
the fallback also fails
- Consolidates 3 components that were using `navigator.clipboard`
directly (without error handling) to use the centralized
`useCopyToClipboard` hook

Generated with [Claude Code](https://claude.ai/code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Scoped to frontend clipboard UX with a defensive fallback and clearer
errors; minimal impact outside copy flows.
> 
> **Overview**
> Improves copy-to-clipboard behavior in non-HTTPS/self-hosted
deployments by enhancing `useCopyToClipboard` to use
`navigator.clipboard` only in secure contexts and otherwise fall back to
`document.execCommand('copy')`.
> 
> Updates 2FA setup screens and the view visibility dropdown to use the
centralized `copyToClipboard` helper (with consistent snackbars), and
shows a more descriptive error (longer duration) when copying fails due
to an insecure context.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
30944e63eb. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2026-02-17 14:24:00 +01:00
09e1684300 feat: show auto-generated conversation title for AI chat. (#17922)
## Summary
Replaces the static "Ask AI" header in the command menu with the
conversation’s auto-generated title once it’s set after the first
message.

## Changes
- **Backend:** Title is generated after the first user message (existing
behavior).
- **Frontend:** After the first stream completes, we fetch the thread
title and sync it to:
- `currentAIChatThreadTitleState` (persists across command menu
close/reopen)
- Command menu page info and navigation stack (so the title survives
back navigation)
- **Entry points:** Opening Ask AI from the left nav or command center
uses the same title resolution (explicit `pageTitle` → current thread
title → "Ask AI" fallback).
- **Race fix:** Title sync only runs when the thread that finished
streaming is still the active thread, so switching threads mid-stream
doesn’t overwrite the current thread’s title.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-17 12:46:35 +00:00
nitinandGitHub e80e9a6a25 fix: on charts newly added multi split values toggle wasnt being saved (#17990)
:)
2026-02-17 14:01:11 +01:00
c2fe18af53 i18n - translations (#17993)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 14:00:47 +01:00
EtienneandGitHub 2b702b2b45 Navigation Menu Item - Migration in v1.18 (#17991)
Add navigation menu item data migration command in 1.18
2026-02-17 14:00:24 +01:00
EtienneandGitHub dc167b2d3d File - Disable file upload in standalone rich text widget (#17934)
File's url are not signed, in standalone rich text. We choose to disable
file upload to prevent unauthorised file upload links.
2026-02-17 13:46:28 +01:00
1e6c5b57b2 fix: use pickMorphGroupSurvivor in relation loader to match field metadata deduplication (#17988)
## Summary

- Fixes "Target field metadata full object not found" error thrown
during optimistic effects (e.g., bulk delete) on workspaces with custom
objects
- The relation loader was using a simple sort-by-ID to pick the
representative morph field, while `filterMorphRelationDuplicateFields`
uses `pickMorphGroupSurvivor` which prefers active non-system fields.
When a custom object's auto-created morph field (`isSystem: true`)
happened to have the smallest UUID, the two loaders would disagree — the
relation DTO pointed to that system field's ID, but the field metadata
loader filtered it out in favor of a standard field, causing the
frontend lookup to fail.
- Now both code paths use `pickMorphGroupSurvivor` so they always agree
on which morph field represents the group.

## Test plan

- [ ] Create a custom object on a workspace that already has standard
objects with morph relations (e.g., noteTarget, taskTarget)
- [ ] Bulk-select and delete records (e.g., People) — should no longer
throw "Target field metadata full object not found"

Made with [Cursor](https://cursor.com)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Small, localized change to morph-relation selection logic in a
dataloader; main risk is altered field choice for edge-case morph
groups, but behavior now matches existing deduplication.
> 
> **Overview**
> Ensures the relation dataloader picks the representative
morph-relation target field using `pickMorphGroupSurvivor` (preferring
active non-system fields) instead of the previous sort-by-id approach.
> 
> This aligns `createRelationLoader` with
`filterMorphRelationDuplicateFields`, preventing mismatches where
relation DTOs could reference a morph field that gets filtered out
elsewhere (e.g., triggering “Target field metadata full object not
found”).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c3a6d86126. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-17 13:46:05 +01:00
3516be2cf4 i18n - translations (#17987)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 13:43:13 +01:00
9477bb3677 Improve AI chat UX (#17974)
## Summary
- update AI chat message typography and list line-height for readability
- apply richer markdown-section styling for headings, spacing,
separators, and inline code
- keep links non-underlined by default with underline on hover, using
accent11 for link color
- preserve previous AI chat table design while keeping other markdown
improvements

## Validation
- yarn eslint
packages/twenty-front/src/modules/ai/components/LazyMarkdownRenderer.tsx
packages/twenty-front/src/modules/ai/components/AIChatMessage.tsx

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-02-17 11:24:33 +01:00
aac032e517 i18n - translations (#17986)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 11:14:14 +01:00
Paul RastoinandGitHub 5544b5dcfe Fix and refactor all metadata relation (#17978)
# Introduction
The initial motivation was that in the workspace migration create action
some universal foreign key aggregators weren't correctly deleted before
returned due to constant missconfiguration
<img width="2300" height="972" alt="image"
src="https://github.com/user-attachments/assets/9401eb02-2bb2-4e69-9c5f-9a354ff61079"
/>
It also meant that under the hood some optimistic behavior wasn't
correctly rendered for some aggregators

## Solution
Refactored the `ALL_METADATA_RELATIONS` as follows:

This way we can infer the FK and transpile it to a universalFK, also the
aggregators are one to one instead of one versus all available
Making the only manual configuration to be defined the `foreignKey` and
`inverseOneToManyProperty`

```
┌──────────────────────────────────────┐      ┌─────────────────────────────────────────────┐
│  ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY│      │      ALL_ONE_TO_MANY_METADATA_RELATIONS     │
│──────────────────────────────────────│      │─────────────────────────────────────────────│
│  Derived from: Entity types          │      │  Derived from: Entity types                 │
│                                      │      │                                             │
│  Provides:                           │      │  Provides:                                  │
│   • foreignKey                       │      │   • metadataName                            │
│                                      │      │   • flatEntityForeignKeyAggregator          │
│  Standalone low-level primitive      │      │   • universalFlatEntityForeignKeyAggregator │
└──────────────┬───────────────────────┘      └──────────────┬──────────────────────────────┘
               │                                             │
               │ foreignKey type +                           │ inverseOneToManyProperty
               │ universalForeignKey derivation              │ keys (type constraint)
               │                                             │
               ▼                                             ▼
       ┌───────────────────────────────────────────────────────────────┐
       │              ALL_MANY_TO_ONE_METADATA_RELATIONS              │
       │───────────────────────────────────────────────────────────────│
       │  Derived from:                                               │
       │   • Entity types (metadataName, isNullable)                  │
       │   • ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY (FK → universalFK)  │
       │   • ALL_ONE_TO_MANY_METADATA_RELATIONS (inverse keys)        │
       │                                                              │
       │  Provides:                                                   │
       │   • metadataName                                             │
       │   • foreignKey (replicated from FK constant)                 │
       │   • inverseOneToManyProperty                                 │
       │   • isNullable                                               │
       │   • universalForeignKey                                      │
       └──────────────────────────┬────────────────────────────────────┘
                                  │
               ┌──────────────────┼──────────────────┐
               │                  │                  │
               ▼                  ▼                  ▼
   ┌───────────────────┐ ┌────────────────┐ ┌──────────────────────┐
   │  Type consumers   │ │  Atomic utils  │ │  Optimistic utils    │
   │───────────────────│ │────────────────│ │──────────────────────│
   │ • JoinColumn      │ │ • resolve-*    │ │ • add/delete flat    │
   │ • RelatedNames    │ │ • get-*        │ │   entity maps        │
   │ • UniversalFlat   │ │                │ │ • add/delete         │
   │   EntityFrom      │ │                │ │   universal flat     │
   │                   │ │                │ │   entity maps        │
   └───────────────────┘ └────────────────┘ │                      │
                                            │  (bridge via         │
                                            │   inverseOneToMany   │
                                            │   Property →         │
                                            │   ONE_TO_MANY for    │
                                            │   aggregator lookup) │
                                            └──────────────────────┘
```

### Previously
```
┌─────────────────────────────────────────────────────────────────────┐
│                       ALL_METADATA_RELATIONS                       │
│─────────────────────────────────────────────────────────────────────│
│  Derived from: Entity types                                        │
│                                                                    │
│  Structure: { [metadataName]: { manyToOne: {...}, oneToMany: {...},│
│               serializedRelations?: {...} } }                      │
│                                                                    │
│  manyToOne provides:                                               │
│   • metadataName                                                   │
│   • foreignKey                                                     │
│   • flatEntityForeignKeyAggregator (nullable, often wrong/null)    │
│   • isNullable                                                     │
│                                                                    │
│  oneToMany provides:                                               │
│   • metadataName                                                   │
│                                                                    │
│  Monolithic single source of truth                                 │
└──────────────────────────┬──────────────────────────────────────────┘
                           │
                           │ manyToOne entries transformed via
                           │ ToUniversalMetadataManyToOneRelationConfiguration
                           │
                           ▼
┌─────────────────────────────────────────────────────────────────────┐
│                  ALL_UNIVERSAL_METADATA_RELATIONS                   │
│─────────────────────────────────────────────────────────────────────│
│  Derived from: ALL_METADATA_RELATIONS (type-level transform)       │
│                                                                    │
│  Structure: { [metadataName]: { manyToOne: {...}, oneToMany: {...} │
│  } }                                                               │
│                                                                    │
│  manyToOne provides:                                               │
│   • metadataName                                                   │
│   • foreignKey                                                     │
│   • universalForeignKey (derived: FK → replace Id → UniversalId)   │
│   • universalFlatEntityForeignKeyAggregator (derived from          │
│     flatEntityForeignKeyAggregator → replace Ids → UniversalIds)   │
│   • isNullable                                                     │
│                                                                    │
│  oneToMany: passthrough from ALL_METADATA_RELATIONS                │
│                                                                    │
│  Duplicated monolith with universal key transforms                 │
└──────────────────────────┬──────────────────────────────────────────┘
                           │
        ┌──────────────────┼──────────────────────┐
        │                  │                      │
        ▼                  ▼                      ▼
┌───────────────┐ ┌────────────────────┐ ┌──────────────────────┐
│ Type consumers│ │   Atomic utils     │ │  Optimistic utils    │
│───────────────│ │────────────────────│ │──────────────────────│
│ • JoinColumn  │ │ • resolve-entity-  │ │ • add/delete flat    │
│ • RelatedNames│ │   relation-univ-id │ │   entity maps        │
│ • Universal   │ │   (ALL_METADATA_   │ │   (ALL_METADATA_     │
│   FlatEntity  │ │    RELATIONS       │ │    RELATIONS         │
│   From        │ │    .manyToOne)     │ │    .manyToOne)       │
│               │ │                    │ │                      │
│ Mixed usage   │ │ • resolve-univ-    │ │ • add/delete univ    │
│ of both       │ │   relation-ids     │ │   flat entity maps   │
│ constants     │ │   (ALL_UNIVERSAL_  │ │   (ALL_UNIVERSAL_    │
│               │ │    METADATA_REL    │ │    METADATA_REL      │
│               │ │    .manyToOne)     │ │    .manyToOne)       │
│               │ │                    │ │                      │
│               │ │ • resolve-univ-    │ │ universalFlatEntity  │
│               │ │   update-rel-ids   │ │ ForeignKeyAggregator │
│               │ │   (ALL_UNIVERSAL_  │ │ read directly from   │
│               │ │    METADATA_REL    │ │ the constant         │
│               │ │    .manyToOne)     │ │                      │
│               │ │                    │ │                      │
│               │ │ • regex hack:      │ │                      │
│               │ │   foreignKey       │ │                      │
│               │ │   .replace(/Id$/,  │ │                      │
│               │ │   'UniversalId')   │ │                      │
└───────────────┘ └────────────────────┘ └──────────────────────┘
```
2026-02-17 11:13:54 +01:00
8244610bdc i18n - translations (#17983)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 11:05:36 +01:00
e3db73ef46 Change condition for multi-workspace check (#17938)
When deploying with
```
IS_WORKSPACE_CREATION_LIMITED_TO_SERVER_ADMINS=true
IS_MULTIWORKSPACE_ENABLED=true
```
The first workspace can be created successfully. However, any attempt to
create additional workspaces as admin fails with the error: `Workspace
creation is restricted to admins` because `canAccessFullAdminPanel` is
**false**

If these flags are set to false during the initial deployment and
restarting the Docker container, workspace creation works normally.

Problem is caused by `canAccessFullAdminPanel`

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2026-02-17 09:29:59 +01:00
7523143f12 i18n - docs translations (#17981)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-17 09:29:37 +01:00
nitinandGitHub cfc4e0e343 [DASHBOARDS] Add split multi-value fields setting for charts (#17907)
closes https://github.com/twentyhq/twenty/issues/17890



https://github.com/user-attachments/assets/dbf2ebe6-c2da-44d0-846e-d7fa9fac5f43
2026-02-17 09:29:17 +01:00
martmullandGitHub c3d565f266 Add default fields on object manifest (#17977)
as title

<img width="830" height="227" alt="image"
src="https://github.com/user-attachments/assets/8cbf4a14-5d1d-496f-a146-f31079e6e602"
/>
2026-02-16 16:50:46 +01:00
Paul RastoinandGitHub 2b7b05de2e [OBJECT_MANIFEST_BREAKING_CHANGE] Sync returns workspace migration (#17918)
# Introduction
In this PR we start returning a workspace migration post sync so it can
committed and provided within the tarball

## Universal aggregators utils
Created two utils
### deleteUniversalFlatEntityForeignKeyAggregators
Used when building a universal create action, a newly created actions
should not contain any aggregated foreign key so they won't be codegen
in the workspace migration but also they are overriden at uninversal to
flat transpilation anw

### resetUniversalFlatEntityForeignKeyAggregators
Used before validating a new flat entity creation, some validator will
consume the fk aggregator in order to validate integrity, but of
optimstically provided it can result to errors. To avoid caller
responsability we override them here

## create-field-action refactor
Refactored the universal and flat field create action to be following
the base actions in order to ease typing
Also it was tailored to handle unlimited amount of flat field metadata
in the same actions whereas in the reality we were always only sending
at max 2 ( for relation fields )

Note: relation field has to be provided at the same as if not optimistic
would fail to retrieve circular universal identifiers

## ObjectManifest
Now always expect a `labelIdentifierFieldMetadataUniversalIdentifier`

## Integration test
Created an integration test that creates an app, sync a first manifest
and a second implying update workspace migration action generation
2026-02-16 15:00:24 +01:00
4b3c58e013 i18n - docs translations (#17972)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-16 13:51:12 +01:00
Félix MalfaitGitHubCursorclaude[bot] <41898282+claude[bot]@users.noreply.github.com>
c775d65952 feat: configure standard views and migrate attachment seeds to FILES field (#17958)
## Summary

- Add default visible view fields for `timelineActivity`, `attachment`,
`noteTarget`, `taskTarget`, and `workspaceMember` objects so they
display useful columns out of the box
- Standardize morph relation field labels to "Target" with
`IconArrowUpRight` for consistency across all pivot/junction tables
- Mark deprecated fields (`fullPath`, `fileCategory`,
`linkedRecordCachedName`, `linkedRecordId`, `linkedObjectMetadataId`) as
`isSystem` to hide them from the UI column picker
- Fix morph field deduplication logic (`pickMorphGroupSurvivor`) to
prefer active, non-system fields over auto-generated system fields from
custom objects
- Migrate attachment seeds from legacy `fullPath`/`fileCategory` to the
new `FILES` field type, creating proper `FileEntity` records in
`core.file` via `fileStorageService.writeFile()`
- Restore `customDomain` in the user query fragment


<img width="825" height="754" alt="Screenshot 2026-02-15 at 15 44 27"
src="https://github.com/user-attachments/assets/9596a3dd-8d3a-43c0-925a-0adef9ee68a8"
/>
<img width="736" height="731" alt="Screenshot 2026-02-15 at 15 44 13"
src="https://github.com/user-attachments/assets/cd1a66c5-731d-43e6-bbc3-703cbeda1652"
/>
<img width="722" height="757" alt="Screenshot 2026-02-15 at 15 44 03"
src="https://github.com/user-attachments/assets/b5210546-6a40-4940-8e4f-874818a614fb"
/>
<img width="907" height="757" alt="Screenshot 2026-02-15 at 15 43 52"
src="https://github.com/user-attachments/assets/ead5b9a8-1989-4d68-9640-583da6233711"
/>
<img width="1002" height="731" alt="Screenshot 2026-02-15 at 15 43 38"
src="https://github.com/user-attachments/assets/38accb8c-f5d5-4bfc-b245-06389849810b"
/>




<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches migration/upgrade commands that write to core metadata tables
and adjust field/view definitions, plus changes dev seeding to create
`core.file` records; mistakes could affect UI visibility or seed
integrity across workspaces.
> 
> **Overview**
> Adds a new `upgrade:1-18:backfill-standard-views-and-field-metadata`
command that, per workspace, marks specific fields as `isSystem`,
normalizes morph-relation field `label`/`icon` to
`Target`/`IconArrowUpRight`, and backfills missing standard
`view`/`viewField` rows for `attachment`, `noteTarget`, `taskTarget`,
`timelineActivity`, and `workspaceMember`, followed by cache
invalidation + metadata version bump.
> 
> Refactors morph-relation deduplication to pick a single survivor per
`morphId` using a new `pickMorphGroupSurvivor` rule (prefer active +
non-system, then smallest id), with new unit tests.
> 
> Updates standard metadata generators and snapshots to reflect the new
system flags and default view fields, and rewrites attachment dev
seeding to populate the new `file` (FILES field) JSON and create
corresponding `core.file` entries via `FileStorageService.writeFile`
with workspace-scoped file IDs.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b1939bbf6f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-02-16 13:34:56 +01:00
b80146c890 i18n - docs translations (#17967)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-16 12:11:24 +01:00
5604cdbb4b i18n - translations (#17966)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-02-16 11:07:14 +01:00
3799 changed files with 102550 additions and 46980 deletions
+6 -3
View File
@@ -56,7 +56,7 @@ Follow these skills in order:
- Create TypeORM entity (extends `SyncableEntity`)
- Define flat entity types
- Define action types (universal + flat)
- Register in 4 central constants
- Register in 5 central constants
**Why first:** Everything else depends on these types
@@ -177,9 +177,12 @@ packages/twenty-server/src/engine/metadata-modules/
│ ├── services/
│ └── utils/
└── flat-entity/constant/ # Step 1 (central registries)
├── all-entity-properties-configuration-by-metadata-name.constant.ts
├── all-one-to-many-metadata-relations.constant.ts
├── all-many-to-one-metadata-foreign-key.constant.ts
└── all-many-to-one-metadata-relations.constant.ts
packages/twenty-server/src/engine/workspace-manager/workspace-migration/
├── universal-flat-entity/constants/ # Step 1
├── workspace-migration-builder/ # Step 3
│ ├── builders/my-entity/
│ └── validators/services/
@@ -192,7 +195,7 @@ packages/twenty-server/src/engine/workspace-manager/workspace-migration/
Before considering complete:
- [ ] All 6 guides completed
- [ ] TypeORM entity extends `SyncableEntity`
- [ ] All constants registered (4 central registries)
- [ ] All constants registered (5 central registries)
- [ ] Cache service with correct decorator
- [ ] Transform utils return universal flat entities
- [ ] Validator never throws/mutates
@@ -1,6 +1,6 @@
---
name: syncable-entity-types-and-constants
description: Define types, entities, and central constant registrations for syncable entities in Twenty's workspace migration system. Use when creating new syncable entities, defining TypeORM entities, flat entity types, or registering in central constants (ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME, ALL_METADATA_RELATIONS, ALL_UNIVERSAL_METADATA_RELATIONS).
description: Define types, entities, and central constant registrations for syncable entities in Twenty's workspace migration system. Use when creating new syncable entities, defining TypeORM entities, flat entity types, or registering in central constants (ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME, ALL_ONE_TO_MANY_METADATA_RELATIONS, ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY, ALL_MANY_TO_ONE_METADATA_RELATIONS).
---
# Syncable Entity: Types & Constants (Step 1/6)
@@ -18,7 +18,7 @@ This step creates:
2. TypeORM entity (extends `SyncableEntity`)
3. Flat entity types
4. Action types (universal + flat)
5. Central constant registrations (4 constants)
5. Central constant registrations (5 constants)
---
@@ -225,61 +225,91 @@ export const ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME = {
- `toStringify: true` → JSONB/object property (needs JSON serialization)
- `universalProperty` → Maps to universal version (for foreign keys & JSONB with `SerializedRelation`)
### 6c. ALL_METADATA_RELATIONS
### 6c. ALL_ONE_TO_MANY_METADATA_RELATIONS
**File**: `src/engine/metadata-modules/flat-entity/constant/all-metadata-relations.constant.ts`
**File**: `src/engine/metadata-modules/flat-entity/constant/all-one-to-many-metadata-relations.constant.ts`
This constant is **type-checked** — values for `metadataName`, `flatEntityForeignKeyAggregator`, and `universalFlatEntityForeignKeyAggregator` are derived from entity type definitions. The aggregator names follow the pattern: remove trailing `'s'` from the relation property name, then append `Ids` or `UniversalIdentifiers`.
```typescript
export const ALL_METADATA_RELATIONS = {
export const ALL_ONE_TO_MANY_METADATA_RELATIONS = {
// ... existing entries
myEntity: {
manyToOne: {
workspace: null,
application: null,
parentEntity: {
metadataName: 'parentEntity',
flatEntityForeignKeyAggregator: 'myEntityIds',
foreignKey: 'parentEntityId',
isNullable: false,
},
// If myEntity has a `childEntities: ChildEntityEntity[]` property:
childEntities: {
metadataName: 'childEntity',
flatEntityForeignKeyAggregator: 'childEntityIds',
universalFlatEntityForeignKeyAggregator: 'childEntityUniversalIdentifiers',
},
oneToMany: {
childEntities: { metadataName: 'childEntity' },
},
// Only if JSONB contains SerializedRelation fields
serializedRelations: {
fieldMetadata: true,
// null for relations to non-syncable entities
someNonSyncableRelation: null,
},
} as const;
```
### 6d. ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY
**File**: `src/engine/metadata-modules/flat-entity/constant/all-many-to-one-metadata-foreign-key.constant.ts`
Low-level primitive constant. Only contains `foreignKey` — the column name ending in `Id` that stores the foreign key. Type-checked against entity properties.
```typescript
export const ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY = {
// ... existing entries
myEntity: {
workspace: null,
application: null,
parentEntity: {
foreignKey: 'parentEntityId',
},
},
} as const;
```
### 6d. ALL_UNIVERSAL_METADATA_RELATIONS
### 6e. ALL_MANY_TO_ONE_METADATA_RELATIONS
**File**: `src/engine/workspace-manager/workspace-migration/universal-flat-entity/constants/all-universal-metadata-relations.constant.ts`
**File**: `src/engine/metadata-modules/flat-entity/constant/all-many-to-one-metadata-relations.constant.ts`
Derived from both `ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY` (for `foreignKey` type and `universalForeignKey` derivation) and `ALL_ONE_TO_MANY_METADATA_RELATIONS` (for `inverseOneToManyProperty` key constraint). This is the main constant consumed by utils and optimistic tooling.
```typescript
export const ALL_UNIVERSAL_METADATA_RELATIONS = {
export const ALL_MANY_TO_ONE_METADATA_RELATIONS = {
// ... existing entries
myEntity: {
manyToOne: {
workspace: null,
application: null,
parentEntity: {
metadataName: 'parentEntity',
foreignKey: 'parentEntityId',
universalForeignKey: 'parentEntityUniversalIdentifier',
universalFlatEntityForeignKeyAggregator: 'myEntityUniversalIdentifiers',
isNullable: false,
},
},
oneToMany: {
childEntities: { metadataName: 'childEntity' },
workspace: null,
application: null,
parentEntity: {
metadataName: 'parentEntity',
foreignKey: 'parentEntityId',
inverseOneToManyProperty: 'myEntities', // key in ALL_ONE_TO_MANY_METADATA_RELATIONS['parentEntity'], or null if no inverse
isNullable: false,
universalForeignKey: 'parentEntityUniversalIdentifier',
},
},
} as const;
```
**Derivation dependency graph**:
```
ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY ALL_ONE_TO_MANY_METADATA_RELATIONS
(foreignKey only) (metadataName, aggregators)
│ │
│ FK type + universalFK derivation │ inverseOneToManyProperty keys
│ │
└────────────────┬───────────────────────┘
ALL_MANY_TO_ONE_METADATA_RELATIONS
(metadataName, foreignKey, inverseOneToManyProperty,
isNullable, universalForeignKey)
```
**Rules**:
- `workspace: null`, `application: null` — always present, always null (non-syncable relations)
- `inverseOneToManyProperty` — must be a key in `ALL_ONE_TO_MANY_METADATA_RELATIONS[targetMetadataName]`, or `null` if the target entity doesn't expose an inverse one-to-many relation
- `universalForeignKey` — derived from `foreignKey` by replacing the `Id` suffix with `UniversalIdentifier`
- Optimistic utils resolve `flatEntityForeignKeyAggregator` / `universalFlatEntityForeignKeyAggregator` at runtime by looking up `inverseOneToManyProperty` in `ALL_ONE_TO_MANY_METADATA_RELATIONS`
---
## Checklist
@@ -295,8 +325,9 @@ Before moving to Step 2:
- [ ] Universal and flat action types defined
- [ ] Registered in `AllFlatEntityTypesByMetadataName`
- [ ] Registered in `ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME`
- [ ] Registered in `ALL_METADATA_RELATIONS`
- [ ] Registered in `ALL_UNIVERSAL_METADATA_RELATIONS`
- [ ] Registered in `ALL_ONE_TO_MANY_METADATA_RELATIONS` (if entity has one-to-many relations)
- [ ] Registered in `ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY`
- [ ] Registered in `ALL_MANY_TO_ONE_METADATA_RELATIONS`
- [ ] TypeScript compiles without errors
---
+1 -1
View File
@@ -11,7 +11,7 @@ on:
jobs:
deploy-main:
timeout-minutes: 3
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
steps:
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@v2
+1 -1
View File
@@ -11,7 +11,7 @@ on:
jobs:
deploy-tag:
timeout-minutes: 3
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
steps:
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@v2
+1 -1
View File
@@ -16,7 +16,7 @@ permissions:
jobs:
changed-files:
timeout-minutes: 5
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
outputs:
any_changed: ${{ steps.changed-files.outputs.any_changed }}
steps:
+1 -1
View File
@@ -34,7 +34,7 @@ jobs:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 45
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
services:
postgres:
image: twentycrm/twenty-postgres-spilo
+2 -2
View File
@@ -25,7 +25,7 @@ jobs:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
strategy:
matrix:
task: [lint, typecheck, test]
@@ -50,7 +50,7 @@ jobs:
ci-create-app-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
needs: [changed-files-check, create-app-test]
steps:
- name: Fail job if any needs failed
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 10
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
+2 -2
View File
@@ -25,7 +25,7 @@ jobs:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 10
runs-on: ubuntu-latest-8-cores
runs-on: depot-ubuntu-24.04-8
steps:
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@v4
@@ -56,7 +56,7 @@ jobs:
ci-emails-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
needs: [changed-files-check, emails-test]
steps:
- name: Fail job if any needs failed
+12 -19
View File
@@ -14,8 +14,8 @@ concurrency:
env:
# restore-cache action adds 'v4-' prefix and '-<branch>-<sha>' suffix to the key
STORYBOOK_BUILD_CACHE_KEY_FOR_RESTORE_ACTION: storybook-build-ubuntu-latest-8-cores-runner
STORYBOOK_BUILD_CACHE_KEY_FOR_SAVE_ACTION: v4-storybook-build-ubuntu-latest-8-cores-runner-${{ github.ref_name }}-${{ github.sha }}
STORYBOOK_BUILD_CACHE_KEY_FOR_RESTORE_ACTION: storybook-build-depot-ubuntu-24.04-8-runner
STORYBOOK_BUILD_CACHE_KEY_FOR_SAVE_ACTION: v4-storybook-build-depot-ubuntu-24.04-8-runner-${{ github.ref_name }}-${{ github.sha }}
jobs:
changed-files-check:
@@ -42,7 +42,7 @@ jobs:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest-8-cores
runs-on: depot-ubuntu-24.04-8
env:
REACT_APP_SERVER_BASE_URL: http://localhost:3000
steps:
@@ -68,7 +68,7 @@ jobs:
key: ${{ env.STORYBOOK_BUILD_CACHE_KEY_FOR_SAVE_ACTION }}
front-sb-test:
timeout-minutes: 30
runs-on: ubuntu-latest-8-cores
runs-on: depot-ubuntu-24.04-8
needs: front-sb-build
strategy:
fail-fast: false
@@ -115,7 +115,7 @@ jobs:
path: packages/twenty-front/coverage/storybook/coverage-shard-${{matrix.shard}}.json
merge-reports-and-check-coverage:
timeout-minutes: 30
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
needs: front-sb-test
env:
PATH_TO_COVERAGE: packages/twenty-front/coverage/storybook
@@ -143,7 +143,7 @@ jobs:
timeout-minutes: 30
if: false
needs: front-sb-build
runs-on: ubuntu-latest-8-cores
runs-on: depot-ubuntu-24.04-8
env:
REACT_APP_SERVER_BASE_URL: http://127.0.0.1:3000
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
@@ -169,8 +169,9 @@ jobs:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
env:
NODE_OPTIONS: '--max-old-space-size=4096'
TASK_CACHE_KEY: front-task-${{ matrix.task }}
strategy:
matrix:
@@ -202,14 +203,6 @@ jobs:
with:
tag: scope:frontend
tasks: ${{ matrix.task }}
- name: Check for coverage threshold failure
if: always() && steps.run-task.outcome == 'failure' && matrix.task == 'test'
shell: bash
run: |
echo "::error::The test task failed. If no individual test is failing, this is likely a coverage threshold not being met."
echo ""
echo "To debug locally, run: npx nx run twenty-front:test:ci"
exit 1
- name: Save ${{ matrix.task }} cache
uses: ./.github/actions/save-cache
with:
@@ -218,7 +211,7 @@ jobs:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest-8-cores
runs-on: depot-ubuntu-24.04-8
env:
NODE_OPTIONS: "--max-old-space-size=10240"
steps:
@@ -243,7 +236,7 @@ jobs:
path: packages/twenty-front/build
retention-days: 1
e2e-test:
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
needs: [changed-files-check-e2e, front-build]
if: |
always() &&
@@ -353,7 +346,7 @@ jobs:
ci-front-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
needs:
[
changed-files-check,
@@ -370,7 +363,7 @@ jobs:
ci-e2e-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
needs: [changed-files-check-e2e, e2e-test]
steps:
- name: Fail job if any needs failed
+1 -1
View File
@@ -25,7 +25,7 @@ defaults:
jobs:
create_pr:
timeout-minutes: 10
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
+1 -1
View File
@@ -15,7 +15,7 @@ defaults:
jobs:
tag_and_release:
timeout-minutes: 10
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'release')
steps:
- name: Check PR Author
+3 -3
View File
@@ -23,7 +23,7 @@ jobs:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
strategy:
matrix:
task: [lint, typecheck, test:unit, storybook:build, storybook:test, test:integration]
@@ -50,7 +50,7 @@ jobs:
tasks: ${{ matrix.task }}
sdk-e2e-test:
timeout-minutes: 30
runs-on: ubuntu-latest-8-cores
runs-on: depot-ubuntu-24.04-8
needs: [changed-files-check, sdk-test]
if: needs.changed-files-check.outputs.any_changed == 'true'
services:
@@ -94,7 +94,7 @@ jobs:
ci-sdk-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
needs: [changed-files-check, sdk-test, sdk-e2e-test]
steps:
- name: Fail job if any needs failed
+4 -4
View File
@@ -31,7 +31,7 @@ jobs:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest-8-cores
runs-on: depot-ubuntu-24.04-8
services:
postgres:
image: twentycrm/twenty-postgres-spilo
@@ -143,7 +143,7 @@ jobs:
key: ${{ steps.restore-server-setup-cache.outputs.cache-primary-key }}
server-test:
timeout-minutes: 30
runs-on: ubuntu-latest-8-cores
runs-on: depot-ubuntu-24.04-8
needs: server-setup
steps:
- name: Fetch custom Github Actions and base branch history
@@ -164,7 +164,7 @@ jobs:
server-integration-test:
timeout-minutes: 30
runs-on: ubuntu-latest-8-cores
runs-on: depot-ubuntu-24.04-8
needs: server-setup
strategy:
fail-fast: false
@@ -250,7 +250,7 @@ jobs:
ci-server-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
needs: [changed-files-check, server-setup, server-test, server-integration-test]
steps:
- name: Fail job if any needs failed
+4 -2
View File
@@ -22,7 +22,9 @@ jobs:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
env:
NODE_OPTIONS: '--max-old-space-size=4096'
strategy:
matrix:
task: [lint, typecheck, test]
@@ -45,7 +47,7 @@ jobs:
ci-shared-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
needs: [changed-files-check, shared-test]
steps:
- name: Fail job if any needs failed
@@ -23,7 +23,7 @@ jobs:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -92,7 +92,7 @@ jobs:
ci-test-docker-compose-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
needs: [changed-files-check, test]
steps:
- name: Fail job if any needs failed
+2 -2
View File
@@ -25,7 +25,7 @@ concurrency:
jobs:
danger-js:
timeout-minutes: 5
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
if: github.event.action != 'closed'
steps:
- uses: actions/checkout@v4
@@ -38,7 +38,7 @@ jobs:
congratulate:
timeout-minutes: 3
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
if: github.event.action == 'closed' && github.event.pull_request.merged == true
steps:
- uses: actions/checkout@v4
+2 -2
View File
@@ -23,7 +23,7 @@ jobs:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 10
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
services:
postgres:
image: twentycrm/twenty-postgres-spilo
@@ -65,7 +65,7 @@ jobs:
ci-website-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
needs: [changed-files-check, website-build]
steps:
- name: Fail job if any needs failed
+60
View File
@@ -0,0 +1,60 @@
name: CI Zapier
on:
push:
branches:
- main
pull_request:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
packages/twenty-zapier/**
packages/twenty-server/**
!packages/twenty-zapier/package.json
!packages/twenty-zapier/CHANGELOG.md
zapier-test:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
strategy:
matrix:
task: [lint, typecheck, test, validate]
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
uses: ./.github/actions/yarn-install
- name: Build
run: npx nx build twenty-zapier
- name: Run ${{ matrix.task }} task
uses: ./.github/actions/nx-affected
with:
tag: scope:zapier
tasks: ${{ matrix.task }}
ci-zapier-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
needs: [changed-files-check, zapier-test]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
+2 -2
View File
@@ -23,7 +23,7 @@ jobs:
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && github.event.comment.user.type != 'Bot') ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && github.event.review.user.type != 'Bot') ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
timeout-minutes: 60
permissions:
contents: write
@@ -96,7 +96,7 @@ jobs:
claude-cross-repo:
if: github.event_name == 'repository_dispatch'
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
timeout-minutes: 60
permissions:
contents: write
+1 -1
View File
@@ -34,7 +34,7 @@ concurrency:
jobs:
pull_docs_translations:
name: Pull docs translations
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
+1 -1
View File
@@ -21,7 +21,7 @@ concurrency:
jobs:
push_docs:
name: Push documentation to Crowdin
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
+1 -1
View File
@@ -32,7 +32,7 @@ concurrency:
jobs:
pull_translations:
name: Pull translations
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
+1 -1
View File
@@ -17,7 +17,7 @@ concurrency:
jobs:
extract_translations:
name: Extract and upload translations
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
+1 -1
View File
@@ -18,7 +18,7 @@ concurrency:
jobs:
qa_report:
name: Generate QA Report
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
trigger-preview:
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.action == 'reopened' || (github.event.action == 'labeled' && github.event.label.name == 'preview-app')
timeout-minutes: 5
runs-on: ubuntu-latest
runs-on: depot-ubuntu-24.04
steps:
- name: Trigger preview environment workflow
uses: peter-evans/repository-dispatch@v2
+20 -20
View File
@@ -17,7 +17,7 @@ jobs:
uses: actions/checkout@v4
with:
ref: ${{ github.event.client_payload.pr_head_sha }}
- name: Run compose setup
run: |
echo "Patching docker-compose.yml..."
@@ -25,17 +25,17 @@ jobs:
yq eval 'del(.services.server.image)' -i packages/twenty-docker/docker-compose.yml
yq eval '.services.server.build.context = "../../"' -i packages/twenty-docker/docker-compose.yml
yq eval '.services.server.build.dockerfile = "./packages/twenty-docker/twenty/Dockerfile"' -i packages/twenty-docker/docker-compose.yml
yq eval 'del(.services.worker.image)' -i packages/twenty-docker/docker-compose.yml
yq eval '.services.worker.build.context = "../../"' -i packages/twenty-docker/docker-compose.yml
yq eval '.services.worker.build.dockerfile = "./packages/twenty-docker/twenty/Dockerfile"' -i packages/twenty-docker/docker-compose.yml
echo "Adding SIGN_IN_PREFILLED environment variable to server service..."
yq eval '.services.server.environment.SIGN_IN_PREFILLED = "${SIGN_IN_PREFILLED}"' -i packages/twenty-docker/docker-compose.yml
echo "Setting up .env file..."
cp packages/twenty-docker/.env.example packages/twenty-docker/.env
echo "Generating secrets..."
echo "" >> packages/twenty-docker/.env
echo "# === Randomly generated secrets ===" >> packages/twenty-docker/.env
@@ -46,24 +46,24 @@ jobs:
cd packages/twenty-docker/
docker compose build
working-directory: ./
- name: Create Tunnel
id: expose-tunnel
uses: codetalkio/expose-tunnel@v1.5.0
with:
service: bore.pub
port: 3000
- name: Start services with correct SERVER_URL
run: |
cd packages/twenty-docker/
# Update the SERVER_URL with the tunnel URL
echo "Setting SERVER_URL to ${{ steps.expose-tunnel.outputs.tunnel-url }}"
sed -i '/SERVER_URL=/d' .env
echo "" >> .env
echo "SERVER_URL=${{ steps.expose-tunnel.outputs.tunnel-url }}" >> .env
# Start the services
echo "Docker compose up..."
docker compose up -d || {
@@ -71,7 +71,7 @@ jobs:
docker compose logs
exit 1
}
echo "Waiting for services to be ready..."
count=0
while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-db-1) = "healthy" ] || [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-server-1) = "healthy" ]; do
@@ -84,7 +84,7 @@ jobs:
fi
echo "Still waiting for services... ($count/60)"
done
echo "All services are up and running!"
working-directory: ./
@@ -104,7 +104,7 @@ jobs:
echo "✅ Preview Environment Ready!"
echo "🔗 Preview URL: ${{ steps.expose-tunnel.outputs.tunnel-url }}"
echo "⏱️ This environment will be available for 5 hours"
- name: Post comment on PR
uses: actions/github-script@v6
with:
@@ -113,21 +113,21 @@ jobs:
const COMMENT_MARKER = '<!-- PR_PREVIEW_ENV -->';
const commentBody = `${COMMENT_MARKER}
🚀 **Preview Environment Ready!**
Your preview environment is available at: ${{ steps.expose-tunnel.outputs.tunnel-url }}
This environment will automatically shut down when the PR is closed or after 5 hours.`;
// Get all comments
const {data: comments} = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ github.event.client_payload.pr_number }},
});
// Find our comment
const botComment = comments.find(comment => comment.body.includes(COMMENT_MARKER));
if (botComment) {
// Update existing comment
await github.rest.issues.updateComment({
@@ -147,13 +147,13 @@ jobs:
});
console.log('Created new comment');
}
- name: Keep tunnel alive for 5 hours
run: timeout 300m sleep 18000 # Stop on whichever we reach first (300m or 5hour sleep)
- name: Cleanup
if: always()
run: |
cd packages/twenty-docker/
docker compose down -v
working-directory: ./
working-directory: ./
+2
View File
@@ -28,6 +28,8 @@ npx jest path/to/test.test.ts --config=packages/PROJECT/jest.config.mjs
npx nx test twenty-front # Frontend unit tests
npx nx test twenty-server # Backend unit tests
npx nx run twenty-server:test:integration:with-db-reset # Integration tests with DB reset
# To run an indivual test or a pattern of tests, use the following command:
cd packages/{workspace} && npx jest "pattern or filename"
# Storybook
npx nx storybook:build twenty-front
+2 -1
View File
@@ -28,7 +28,7 @@ See:
🚀 [Self-hosting](https://docs.twenty.com/developers/self-hosting/docker-compose)
🖥️ [Local Setup](https://docs.twenty.com/developers/local-setup)
# Does the world need another CRM?
# Why Twenty
We built Twenty for three reasons:
@@ -120,6 +120,7 @@ Below are a few features we have implemented to date:
<a href="https://greptile.com"><img src="./packages/twenty-website/public/images/readme/greptile.png" height="30" alt="Greptile" /></a>
<a href="https://sentry.io/"><img src="./packages/twenty-website/public/images/readme/sentry.png" height="30" alt="Sentry" /></a>
<a href="https://crowdin.com/"><img src="./packages/twenty-website/public/images/readme/crowdin.png" height="30" alt="Crowdin" /></a>
<a href="https://e2b.dev/"><img src="./packages/twenty-website/public/images/readme/e2b.svg" height="30" alt="E2B" /></a>
</p>
Thanks to these amazing services that we use and recommend for UI testing (Chromatic), code review (Greptile), catching bugs (Sentry) and translating (Crowdin).
+4
View File
@@ -83,6 +83,10 @@ export default [
sourceTag: 'scope:frontend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:frontend'],
},
{
sourceTag: 'scope:zapier',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:zapier'],
},
],
},
],
+1
View File
@@ -118,6 +118,7 @@
"outputs": ["{projectRoot}/coverage"],
"options": {
"jestConfig": "{projectRoot}/jest.config.mjs",
"silent": true,
"coverage": true,
"coverageReporters": ["text-summary"],
"cacheDirectory": "../../.cache/jest/{projectRoot}"
+4 -4
View File
@@ -91,10 +91,10 @@
"@storybook/react-vite": "^10.1.11",
"@storybook/test-runner": "^0.24.2",
"@stylistic/eslint-plugin": "^1.5.0",
"@swc-node/register": "1.8.0",
"@swc-node/register": "1.11.1",
"@swc/cli": "^0.3.12",
"@swc/core": "1.13.3",
"@swc/helpers": "~0.5.2",
"@swc/core": "1.15.11",
"@swc/helpers": "~0.5.18",
"@swc/jest": "^0.2.39",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
@@ -137,7 +137,7 @@
"@typescript-eslint/parser": "^8.39.0",
"@typescript-eslint/utils": "^8.39.0",
"@typescript/native-preview": "^7.0.0-dev.20260116.1",
"@vitejs/plugin-react-swc": "3.11.0",
"@vitejs/plugin-react-swc": "4.2.3",
"@vitest/browser-playwright": "^4.0.18",
"@vitest/coverage-istanbul": "^4.0.18",
"@vitest/coverage-v8": "^4.0.18",
+53 -13
View File
@@ -15,7 +15,7 @@
Create Twenty App is the official scaffolding CLI for building apps on top of [Twenty CRM](https://twenty.com). It sets up a readytorun project that works seamlessly with the [twenty-sdk](https://www.npmjs.com/package/twenty-sdk).
- Zeroconfig project bootstrap
- Preconfigured scripts for auth, dev mode (watch & sync), generate, uninstall, and function management
- Preconfigured scripts for auth, dev mode (watch & sync), uninstall, and function management
- Strong TypeScript support and typed client generation
## Documentation
@@ -44,10 +44,8 @@ yarn twenty auth:login
# Add a new entity to your application (guided)
yarn twenty entity:add
# Generate a typed Twenty client and workspace entity types
yarn twenty app:generate
# Start dev mode: watches, builds, and syncs local changes to your workspace
# (also auto-generates a typed API client in node_modules/twenty-sdk/generated)
yarn twenty app:dev
# Watch your application's function logs
@@ -56,25 +54,67 @@ yarn twenty function:logs
# Execute a function with a JSON payload
yarn twenty function:execute -n my-function -p '{"key": "value"}'
# Execute the post-install function
yarn twenty function:execute --postInstall
# Uninstall the application from the current workspace
yarn twenty app:uninstall
```
## Scaffolding modes
Control which example files are included when creating a new app:
| Flag | Behavior |
|------|----------|
| `-e, --exhaustive` | **(default)** Creates all example files without prompting |
| `-m, --minimal` | Creates only core files (`application-config.ts` and `default-role.ts`) |
| `-i, --interactive` | Prompts you to select which examples to include |
```bash
# Default: all examples included
npx create-twenty-app@latest my-app
# Minimal: only core files
npx create-twenty-app@latest my-app -m
# Interactive: choose which examples to include
npx create-twenty-app@latest my-app -i
```
In interactive mode, you can pick from:
- **Example object** — a custom CRM object definition (`objects/example-object.ts`)
- **Example field** — a custom field on the example object (`fields/example-field.ts`)
- **Example logic function** — a server-side handler with HTTP trigger (`logic-functions/hello-world.ts`)
- **Example front component** — a React UI component (`front-components/hello-world.tsx`)
- **Example view** — a saved view for the example object (`views/example-view.ts`)
- **Example navigation menu item** — a sidebar link (`navigation-menu-items/example-navigation-menu-item.ts`)
- **Example skill** — an AI agent skill definition (`skills/example-skill.ts`)
## What gets scaffolded
- A minimal app structure ready for Twenty with example files:
- `application-config.ts` - Application metadata configuration
- `roles/default-role.ts` - Default role for logic functions
- `logic-functions/hello-world.ts` - Example logic function with HTTP trigger
- `front-components/hello-world.tsx` - Example front component
- TypeScript configuration
**Core files (always created):**
- `application-config.ts` — Application metadata configuration
- `roles/default-role.ts` — Default role for logic functions
- `logic-functions/post-install.ts` — Post-install logic function (runs after app installation)
- TypeScript configuration, ESLint, package.json, .gitignore
- A prewired `twenty` script that delegates to the `twenty` CLI from twenty-sdk
**Example files (controlled by scaffolding mode):**
- `objects/example-object.ts` — Example custom object with a text field
- `fields/example-field.ts` — Example standalone field extending the example object
- `logic-functions/hello-world.ts` — Example logic function with HTTP trigger
- `front-components/hello-world.tsx` — Example front component
- `views/example-view.ts` — Example saved view for the example object
- `navigation-menu-items/example-navigation-menu-item.ts` — Example sidebar navigation link
- `skills/example-skill.ts` — Example AI agent skill definition
## Next steps
- Run `yarn twenty help` to see all available commands.
- Use `yarn twenty auth:login` to authenticate with your Twenty workspace.
- Explore the generated project and add your first entity with `yarn twenty entity:add` (logic functions, front components, objects, roles).
- Explore the generated project and add your first entity with `yarn twenty entity:add` (logic functions, front components, objects, roles, views, navigation menu items, skills).
- Use `yarn twenty app:dev` while you iterate — it watches, builds, and syncs changes to your workspace in real time.
- Keep your types uptodate using `yarn twenty app:generate`.
- Types are autogenerated by `yarn twenty app:dev` and stored in `node_modules/twenty-sdk/generated`.
## Publish your application
@@ -103,7 +143,7 @@ Our team reviews contributions for quality, security, and reusability before mer
## Troubleshooting
- Auth prompts not appearing: run `yarn twenty auth:login` again and verify the API key permissions.
- Types not generated: ensure `yarn twenty app:generate` runs without errors, then restart `yarn twenty app:dev`.
- Types not generated: ensure `yarn twenty app:dev` is running — it autogenerates the typed client.
## Contributing
- See our [GitHub](https://github.com/twentyhq/twenty)
+1 -1
View File
@@ -1,5 +1,5 @@
const jestConfig = {
displayName: 'twenty-cli',
displayName: 'create-twenty-app',
preset: '../../jest.preset.js',
testEnvironment: 'node',
transformIgnorePatterns: ['../../node_modules/'],
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "create-twenty-app",
"version": "0.6.0-alpha",
"version": "0.6.1",
"description": "Command-line interface to create Twenty application",
"main": "dist/cli.cjs",
"bin": "dist/cli.cjs",
+52 -11
View File
@@ -2,6 +2,7 @@
import chalk from 'chalk';
import { Command, CommanderError } from 'commander';
import { CreateAppCommand } from '@/create-app.command';
import { type ScaffoldingMode } from '@/types/scaffolding-options';
import packageJson from '../package.json';
const program = new Command(packageJson.name)
@@ -12,18 +13,58 @@ const program = new Command(packageJson.name)
'Output the current version of create-twenty-app.',
)
.argument('[directory]')
.option('-e, --exhaustive', 'Create all example entities (default)')
.option(
'-m, --minimal',
'Create only core entities (application-config and default-role)',
)
.option(
'-i, --interactive',
'Interactively choose which entity examples to include',
)
.helpOption('-h, --help', 'Display this help message.')
.action(async (directory?: string) => {
if (directory && !/^[a-z0-9-]+$/.test(directory)) {
console.error(
chalk.red(
`Invalid directory "${directory}". Must contain only lowercase letters, numbers, and hyphens`,
),
);
process.exit(1);
}
await new CreateAppCommand().execute(directory);
});
.action(
async (
directory?: string,
options?: {
exhaustive?: boolean;
minimal?: boolean;
interactive?: boolean;
},
) => {
const modeFlags = [
options?.exhaustive,
options?.minimal,
options?.interactive,
].filter(Boolean);
if (modeFlags.length > 1) {
console.error(
chalk.red(
'Error: --exhaustive, --minimal, and --interactive are mutually exclusive.',
),
);
process.exit(1);
}
if (directory && !/^[a-z0-9-]+$/.test(directory)) {
console.error(
chalk.red(
`Invalid directory "${directory}". Must contain only lowercase letters, numbers, and hyphens`,
),
);
process.exit(1);
}
const mode: ScaffoldingMode = options?.minimal
? 'minimal'
: options?.interactive
? 'interactive'
: 'exhaustive';
await new CreateAppCommand().execute(directory, mode);
},
);
program.exitOverride();
@@ -0,0 +1,9 @@
## Base documentation
- Documentation: https://docs.twenty.com/developers/extend/capabilities/apps
- Rich app example: https://github.com/twentyhq/twenty/tree/main/packages/twenty-sdk/src/cli/__tests__/apps/rich-app
## Common Pitfalls
- Creating an object without an index view associated. Unless this is a technical object, user will need to visualize it.
- Creating a view without a navigationMenuItem associated. This will make the view available on the left sidebar.
@@ -29,14 +29,17 @@ yarn twenty auth:switch # Switch default workspace
yarn twenty auth:list # List all configured workspaces
# Application
yarn twenty app:dev # Start dev mode (watch, build, and sync)
yarn twenty entity:add # Add a new entity (function, front-component, object, role)
yarn twenty app:generate # Generate typed Twenty client
yarn twenty app:dev # Start dev mode (watch, build, sync, and auto-generate typed client)
yarn twenty entity:add # Add a new entity (object, field, function, front-component, role, view, navigation-menu-item)
yarn twenty function:logs # Stream function logs
yarn twenty function:execute # Execute a function with JSON payload
yarn twenty app:uninstall # Uninstall app from workspace
```
## LLMs instructions
Main docs and pitfalls are available in LLMS.md file.
## Learn More
To learn more about Twenty applications, take a look at the following resources:
@@ -8,14 +8,24 @@ import inquirer from 'inquirer';
import kebabCase from 'lodash.kebabcase';
import * as path from 'path';
import {
type ExampleOptions,
type ScaffoldingMode,
} from '@/types/scaffolding-options';
const CURRENT_EXECUTION_DIRECTORY = process.env.INIT_CWD || process.cwd();
export class CreateAppCommand {
async execute(directory?: string): Promise<void> {
async execute(
directory?: string,
mode: ScaffoldingMode = 'exhaustive',
): Promise<void> {
try {
const { appName, appDisplayName, appDirectory, appDescription } =
await this.getAppInfos(directory);
const exampleOptions = await this.resolveExampleOptions(mode);
await this.validateDirectory(appDirectory);
this.logCreationInfo({ appDirectory, appName });
@@ -27,6 +37,7 @@ export class CreateAppCommand {
appDisplayName,
appDescription,
appDirectory,
exampleOptions,
});
await install(appDirectory);
@@ -92,6 +103,103 @@ export class CreateAppCommand {
return { appName, appDisplayName, appDirectory, appDescription };
}
private async resolveExampleOptions(
mode: ScaffoldingMode,
): Promise<ExampleOptions> {
if (mode === 'minimal') {
return {
includeExampleObject: false,
includeExampleField: false,
includeExampleLogicFunction: false,
includeExampleFrontComponent: false,
includeExampleView: false,
includeExampleNavigationMenuItem: false,
includeExampleSkill: false,
};
}
if (mode === 'exhaustive') {
return {
includeExampleObject: true,
includeExampleField: true,
includeExampleLogicFunction: true,
includeExampleFrontComponent: true,
includeExampleView: true,
includeExampleNavigationMenuItem: true,
includeExampleSkill: true,
};
}
const { selectedExamples } = await inquirer.prompt([
{
type: 'checkbox',
name: 'selectedExamples',
message: 'Select which example files to include:',
choices: [
{
name: 'Example object (custom object definition)',
value: 'object',
checked: true,
},
{
name: 'Example field (custom field on the example object)',
value: 'field',
checked: true,
},
{
name: 'Example logic function (server-side handler)',
value: 'logicFunction',
checked: true,
},
{
name: 'Example front component (React UI component)',
value: 'frontComponent',
checked: true,
},
{
name: 'Example view (saved view for the example object)',
value: 'view',
checked: true,
},
{
name: 'Example navigation menu item (sidebar link)',
value: 'navigationMenuItem',
checked: true,
},
{
name: 'Example skill (AI agent skill definition)',
value: 'skill',
checked: true,
},
],
},
]);
const includeField = selectedExamples.includes('field');
const includeView = selectedExamples.includes('view');
const includeObject =
selectedExamples.includes('object') || includeField || includeView;
if ((includeField || includeView) && !selectedExamples.includes('object')) {
console.log(
chalk.yellow(
'Note: Example object auto-included because example field/view depends on it.',
),
);
}
return {
includeExampleObject: includeObject,
includeExampleField: includeField,
includeExampleLogicFunction: selectedExamples.includes('logicFunction'),
includeExampleFrontComponent: selectedExamples.includes('frontComponent'),
includeExampleView: includeView,
includeExampleNavigationMenuItem:
selectedExamples.includes('navigationMenuItem'),
includeExampleSkill: selectedExamples.includes('skill'),
};
}
private async validateDirectory(appDirectory: string): Promise<void> {
if (!(await fs.pathExists(appDirectory))) {
return;
@@ -0,0 +1,11 @@
export type ScaffoldingMode = 'exhaustive' | 'minimal' | 'interactive';
export type ExampleOptions = {
includeExampleObject: boolean;
includeExampleField: boolean;
includeExampleLogicFunction: boolean;
includeExampleFrontComponent: boolean;
includeExampleView: boolean;
includeExampleNavigationMenuItem: boolean;
includeExampleSkill: boolean;
};
@@ -1,7 +1,9 @@
import * as fs from 'fs-extra';
import { join } from 'path';
import { tmpdir } from 'os';
import { type ExampleOptions } from '@/types/scaffolding-options';
import { GENERATED_DIR } from 'twenty-shared/application';
import { copyBaseApplicationProject } from '@/utils/app-template';
import * as fs from 'fs-extra';
import { tmpdir } from 'os';
import { join } from 'path';
// Mock fs-extra's copy function to skip copying base template (not available during tests)
jest.mock('fs-extra', () => {
@@ -15,6 +17,26 @@ jest.mock('fs-extra', () => {
const APPLICATION_FILE_NAME = 'application-config.ts';
const DEFAULT_ROLE_FILE_NAME = 'default-role.ts';
const ALL_EXAMPLES: ExampleOptions = {
includeExampleObject: true,
includeExampleField: true,
includeExampleLogicFunction: true,
includeExampleFrontComponent: true,
includeExampleView: true,
includeExampleNavigationMenuItem: true,
includeExampleSkill: true,
};
const NO_EXAMPLES: ExampleOptions = {
includeExampleObject: false,
includeExampleField: false,
includeExampleSkill: false,
includeExampleLogicFunction: false,
includeExampleFrontComponent: false,
includeExampleView: false,
includeExampleNavigationMenuItem: false,
};
describe('copyBaseApplicationProject', () => {
let testAppDirectory: string;
@@ -41,6 +63,7 @@ describe('copyBaseApplicationProject', () => {
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
// Verify src/ folder exists
@@ -62,6 +85,7 @@ describe('copyBaseApplicationProject', () => {
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
const packageJsonPath = join(testAppDirectory, 'package.json');
@@ -80,6 +104,7 @@ describe('copyBaseApplicationProject', () => {
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
const gitignorePath = join(testAppDirectory, '.gitignore');
@@ -87,7 +112,7 @@ describe('copyBaseApplicationProject', () => {
const gitignoreContent = await fs.readFile(gitignorePath, 'utf8');
expect(gitignoreContent).toContain('/node_modules');
expect(gitignoreContent).toContain('generated');
expect(gitignoreContent).toContain(GENERATED_DIR);
});
it('should create yarn.lock file', async () => {
@@ -96,6 +121,7 @@ describe('copyBaseApplicationProject', () => {
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
const yarnLockPath = join(testAppDirectory, 'yarn.lock');
@@ -111,6 +137,7 @@ describe('copyBaseApplicationProject', () => {
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
const appConfigPath = join(testAppDirectory, 'src', APPLICATION_FILE_NAME);
@@ -148,6 +175,7 @@ describe('copyBaseApplicationProject', () => {
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
const roleConfigPath = join(
@@ -192,6 +220,7 @@ describe('copyBaseApplicationProject', () => {
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
// Verify fs.copy was called with correct destination
@@ -208,6 +237,7 @@ describe('copyBaseApplicationProject', () => {
appDisplayName: 'My Test App',
appDescription: '',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
const appConfigPath = join(testAppDirectory, 'src', APPLICATION_FILE_NAME);
@@ -225,6 +255,7 @@ describe('copyBaseApplicationProject', () => {
appDisplayName: 'App One',
appDescription: 'First app',
appDirectory: firstAppDir,
exampleOptions: ALL_EXAMPLES,
});
// Create second app
@@ -235,6 +266,7 @@ describe('copyBaseApplicationProject', () => {
appDisplayName: 'App Two',
appDescription: 'Second app',
appDirectory: secondAppDir,
exampleOptions: ALL_EXAMPLES,
});
// Read both app configs
@@ -267,6 +299,7 @@ describe('copyBaseApplicationProject', () => {
appDisplayName: 'App One',
appDescription: 'First app',
appDirectory: firstAppDir,
exampleOptions: ALL_EXAMPLES,
});
// Create second app
@@ -277,6 +310,7 @@ describe('copyBaseApplicationProject', () => {
appDisplayName: 'App Two',
appDescription: 'Second app',
appDirectory: secondAppDir,
exampleOptions: ALL_EXAMPLES,
});
const firstRoleConfig = await fs.readFile(
@@ -299,4 +333,347 @@ describe('copyBaseApplicationProject', () => {
expect(secondUuid).toBeDefined();
expect(firstUuid).not.toBe(secondUuid);
});
describe('scaffolding modes', () => {
describe('exhaustive mode (all examples)', () => {
it('should create all example files when all options are enabled', async () => {
await copyBaseApplicationProject({
appName: 'my-test-app',
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
const srcPath = join(testAppDirectory, 'src');
expect(
await fs.pathExists(join(srcPath, 'objects', 'example-object.ts')),
).toBe(true);
expect(
await fs.pathExists(join(srcPath, 'fields', 'example-field.ts')),
).toBe(true);
expect(
await fs.pathExists(
join(srcPath, 'logic-functions', 'hello-world.ts'),
),
).toBe(true);
expect(
await fs.pathExists(
join(srcPath, 'front-components', 'hello-world.tsx'),
),
).toBe(true);
expect(
await fs.pathExists(join(srcPath, 'views', 'example-view.ts')),
).toBe(true);
expect(
await fs.pathExists(
join(
srcPath,
'navigation-menu-items',
'example-navigation-menu-item.ts',
),
),
).toBe(true);
});
});
describe('minimal mode (no examples)', () => {
it('should create only core files when no examples are enabled', async () => {
await copyBaseApplicationProject({
appName: 'my-test-app',
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: NO_EXAMPLES,
});
const srcPath = join(testAppDirectory, 'src');
// Core files should exist
expect(await fs.pathExists(join(srcPath, APPLICATION_FILE_NAME))).toBe(
true,
);
expect(
await fs.pathExists(join(srcPath, 'roles', DEFAULT_ROLE_FILE_NAME)),
).toBe(true);
// Example files should not exist
expect(
await fs.pathExists(join(srcPath, 'objects', 'example-object.ts')),
).toBe(false);
expect(
await fs.pathExists(join(srcPath, 'fields', 'example-field.ts')),
).toBe(false);
expect(
await fs.pathExists(
join(srcPath, 'logic-functions', 'hello-world.ts'),
),
).toBe(false);
expect(
await fs.pathExists(
join(srcPath, 'front-components', 'hello-world.tsx'),
),
).toBe(false);
expect(
await fs.pathExists(join(srcPath, 'views', 'example-view.ts')),
).toBe(false);
expect(
await fs.pathExists(
join(
srcPath,
'navigation-menu-items',
'example-navigation-menu-item.ts',
),
),
).toBe(false);
});
});
describe('selective examples', () => {
it('should create only front component when only that option is enabled', async () => {
await copyBaseApplicationProject({
appName: 'my-test-app',
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: {
includeExampleObject: false,
includeExampleField: false,
includeExampleSkill: false,
includeExampleLogicFunction: false,
includeExampleFrontComponent: true,
includeExampleView: false,
includeExampleNavigationMenuItem: false,
},
});
const srcPath = join(testAppDirectory, 'src');
expect(
await fs.pathExists(
join(srcPath, 'front-components', 'hello-world.tsx'),
),
).toBe(true);
expect(
await fs.pathExists(join(srcPath, 'objects', 'example-object.ts')),
).toBe(false);
expect(
await fs.pathExists(join(srcPath, 'fields', 'example-field.ts')),
).toBe(false);
expect(
await fs.pathExists(
join(srcPath, 'logic-functions', 'hello-world.ts'),
),
).toBe(false);
});
it('should create only logic function when only that option is enabled', async () => {
await copyBaseApplicationProject({
appName: 'my-test-app',
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: {
includeExampleObject: false,
includeExampleSkill: false,
includeExampleField: false,
includeExampleLogicFunction: true,
includeExampleFrontComponent: false,
includeExampleView: false,
includeExampleNavigationMenuItem: false,
},
});
const srcPath = join(testAppDirectory, 'src');
expect(
await fs.pathExists(
join(srcPath, 'logic-functions', 'hello-world.ts'),
),
).toBe(true);
expect(
await fs.pathExists(join(srcPath, 'objects', 'example-object.ts')),
).toBe(false);
});
});
});
describe('example object', () => {
it('should create example-object.ts with defineObject and correct structure', async () => {
await copyBaseApplicationProject({
appName: 'my-test-app',
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
const objectPath = join(
testAppDirectory,
'src',
'objects',
'example-object.ts',
);
expect(await fs.pathExists(objectPath)).toBe(true);
const content = await fs.readFile(objectPath, 'utf8');
expect(content).toContain(
"import { defineObject, FieldType } from 'twenty-sdk'",
);
expect(content).toContain('export default defineObject({');
expect(content).toContain(
'export const EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER',
);
expect(content).toContain('export const NAME_FIELD_UNIVERSAL_IDENTIFIER');
expect(content).toContain("nameSingular: 'exampleItem'");
expect(content).toContain("namePlural: 'exampleItems'");
expect(content).toContain('FieldType.TEXT');
expect(content).toContain(
'labelIdentifierFieldMetadataUniversalIdentifier: NAME_FIELD_UNIVERSAL_IDENTIFIER',
);
});
it('should generate unique UUIDs for example objects across apps', async () => {
const firstAppDir = join(testAppDirectory, 'app1');
await fs.ensureDir(firstAppDir);
await copyBaseApplicationProject({
appName: 'app-one',
appDisplayName: 'App One',
appDescription: 'First app',
appDirectory: firstAppDir,
exampleOptions: ALL_EXAMPLES,
});
const secondAppDir = join(testAppDirectory, 'app2');
await fs.ensureDir(secondAppDir);
await copyBaseApplicationProject({
appName: 'app-two',
appDisplayName: 'App Two',
appDescription: 'Second app',
appDirectory: secondAppDir,
exampleOptions: ALL_EXAMPLES,
});
const firstContent = await fs.readFile(
join(firstAppDir, 'src', 'objects', 'example-object.ts'),
'utf8',
);
const secondContent = await fs.readFile(
join(secondAppDir, 'src', 'objects', 'example-object.ts'),
'utf8',
);
const uuidRegex =
/EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER =\s*'([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})'/;
const firstUuid = firstContent.match(uuidRegex)?.[1];
const secondUuid = secondContent.match(uuidRegex)?.[1];
expect(firstUuid).toBeDefined();
expect(secondUuid).toBeDefined();
expect(firstUuid).not.toBe(secondUuid);
});
});
describe('example field', () => {
it('should create example-field.ts with defineField referencing the object', async () => {
await copyBaseApplicationProject({
appName: 'my-test-app',
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
const fieldPath = join(
testAppDirectory,
'src',
'fields',
'example-field.ts',
);
expect(await fs.pathExists(fieldPath)).toBe(true);
const content = await fs.readFile(fieldPath, 'utf8');
expect(content).toContain(
"import { defineField, FieldType } from 'twenty-sdk'",
);
expect(content).toContain(
"import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/objects/example-object'",
);
expect(content).toContain('export default defineField({');
expect(content).toContain(
'objectUniversalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER',
);
expect(content).toContain('FieldType.NUMBER');
expect(content).toContain("name: 'priority'");
});
});
describe('example view', () => {
it('should create example-view.ts with defineView referencing the object', async () => {
await copyBaseApplicationProject({
appName: 'my-test-app',
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
const viewPath = join(
testAppDirectory,
'src',
'views',
'example-view.ts',
);
expect(await fs.pathExists(viewPath)).toBe(true);
const content = await fs.readFile(viewPath, 'utf8');
expect(content).toContain("import { defineView } from 'twenty-sdk'");
expect(content).toContain(
"import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/objects/example-object'",
);
expect(content).toContain('export default defineView({');
expect(content).toContain(
'objectUniversalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER',
);
expect(content).toContain("name: 'example-view'");
});
});
describe('example navigation menu item', () => {
it('should create example-navigation-menu-item.ts with defineNavigationMenuItem', async () => {
await copyBaseApplicationProject({
appName: 'my-test-app',
appDisplayName: 'My Test App',
appDescription: 'A test application',
appDirectory: testAppDirectory,
exampleOptions: ALL_EXAMPLES,
});
const navPath = join(
testAppDirectory,
'src',
'navigation-menu-items',
'example-navigation-menu-item.ts',
);
expect(await fs.pathExists(navPath)).toBe(true);
const content = await fs.readFile(navPath, 'utf8');
expect(content).toContain(
"import { defineNavigationMenuItem } from 'twenty-sdk'",
);
expect(content).toContain('export default defineNavigationMenuItem({');
expect(content).toContain("name: 'example-navigation-menu-item'");
expect(content).toContain("icon: 'IconList'");
expect(content).toContain('position: 0');
});
});
});
@@ -3,6 +3,8 @@ import { join } from 'path';
import { v4 } from 'uuid';
import { ASSETS_DIR } from 'twenty-shared/application';
import { type ExampleOptions } from '@/types/scaffolding-options';
const SRC_FOLDER = 'src';
export const copyBaseApplicationProject = async ({
@@ -10,11 +12,13 @@ export const copyBaseApplicationProject = async ({
appDisplayName,
appDescription,
appDirectory,
exampleOptions,
}: {
appName: string;
appDisplayName: string;
appDescription: string;
appDirectory: string;
exampleOptions: ExampleOptions;
}) => {
await fs.copy(join(__dirname, './constants/base-application'), appDirectory);
@@ -37,16 +41,66 @@ export const copyBaseApplicationProject = async ({
fileName: 'default-role.ts',
});
await createDefaultFrontComponent({
appDirectory: sourceFolderPath,
fileFolder: 'front-components',
fileName: 'hello-world.tsx',
});
if (exampleOptions.includeExampleObject) {
await createExampleObject({
appDirectory: sourceFolderPath,
fileFolder: 'objects',
fileName: 'example-object.ts',
});
}
await createDefaultFunction({
if (exampleOptions.includeExampleField) {
await createExampleField({
appDirectory: sourceFolderPath,
fileFolder: 'fields',
fileName: 'example-field.ts',
});
}
if (exampleOptions.includeExampleLogicFunction) {
await createDefaultFunction({
appDirectory: sourceFolderPath,
fileFolder: 'logic-functions',
fileName: 'hello-world.ts',
});
}
if (exampleOptions.includeExampleFrontComponent) {
await createDefaultFrontComponent({
appDirectory: sourceFolderPath,
fileFolder: 'front-components',
fileName: 'hello-world.tsx',
});
}
if (exampleOptions.includeExampleView) {
await createExampleView({
appDirectory: sourceFolderPath,
fileFolder: 'views',
fileName: 'example-view.ts',
});
}
if (exampleOptions.includeExampleNavigationMenuItem) {
await createExampleNavigationMenuItem({
appDirectory: sourceFolderPath,
fileFolder: 'navigation-menu-items',
fileName: 'example-navigation-menu-item.ts',
});
}
if (exampleOptions.includeExampleSkill) {
await createExampleSkill({
appDirectory: sourceFolderPath,
fileFolder: 'skills',
fileName: 'example-skill.ts',
});
}
await createDefaultPostInstallFunction({
appDirectory: sourceFolderPath,
fileFolder: 'logic-functions',
fileName: 'hello-world.ts',
fileName: 'post-install.ts',
});
await createApplicationConfig({
@@ -196,7 +250,6 @@ const handler = async (): Promise<{ message: string }> => {
return { message: 'Hello, World!' };
};
// Logic function handler - rename and implement your logic
export default defineLogicFunction({
universalIdentifier: '${universalIdentifier}',
name: 'hello-world-logic-function',
@@ -215,6 +268,200 @@ export default defineLogicFunction({
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
};
const createDefaultPostInstallFunction = async ({
appDirectory,
fileFolder,
fileName,
}: {
appDirectory: string;
fileFolder?: string;
fileName: string;
}) => {
const universalIdentifier = v4();
const content = `import { defineLogicFunction } from 'twenty-sdk';
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '${universalIdentifier}';
const handler = async (): Promise<void> => {
console.log('Post install logic function executed successfully!');
};
export default defineLogicFunction({
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
name: 'post-install',
description: 'Runs after installation to set up the application.',
timeoutSeconds: 300,
handler,
});
`;
await fs.ensureDir(join(appDirectory, fileFolder ?? ''));
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
};
const createExampleObject = async ({
appDirectory,
fileFolder,
fileName,
}: {
appDirectory: string;
fileFolder?: string;
fileName: string;
}) => {
const objectUniversalIdentifier = v4();
const nameFieldUniversalIdentifier = v4();
const content = `import { defineObject, FieldType } from 'twenty-sdk';
export const EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER =
'${objectUniversalIdentifier}';
export const NAME_FIELD_UNIVERSAL_IDENTIFIER =
'${nameFieldUniversalIdentifier}';
export default defineObject({
universalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER,
nameSingular: 'exampleItem',
namePlural: 'exampleItems',
labelSingular: 'Example item',
labelPlural: 'Example items',
description: 'A sample custom object',
icon: 'IconBox',
labelIdentifierFieldMetadataUniversalIdentifier: NAME_FIELD_UNIVERSAL_IDENTIFIER,
fields: [
{
universalIdentifier: NAME_FIELD_UNIVERSAL_IDENTIFIER,
type: FieldType.TEXT,
name: 'name',
label: 'Name',
description: 'Name of the example item',
icon: 'IconAbc',
},
],
});
`;
await fs.ensureDir(join(appDirectory, fileFolder ?? ''));
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
};
const createExampleField = async ({
appDirectory,
fileFolder,
fileName,
}: {
appDirectory: string;
fileFolder?: string;
fileName: string;
}) => {
const universalIdentifier = v4();
const content = `import { defineField, FieldType } from 'twenty-sdk';
import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/objects/example-object';
export default defineField({
objectUniversalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER,
universalIdentifier: '${universalIdentifier}',
type: FieldType.NUMBER,
name: 'priority',
label: 'Priority',
description: 'Priority level for the example item (1-10)',
});
`;
await fs.ensureDir(join(appDirectory, fileFolder ?? ''));
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
};
const createExampleView = async ({
appDirectory,
fileFolder,
fileName,
}: {
appDirectory: string;
fileFolder?: string;
fileName: string;
}) => {
const universalIdentifier = v4();
const content = `import { defineView } from 'twenty-sdk';
import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/objects/example-object';
export default defineView({
universalIdentifier: '${universalIdentifier}',
name: 'example-view',
objectUniversalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER,
icon: 'IconList',
position: 0,
});
`;
await fs.ensureDir(join(appDirectory, fileFolder ?? ''));
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
};
const createExampleNavigationMenuItem = async ({
appDirectory,
fileFolder,
fileName,
}: {
appDirectory: string;
fileFolder?: string;
fileName: string;
}) => {
const universalIdentifier = v4();
const content = `import { defineNavigationMenuItem } from 'twenty-sdk';
export default defineNavigationMenuItem({
universalIdentifier: '${universalIdentifier}',
name: 'example-navigation-menu-item',
icon: 'IconList',
position: 0,
// Link to a view:
// viewUniversalIdentifier: '...',
// Or link to an object:
// targetObjectUniversalIdentifier: '...',
// Or link to an external URL:
// link: 'https://example.com',
});
`;
await fs.ensureDir(join(appDirectory, fileFolder ?? ''));
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
};
const createExampleSkill = async ({
appDirectory,
fileFolder,
fileName,
}: {
appDirectory: string;
fileFolder?: string;
fileName: string;
}) => {
const universalIdentifier = v4();
const content = `import { defineSkill } from 'twenty-sdk';
export const EXAMPLE_SKILL_UNIVERSAL_IDENTIFIER =
'${universalIdentifier}';
export default defineSkill({
universalIdentifier: EXAMPLE_SKILL_UNIVERSAL_IDENTIFIER,
name: 'example-skill',
label: 'Example Skill',
description: 'A sample skill for your application',
icon: 'IconBrain',
content: 'Add your skill instructions here. Skills provide context and capabilities to AI agents.',
});
`;
await fs.ensureDir(join(appDirectory, fileFolder ?? ''));
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
};
const createApplicationConfig = async ({
displayName,
description,
@@ -230,12 +477,14 @@ const createApplicationConfig = async ({
}) => {
const content = `import { defineApplication } from 'twenty-sdk';
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
universalIdentifier: '${v4()}',
displayName: '${displayName}',
description: '${description ?? ''}',
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
`;
@@ -17,7 +17,6 @@
},
"scripts": {
"auth": "twenty auth login",
"generate": "twenty app generate",
"dev": "twenty app dev",
"sync": "twenty app sync",
"uninstall": "twenty app uninstall",
@@ -17,7 +17,6 @@
},
"scripts": {
"auth": "twenty auth login",
"generate": "twenty app generate",
"dev": "twenty app dev",
"sync": "twenty app sync",
"uninstall": "twenty app uninstall",
@@ -17,7 +17,6 @@
},
"scripts": {
"auth": "twenty auth login",
"generate": "twenty app generate",
"dev": "twenty app dev",
"sync": "twenty app sync",
"uninstall": "twenty app uninstall",
@@ -11,7 +11,6 @@
"scripts": {
"create-entity": "twenty app add",
"dev": "twenty app dev",
"generate": "twenty app generate",
"sync": "twenty app sync",
"uninstall": "twenty app uninstall",
"auth": "twenty auth login"
@@ -17,7 +17,6 @@
"app:dev": "twenty app dev",
"app:sync": "twenty app sync",
"entity:add": "twenty entity add",
"app:generate": "twenty app generate",
"function:logs": "twenty function logs",
"function:execute": "twenty function execute",
"app:uninstall": "twenty app uninstall",
@@ -14,6 +14,7 @@ Apps let you build and manage Twenty customizations **as code**. Instead of conf
**What you can do today:**
- Define custom objects and fields as code (managed data model)
- Build logic functions with custom triggers
- Define skills for AI agents
- Deploy the same app across multiple workspaces
## Prerequisites
@@ -26,7 +27,7 @@ Apps let you build and manage Twenty customizations **as code**. Instead of conf
Create a new app using the official scaffolder, then authenticate and start developing:
```bash filename="Terminal"
# Scaffold a new app
# Scaffold a new app (includes all examples by default)
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
@@ -41,21 +42,34 @@ yarn twenty auth:login
yarn twenty app:dev
```
The scaffolder supports three modes for controlling which example files are included:
```bash filename="Terminal"
# Default (exhaustive): all examples (object, field, logic function, front component, view, navigation menu item, skill)
npx create-twenty-app@latest my-app
# Minimal: only core files (application-config.ts and default-role.ts)
npx create-twenty-app@latest my-app --minimal
# Interactive: select which examples to include
npx create-twenty-app@latest my-app --interactive
```
From here you can:
```bash filename="Terminal"
# Add a new entity to your application (guided)
yarn twenty entity:add
# Generate a typed Twenty client and workspace entity types
yarn twenty app:generate
# Watch your application's function logs
yarn twenty function:logs
# Execute a function by name
yarn twenty function:execute -n my-function -p '{"name": "test"}'
# Execute the post-install function
yarn twenty function:execute --postInstall
# Uninstall the application from the current workspace
yarn twenty app:uninstall
@@ -72,9 +86,9 @@ When you run `npx create-twenty-app@latest my-twenty-app`, the scaffolder:
- Copies a minimal base application into `my-twenty-app/`
- Adds a local `twenty-sdk` dependency and Yarn 4 configuration
- Creates config files and scripts wired to the `twenty` CLI
- Generates a default application config and a default function role
- Generates core files (application config, default function role, post-install function) plus example files based on the scaffolding mode
A freshly scaffolded app looks like this:
A freshly scaffolded app with the default `--exhaustive` mode looks like this:
```text filename="my-twenty-app/"
my-twenty-app/
@@ -93,12 +107,25 @@ my-twenty-app/
├── application-config.ts # Required - main application configuration
├── roles/
│ └── default-role.ts # Default role for logic functions
├── objects/
│ └── example-object.ts # Example custom object definition
├── fields/
│ └── example-field.ts # Example standalone field definition
├── logic-functions/
── hello-world.ts # Example logic function
└── front-components/
└── hello-world.tsx # Example front component
── hello-world.ts # Example logic function
└── post-install.ts # Post-install logic function
├── front-components/
│ └── hello-world.tsx # Example front component
├── views/
│ └── example-view.ts # Example saved view definition
├── navigation-menu-items/
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
└── skills/
└── example-skill.ts # Example AI agent skill definition
```
With `--minimal`, only the core files are created (`application-config.ts`, `roles/default-role.ts`, and `logic-functions/post-install.ts`). With `--interactive`, you choose which example files to include.
At a high level:
- **package.json**: Declares the app name, version, engines (Node 24+, Yarn 4), and adds `twenty-sdk` plus a `twenty` script that delegates to the local `twenty` CLI. Run `yarn twenty help` to list all available commands.
@@ -121,6 +148,9 @@ The SDK detects entities by parsing your TypeScript files for **`export default
| `defineFrontComponent()` | Front component definitions |
| `defineRole()` | Role definitions |
| `defineField()` | Field extensions for existing objects |
| `defineView()` | Saved view definitions |
| `defineNavigationMenuItem()` | Navigation menu item definitions |
| `defineSkill()` | AI agent skill definitions |
<Note>
**File naming is flexible.** Entity detection is AST-based — the SDK scans your source files for the `export default define<Entity>({...})` pattern. You can organize your files and folders however you like. Grouping by entity type (e.g., `logic-functions/`, `roles/`) is just a convention for code organization, not a requirement.
@@ -140,8 +170,8 @@ export default defineObject({
Later commands will add more files and folders:
- `yarn twenty app:generate` will create a `generated/` folder (typed Twenty client + workspace types).
- `yarn twenty entity:add` will add entity definition files under `src/` for your custom objects, functions, front components, or roles.
- `yarn twenty app:dev` will auto-generate a typed API client in `node_modules/twenty-sdk/generated` (typed Twenty client + workspace types).
- `yarn twenty entity:add` will add entity definition files under `src/` for your custom objects, functions, front components, roles, skills, and more.
## Authentication
@@ -192,6 +222,9 @@ The SDK provides helper functions for defining your app entities. As described i
| `defineFrontComponent()` | Define front components for custom UI |
| `defineRole()` | Configure role permissions and object access |
| `defineField()` | Extend existing objects with additional fields |
| `defineView()` | Define saved views for objects |
| `defineNavigationMenuItem()` | Define sidebar navigation links |
| `defineSkill()` | Define AI agent skills |
These functions validate your configuration at build time and provide IDE autocompletion and type safety.
@@ -277,7 +310,11 @@ Key points:
- You can scaffold new objects using `yarn twenty entity:add`, which guides you through naming, fields, and relationships.
<Note>
**Base fields are created automatically.** When you define a custom object, Twenty automatically adds standard fields such as `name`, `createdAt`, `updatedAt`, `createdBy`, `position`, and `deletedAt`. You don't need to define these in your `fields` array — only add your custom fields.
**Base fields are created automatically.** When you define a custom object, Twenty automatically adds standard fields
such as `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` and `deletedAt`.
You don't need to define these in your `fields` array — only add your custom fields.
You can override default fields by defining a field with the same name in your `fields` array,
but this is not recommended.
</Note>
@@ -288,6 +325,7 @@ Every app has a single `application-config.ts` file that describes:
- **Who the app is**: identifiers, display name, and description.
- **How its functions run**: which role they use for permissions.
- **(Optional) variables**: keyvalue pairs exposed to your functions as environment variables.
- **(Optional) post-install function**: a logic function that runs after the app is installed.
Use `defineApplication()` to define your application configuration:
@@ -295,6 +333,7 @@ Use `defineApplication()` to define your application configuration:
// src/application-config.ts
import { defineApplication } from 'twenty-sdk';
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
@@ -310,6 +349,7 @@ export default defineApplication({
},
},
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
@@ -317,6 +357,7 @@ Notes:
- `universalIdentifier` fields are deterministic IDs you own; generate them once and keep them stable across syncs.
- `applicationVariables` become environment variables for your functions (for example, `DEFAULT_RECIPIENT_NAME` is available as `process.env.DEFAULT_RECIPIENT_NAME`).
- `defaultRoleUniversalIdentifier` must match the role file (see below).
- `postInstallLogicFunctionUniversalIdentifier` (optional) points to a logic function that runs automatically after the app is installed. See [Post-install functions](#post-install-functions).
#### Roles and permissions
@@ -449,6 +490,54 @@ Notes:
- The `triggers` array is optional. Functions without triggers can be used as utility functions called by other functions.
- You can mix multiple trigger types in a single function.
### Post-install functions
A post-install function is a logic function that runs automatically after your app is installed on a workspace. This is useful for one-time setup tasks such as seeding default data, creating initial records, or configuring workspace settings.
When you scaffold a new app with `create-twenty-app`, a post-install function is generated for you at `src/logic-functions/post-install.ts`:
```typescript
// src/logic-functions/post-install.ts
import { defineLogicFunction } from 'twenty-sdk';
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
const handler = async (): Promise<void> => {
console.log('Post install logic function executed successfully!');
};
export default defineLogicFunction({
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
name: 'post-install',
description: 'Runs after installation to set up the application.',
timeoutSeconds: 300,
handler,
});
```
The function is wired into your app by referencing its universal identifier in `application-config.ts`:
```typescript
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
// ...
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
You can also manually execute the post-install function at any time using the CLI:
```bash filename="Terminal"
yarn twenty function:execute --postInstall
```
Key points:
- Post-install functions are standard logic functions — they use `defineLogicFunction()` like any other function.
- The `postInstallLogicFunctionUniversalIdentifier` field in `defineApplication()` is optional. If omitted, no function runs after installation.
- The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
- Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `function:execute --postInstall`.
### Route trigger payload
<Warning>
@@ -645,9 +734,43 @@ You can create new front components in two ways:
- **Scaffolded**: Run `yarn twenty entity:add` and choose the option to add a new front component.
- **Manual**: Create a new `*.front-component.tsx` file and use `defineFrontComponent()`.
### Skills
Skills define reusable instructions and capabilities that AI agents can use within your workspace. Use `defineSkill()` to define skills with built-in validation:
```typescript
// src/skills/example-skill.ts
import { defineSkill } from 'twenty-sdk';
export default defineSkill({
universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
name: 'sales-outreach',
label: 'Sales Outreach',
description: 'Guides the AI agent through a structured sales outreach process',
icon: 'IconBrain',
content: `You are a sales outreach assistant. When reaching out to a prospect:
1. Research the company and recent news
2. Identify the prospect's role and likely pain points
3. Draft a personalized message referencing specific details
4. Keep the tone professional but conversational`,
});
```
Key points:
- `name` is a unique identifier string for the skill (kebab-case recommended).
- `label` is the human-readable display name shown in the UI.
- `content` contains the skill instructions — this is the text the AI agent uses.
- `icon` (optional) sets the icon displayed in the UI.
- `description` (optional) provides additional context about the skill's purpose.
You can create new skills in two ways:
- **Scaffolded**: Run `yarn twenty entity:add` and choose the option to add a new skill.
- **Manual**: Create a new file and use `defineSkill()`, following the same pattern.
### Generated typed client
Run `yarn twenty app:generate` to create a local typed client in `generated/` based on your workspace schema. Use it in your functions:
The typed client is auto-generated by `yarn twenty app:dev` and stored in `node_modules/twenty-sdk/generated` based on your workspace schema. Use it in your functions:
```typescript
import Twenty from '~/generated';
@@ -656,7 +779,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
The client is re-generated by `yarn twenty app:generate`. Re-run after changing your objects or when onboarding to a new workspace.
The client is re-generated automatically by `yarn twenty app:dev` whenever your objects or fields change.
#### Runtime credentials in logic functions
@@ -670,6 +793,51 @@ Notes:
- The API key's permissions are determined by the role referenced in your `application-config.ts` via `defaultRoleUniversalIdentifier`. This is the default role used by logic functions of your application.
- Applications can define roles to follow leastprivilege. Grant only the permissions your functions need, then point `defaultRoleUniversalIdentifier` to that role's universal identifier.
#### Uploading files
The generated `Twenty` client includes an `uploadFile` method for attaching files to file-type fields on your workspace objects. Because standard GraphQL clients do not support multipart file uploads natively, the client provides this dedicated method that implements the [GraphQL multipart request specification](https://github.com/jaydenseric/graphql-multipart-request-spec) under the hood.
```typescript
import Twenty from '~/generated';
import * as fs from 'fs';
const client = new Twenty();
const fileBuffer = fs.readFileSync('./invoice.pdf');
const uploadedFile = await client.uploadFile(
fileBuffer, // file contents as a Buffer
'invoice.pdf', // filename
'application/pdf', // MIME type (defaults to 'application/octet-stream')
'58a0a314-d7ea-4865-9850-7fb84e72f30b', // field universal identifier
);
console.log(uploadedFile);
// { id: '...', path: '...', size: 12345, createdAt: '...', url: 'https://...' }
```
The method signature:
```typescript
uploadFile(
fileBuffer: Buffer,
filename: string,
contentType: string,
fieldMetadataUniversalIdentifier: string,
): Promise<{ id: string; path: string; size: number; createdAt: string; url: string }>
```
| Parameter | Type | Description |
|-----------|------|-------------|
| `fileBuffer` | `Buffer` | The raw file contents |
| `filename` | `string` | The name of the file (used for storage and display) |
| `contentType` | `string` | MIME type of the file (defaults to `application/octet-stream` if omitted) |
| `fieldMetadataUniversalIdentifier` | `string` | The `universalIdentifier` of the file-type field on your object |
Key points:
- The method sends the file to the **metadata endpoint** (not the main GraphQL endpoint), where the upload mutation is resolved.
- It uses the field's `universalIdentifier` (not its workspace-specific ID), so your upload code works across any workspace where your app is installed — consistent with how apps reference fields everywhere else.
- The returned `url` is a signed URL you can use to access the uploaded file.
### Hello World example
@@ -693,13 +861,13 @@ Then add a `twenty` script:
}
```
Now you can run all commands via `yarn twenty <command>`, e.g. `yarn twenty app:dev`, `yarn twenty app:generate`, `yarn twenty help`, etc.
Now you can run all commands via `yarn twenty <command>`, e.g. `yarn twenty app:dev`, `yarn twenty help`, etc.
## Troubleshooting
- Authentication errors: run `yarn twenty auth:login` and ensure your API key has the required permissions.
- Cannot connect to server: verify the API URL and that the Twenty server is reachable.
- Types or client missing/outdated: run `yarn twenty app:generate`.
- Types or client missing/outdated: restart `yarn twenty app:dev` — it auto-generates the typed client.
- Dev mode not syncing: ensure `yarn twenty app:dev` is running and that changes are not ignored by your environment.
Discord Help Channel: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -15,6 +15,7 @@ description: أنشئ وأدِر تخصيصات Twenty على هيئة كود.
* عرِّف كائنات وحقولًا مخصصة على شكل كود (نموذج بيانات مُدار)
* أنشئ وظائف منطقية مع مشغلات مخصصة
* حدد المهارات لوكلاء الذكاء الاصطناعي
* انشر التطبيق نفسه عبر مساحات عمل متعددة
## المتطلبات الأساسية
@@ -27,7 +28,7 @@ description: أنشئ وأدِر تخصيصات Twenty على هيئة كود.
أنشئ تطبيقًا جديدًا باستخدام المُهيئ الرسمي، ثم قم بالمصادقة وابدأ التطوير:
```bash filename="Terminal"
# إنشاء تطبيق جديد
# إنشاء تطبيق جديد (يتضمن جميع الأمثلة افتراضيًا)
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
@@ -42,25 +43,38 @@ yarn twenty auth:login
yarn twenty app:dev
```
يدعم المُنشئ ثلاثة أوضاع للتحكم في ملفات الأمثلة التي سيتم تضمينها:
```bash filename="Terminal"
# الافتراضي (شامل): جميع الأمثلة (كائن، حقل، دالة منطقية، مكوّن الواجهة الأمامية، عرض، عنصر قائمة التنقل، مهارة)
npx create-twenty-app@latest my-app
# الأدنى: الملفات الأساسية فقط (application-config.ts و default-role.ts)
npx create-twenty-app@latest my-app --minimal
# التفاعلي: اختر الأمثلة التي تريد تضمينها
npx create-twenty-app@latest my-app --interactive
```
من هنا يمكنك:
```bash filename="Terminal"
# أضف كيانًا جديدًا إلى تطبيقك (موجّه)
# Add a new entity to your application (guided)
yarn twenty entity:add
# ولِّد عميل Twenty مضبوط الأنواع وأنواع كيانات مساحة العمل
yarn twenty app:generate
# راقب سجلات وظائف تطبيقك
# Watch your application's function logs
yarn twenty function:logs
# نفّذ وظيفة بالاسم
# Execute a function by name
yarn twenty function:execute -n my-function -p '{"name": "test"}'
# أزل تثبيت التطبيق من مساحة العمل الحالية
# Execute the post-install function
yarn twenty function:execute --postInstall
# Uninstall the application from the current workspace
yarn twenty app:uninstall
# اعرض مساعدة الأوامر
# Display commands' help
yarn twenty help
```
@@ -73,9 +87,9 @@ yarn twenty help
* ينسخ تطبيقًا أساسيًا مصغّرًا إلى `my-twenty-app/`
* يضيف اعتمادًا محليًا `twenty-sdk` وتهيئة Yarn 4
* ينشئ ملفات ضبط ونصوصًا مرتبطة بـ `twenty` CLI
* يُولّد ضبطًا افتراضيًا للتطبيق ودورًا افتراضيًا للوظيفة
* يُنشئ الملفات الأساسية (تهيئة التطبيق، دور الدالة الافتراضي، دالة ما بعد التثبيت) بالإضافة إلى ملفات الأمثلة بحسب وضع الإنشاء
يبدو التطبيق المُنشأ حديثًا بالقالب كما يلي:
يبدو التطبيق المُنشأ حديثًا باستخدام الوضع الافتراضي `--exhaustive` كما يلي:
```text filename="my-twenty-app/"
my-twenty-app/
@@ -91,15 +105,28 @@ my-twenty-app/
README.md
public/ # مجلد الأصول العامة (صور، خطوط، إلخ)
src/
├── application-config.ts # مطلوب - التكوين الرئيسي للتطبيق
├── application-config.ts # مطلوب - إعدادات التطبيق الرئيسية
├── roles/
│ └── default-role.ts # الدور الافتراضي لوظائف المنطق
│ └── default-role.ts # الدور الافتراضي للدوال المنطقية
├── objects/
│ └── example-object.ts # تعريف كائن مخصص — مثال
├── fields/
│ └── example-field.ts # تعريف حقل مستقل — مثال
├── logic-functions/
── hello-world.ts # مثال لوظيفة منطقية
└── front-components/
└── hello-world.tsx # مثال لمكوّن الواجهة الأمامية
── hello-world.ts # دالة منطقية — مثال
└── post-install.ts # دالة منطقية لما بعد التثبيت
├── front-components/
│ └── hello-world.tsx # مكوّن واجهة أمامية — مثال
├── views/
│ └── example-view.ts # تعريف عرض محفوظ — مثال
├── navigation-menu-items/
│ └── example-navigation-menu-item.ts # رابط تنقّل في الشريط الجانبي — مثال
└── skills/
└── example-skill.ts # تعريف مهارة لوكيل الذكاء الاصطناعي — مثال
```
مع `--minimal`، سيتم إنشاء الملفات الأساسية فقط (`application-config.ts` و`roles/default-role.ts` و`logic-functions/post-install.ts`). مع `--interactive`، تختار ملفات الأمثلة التي تريد تضمينها.
بشكل عام:
* **package.json**: يصرّح باسم التطبيق والإصدار والمحرّكات (Node 24+، Yarn 4)، ويضيف `twenty-sdk` بالإضافة إلى نص برمجي `twenty` يفوِّض إلى `twenty` CLI المحلي. شغِّل `yarn twenty help` لعرض جميع الأوامر المتاحة.
@@ -115,13 +142,16 @@ my-twenty-app/
يكتشف SDK الكيانات عبر تحليل ملفات TypeScript الخاصة بك بحثًا عن استدعاءات **`export default define<Entity>({...})`**. يحتوي كل نوع كيان على دالة مساعدة مقابلة يتم تصديرها من `twenty-sdk`:
| دالة مساعدة | نوع الكيان |
| ------------------------ | --------------------------------- |
| `defineObject()` | تعريفات كائنات مخصصة |
| `defineLogicFunction()` | تعريفات الوظائف المنطقية |
| `defineFrontComponent()` | Front component definitions |
| `defineRole()` | تعريفات الأدوار |
| `defineField()` | امتدادات الحقول للكائنات الموجودة |
| دالة مساعدة | نوع الكيان |
| ---------------------------- | ------------------------------------ |
| `defineObject()` | تعريفات كائنات مخصصة |
| `defineLogicFunction()` | تعريفات الوظائف المنطقية |
| `defineFrontComponent()` | Front component definitions |
| `defineRole()` | تعريفات الأدوار |
| `defineField()` | امتدادات الحقول للكائنات الموجودة |
| `defineView()` | تعريفات العروض المحفوظة |
| `defineNavigationMenuItem()` | تعريفات عناصر قائمة التنقل |
| `defineSkill()` | تعريفات مهارات وكيل الذكاء الاصطناعي |
<Note>
**تسمية الملفات مرنة.** يعتمد اكتشاف الكيانات على بنية الشجرة المجردة (AST) — إذ يقوم SDK بفحص ملفات المصدر لديك بحثًا عن النمط `export default define<Entity>({...})`. يمكنك تنظيم ملفاتك ومجلداتك كيفما تشاء. التجميع حسب نوع الكيان (مثلًا، `logic-functions/` و`roles/`) هو مجرد عرف لتنظيم الشيفرة، وليس مطلبًا إلزاميًا.
@@ -142,8 +172,8 @@ export default defineObject({
ستضيف الأوامر اللاحقة مزيدًا من الملفات والمجلدات:
* `yarn twenty app:generate` سيُنشئ مجلدًا `generated/` (عميل Twenty مضبوط الأنواع + أنواع مساحة العمل).
* `yarn twenty entity:add` سيضيف ملفات تعريف الكيانات تحت `src/` لكائناتك المخصصة أو الوظائف أو المكونات الواجهية أو الأدوار.
* `yarn twenty app:dev` سيولّد تلقائيًا عميل API مضبوط الأنواع في `node_modules/twenty-sdk/generated` (عميل Twenty مضبوط الأنواع + أنواع مساحة العمل).
* `yarn twenty entity:add` سيضيف ملفات تعريف الكيانات ضمن `src/` لكائناتك المخصّصة، والوظائف، ومكوّنات الواجهة الأمامية، والأدوار، والمهارات، وغير ذلك.
## المصادقة
@@ -186,14 +216,17 @@ yarn twenty auth:status
يوفّر SDK دوالًا مساعدة لتعريف كيانات تطبيقك. كما هو موضح في [اكتشاف الكيانات](#entity-detection)، يجب استخدام `export default define<Entity>({...})` كي يتم اكتشاف كياناتك:
| دالة | الغرض |
| ------------------------ | ---------------------------------------------------- |
| `defineApplication()` | تهيئة بيانات التعريف للتطبيق (مطلوب، واحد لكل تطبيق) |
| `defineObject()` | تعريف كائنات مخصصة مع حقول |
| `defineLogicFunction()` | تعريف وظائف منطقية مع معالجات |
| `defineFrontComponent()` | عرِّف مكوّنات أمامية لواجهة مستخدم مخصّصة |
| `defineRole()` | تهيئة صلاحيات الدور والوصول إلى الكائنات |
| `defineField()` | وسّع الكائنات الموجودة بحقول إضافية |
| دالة | الغرض |
| ---------------------------- | ---------------------------------------------------- |
| `defineApplication()` | تهيئة بيانات التعريف للتطبيق (مطلوب، واحد لكل تطبيق) |
| `defineObject()` | تعريف كائنات مخصصة مع حقول |
| `defineLogicFunction()` | تعريف وظائف منطقية مع معالجات |
| `defineFrontComponent()` | عرِّف مكوّنات أمامية لواجهة مستخدم مخصّصة |
| `defineRole()` | تهيئة صلاحيات الدور والوصول إلى الكائنات |
| `defineField()` | وسّع الكائنات الموجودة بحقول إضافية |
| `defineView()` | تعريف العروض المحفوظة للكائنات |
| `defineNavigationMenuItem()` | تعريف روابط التنقل في الشريط الجانبي |
| `defineSkill()` | عرّف مهارات وكيل الذكاء الاصطناعي |
تتحقق هذه الدوال من تكوينك وقت البناء وتوفّر إكمالًا تلقائيًا في بيئة التطوير وأمان الأنواع.
@@ -279,7 +312,11 @@ export default defineObject({
* يمكنك إنشاء كائنات جديدة باستخدام `yarn twenty entity:add`، والذي يرشدك خلال التسمية والحقول والعلاقات.
<Note>
**يتم إنشاء الحقول الأساسية تلقائيًا.** عند تعريف كائن مخصص، يضيف Twenty تلقائيًا حقولًا قياسية مثل `name` و`createdAt` و`updatedAt` و`createdBy` و`position` و`deletedAt`. لا تحتاج إلى تعريف هذه في مصفوفة `fields` — أضف فقط حقولك المخصصة.
**يتم إنشاء الحقول الأساسية تلقائيًا.** عند تعريف كائن مخصص، يضيف Twenty تلقائيًا حقولًا قياسية
مثل `id` و`name` و`createdAt` و`updatedAt` و`createdBy` و`updatedBy` و`deletedAt`.
لا تحتاج إلى تعريف هذه في مصفوفة `fields` — أضف فقط حقولك المخصصة.
يمكنك تجاوز الحقول الافتراضية من خلال تعريف حقل بالاسم نفسه في مصفوفة `fields` الخاصة بك،
لكن هذا غير مستحسن.
</Note>
### تكوين التطبيق (application-config.ts)
@@ -289,6 +326,7 @@ export default defineObject({
* **هوية التطبيق**: المعرفات، اسم العرض، والوصف.
* **كيفية تشغيل وظائفه**: الدور الذي تستخدمه للأذونات.
* **متغيرات (اختياري)**: أزواج مفتاح-قيمة تُعرض لوظائفك كمتغيرات بيئة.
* **(Optional) post-install function**: a logic function that runs after the app is installed.
Use `defineApplication()` to define your application configuration:
@@ -296,6 +334,7 @@ Use `defineApplication()` to define your application configuration:
// src/application-config.ts
import { defineApplication } from 'twenty-sdk';
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
@@ -311,6 +350,7 @@ export default defineApplication({
},
},
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
@@ -319,6 +359,7 @@ export default defineApplication({
* حقول `universalIdentifier` هي معرّفات حتمية تخصك؛ أنشئها مرة واحدة واحتفظ بها ثابتة عبر عمليات المزامنة.
* `applicationVariables` تصبح متغيرات بيئة لوظائفك (على سبيل المثال، `DEFAULT_RECIPIENT_NAME` متاح كـ `process.env.DEFAULT_RECIPIENT_NAME`).
* `defaultRoleUniversalIdentifier` يجب أن يطابق ملف الدور (انظر أدناه).
* `postInstallLogicFunctionUniversalIdentifier` (optional) points to a logic function that runs automatically after the app is installed. See [Post-install functions](#post-install-functions).
#### الأدوار والصلاحيات
@@ -457,6 +498,55 @@ export default defineLogicFunction({
* المصفوفة `triggers` اختيارية. يمكن استخدام الوظائف بدون مشغلات كوظائف مساعدة تُستدعى بواسطة وظائف أخرى.
* يمكنك مزج أنواع متعددة من المشغلات في وظيفة واحدة.
### Post-install functions
A post-install function is a logic function that runs automatically after your app is installed on a workspace. This is useful for one-time setup tasks such as seeding default data, creating initial records, or configuring workspace settings.
عند إنشاء هيكل تطبيق جديد باستخدام `create-twenty-app`، يتم إنشاء دالة ما بعد التثبيت لك في `src/logic-functions/post-install.ts`:
```typescript
// src/logic-functions/post-install.ts
import { defineLogicFunction } from 'twenty-sdk';
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
const handler = async (): Promise<void> => {
console.log('Post install logic function executed successfully!');
};
export default defineLogicFunction({
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
name: 'post-install',
description: 'Runs after installation to set up the application.',
timeoutSeconds: 300,
handler,
});
```
يتم ربط الدالة بتطبيقك من خلال الإشارة إلى المعرِّف العالمي الخاص بها في `application-config.ts`:
```typescript
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
// ...
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
يمكنك أيضًا تنفيذ دالة ما بعد التثبيت يدويًا في أي وقت باستخدام CLI:
```bash filename="Terminal"
yarn twenty function:execute --postInstall
```
النقاط الرئيسية:
* دوال ما بعد التثبيت هي دوال منطقية قياسية — فهي تستخدم `defineLogicFunction()` مثل أي دالة أخرى.
* حقل `postInstallLogicFunctionUniversalIdentifier` في `defineApplication()` اختياري. إذا تم تجاهله، لن يتم تشغيل أي دالة بعد التثبيت.
* تم تعيين مهلة افتراضية إلى 300 ثانية (5 دقائق) للسماح بمهام الإعداد الأطول مثل تهيئة البيانات.
* لا تحتاج دوال ما بعد التثبيت إلى مُشغِّلات — حيث يستدعيها النظام الأساسي أثناء التثبيت أو يدويًا عبر `function:execute --postInstall`.
### حمولة مشغل المسار
<Warning>
@@ -554,6 +644,71 @@ const handler = async (event: RoutePayload) => {
* **مُنشأ بالقالب**: شغّل `yarn twenty entity:add` واختر خيار إضافة وظيفة منطقية جديدة. يُولّد هذا ملفًا مبدئيًا مع معالج وتكوين.
* **يدوي**: أنشئ ملفًا جديدًا `*.logic-function.ts` واستخدم `defineLogicFunction()` مع اتباع النمط نفسه.
### تمييز دالة منطقية كأداة
يمكن إتاحة الدوال المنطقية بوصفها **أدوات** لوكلاء الذكاء الاصطناعي وسير العمل. عندما يتم تمييز دالة كأداة، تصبح قابلة للاكتشاف بواسطة ميزات الذكاء الاصطناعي الخاصة بـ Twenty ويمكن اختيارها كخطوة في أتمتة سير العمل.
لتمييز دالة منطقية كأداة، عيّن `isTool: true` وقدّم `toolInputSchema` يصف معاملات الإدخال المتوقعة باستخدام [مخطط JSON](https://json-schema.org/):
```typescript
// src/logic-functions/enrich-company.logic-function.ts
import { defineLogicFunction } from 'twenty-sdk';
import Twenty from '~/generated';
const handler = async (params: { companyName: string; domain?: string }) => {
const client = new Twenty();
const result = await client.mutation({
createTask: {
__args: {
data: {
title: `Enrich data for ${params.companyName}`,
body: `Domain: ${params.domain ?? 'unknown'}`,
},
},
id: true,
},
});
return { taskId: result.createTask.id };
};
export default defineLogicFunction({
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
name: 'enrich-company',
description: 'Enrich a company record with external data',
timeoutSeconds: 10,
handler,
isTool: true,
toolInputSchema: {
type: 'object',
properties: {
companyName: {
type: 'string',
description: 'The name of the company to enrich',
},
domain: {
type: 'string',
description: 'The company website domain (optional)',
},
},
required: ['companyName'],
},
});
```
النقاط الرئيسية:
* **`isTool`** (`boolean`, الافتراضي: `false`): عند ضبطه على `true`، يتم تسجيل الدالة كأداة وتصبح متاحة لوكلاء الذكاء الاصطناعي ولأتمتة سير العمل.
* **`toolInputSchema`** (`object`, اختياري): كائن JSON Schema يصف المعلمات التي تقبلها دالتك. يستخدم وكلاء الذكاء الاصطناعي هذا المخطط لفهم المدخلات التي تتوقعها الأداة وللتحقق من صحة الاستدعاءات. إذا تم إغفاله، فالقيمة الافتراضية للمخطط هي `{ type: 'object', properties: {} }` (من دون معلمات).
* الدوال التي لديها `isTool: false` (أو غير معيَّنة) **غير** معروضة كأدوات. لا يزال بالإمكان تنفيذها مباشرةً أو استدعاؤها بواسطة دوال أخرى، لكنها لن تظهر في اكتشاف الأدوات.
* **تسمية الأداة**: عند كشفها كأداة، يتم تطبيع اسم الدالة تلقائيًا إلى `logic_function_<name>` (تحويله إلى أحرف صغيرة، واستبدال المحارف غير الأبجدية الرقمية بشرطات سفلية). على سبيل المثال، `enrich-company` تصبح `logic_function_enrich_company`.
* يمكنك دمج `isTool` مع المشغِّلات — إذ يمكن للدالة أن تكون أداة (قابلة للاستدعاء من قِبل وكلاء الذكاء الاصطناعي) وأن تُشغَّل بواسطة أحداث (cron، وأحداث قاعدة البيانات، والمسارات) في الوقت نفسه.
<Note>
**اكتب `description` جيدًا.** يعتمد وكلاء الذكاء الاصطناعي على حقل `description` الخاص بالدالة لتحديد وقت استخدام الأداة. كن محددًا بشأن ما تفعله الأداة ومتى ينبغي استدعاؤها.
</Note>
### المكوّنات الأمامية
تتيح لك المكوّنات الأمامية إنشاء مكوّنات React مخصّصة تُعرَض داخل واجهة مستخدم Twenty. استخدم `defineFrontComponent()` لتعريف مكوّنات مع تحقّق مدمج:
@@ -591,9 +746,44 @@ export default defineFrontComponent({
* **مُنشأ بالقالب**: شغّل `yarn twenty entity:add` واختر خيار إضافة مكوّن أمامي جديد.
* **يدوي**: أنشئ ملفًا جديدًا `*.front-component.tsx` واستخدم `defineFrontComponent()`.
### المهارات
تُحدِّد المهارات تعليمات وإمكانات قابلة لإعادة الاستخدام يمكن لوكلاء الذكاء الاصطناعي استخدامها داخل مساحة العمل لديك. استخدم `defineSkill()` لتعريف مهارات مع تحقّق مدمج:
```typescript
// src/skills/example-skill.ts
import { defineSkill } from 'twenty-sdk';
export default defineSkill({
universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
name: 'sales-outreach',
label: 'التواصل البيعي',
description: 'يرشد وكيل الذكاء الاصطناعي خلال عملية منظّمة للتواصل البيعي',
icon: 'IconBrain',
content: `أنت مساعد للتواصل البيعي. عند التواصل مع عميل محتمل:
1. ابحث عن الشركة وآخر الأخبار
2. حدِّد دور العميل المحتمل ونقاط الألم المرجّحة
3. صِغ رسالة مخصّصة تشير إلى تفاصيل محدّدة
4. حافظ على نبرة احترافية ولكن حوارية`,
});
```
النقاط الرئيسية:
* `name` هي سلسلة معرّف فريدة للمهارة (يُنصَح باستخدام kebab-case).
* `label` هو اسم العرض المقروء للبشر الظاهر في واجهة المستخدم.
* `content` يحتوي على تعليمات المهارة — وهو النص الذي يستخدمه وكيل الذكاء الاصطناعي.
* `icon` (اختياري) يحدّد الأيقونة المعروضة في واجهة المستخدم.
* `description` (اختياري) يوفّر سياقًا إضافيًا حول غرض المهارة.
يمكنك إنشاء مهارات جديدة بطريقتين:
* **مُنشأ بالقالب**: شغِّل `yarn twenty entity:add` واختر خيار إضافة مهارة جديدة.
* **يدوي**: أنشئ ملفًا جديدًا واستخدم `defineSkill()` مع اتباع النمط نفسه.
### عميل مُولَّد مضبوط الأنواع
شغّل `yarn twenty app:generate` لإنشاء عميل محلي مضبوط الأنواع في `generated/` استنادًا إلى مخطط مساحة العمل لديك. استخدمه في وظائفك:
يُولَّد العميل مضبوط الأنواع تلقائيًا بواسطة `yarn twenty app:dev` ويُخزَّن في `node_modules/twenty-sdk/generated` استنادًا إلى مخطط مساحة العمل لديك. استخدمه في وظائفك:
```typescript
import Twenty from '~/generated';
@@ -602,7 +792,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
يُعاد توليد العميل بواسطة `yarn twenty app:generate`. أعِد التشغيل بعد تغيير كائناتك أو عند الانضمام إلى مساحة عمل جديدة.
يُعاد توليد العميل تلقائيًا بواسطة `yarn twenty app:dev` كلما تغيّرت كائناتك أو حقولك.
#### بيانات الاعتماد وقت التشغيل في الوظائف المنطقية
@@ -617,6 +807,53 @@ const { me } = await client.query({ me: { id: true, displayName: true } });
* تُحدَّد أذونات مفتاح واجهة برمجة التطبيقات بواسطة الدور المشار إليه في `application-config.ts` عبر `defaultRoleUniversalIdentifier`. هذا هو الدور الافتراضي الذي تستخدمه الوظائف المنطقية في تطبيقك.
* يمكن للتطبيقات تعريف أدوار لاتباع مبدأ أقل الامتياز. امنح فقط الأذونات التي تحتاجها وظائفك، ثم وجّه `defaultRoleUniversalIdentifier` إلى المعرّف الشامل لذلك الدور.
#### رفع الملفات
يتضمن العميل `Twenty` المُولَّد طريقة `uploadFile` لإرفاق الملفات بالحقول من نوع ملف ضمن كائنات مساحة العمل الخاصة بك. نظرًا لأن عملاء GraphQL القياسيون لا يدعمون تحميل الملفات متعددة الأجزاء افتراضيًا، يوفر العميل هذه الطريقة المخصصة التي تطبق [مواصفة طلب GraphQL متعدد الأجزاء](https://github.com/jaydenseric/graphql-multipart-request-spec) في الخلفية.
```typescript
import Twenty from '~/generated';
import * as fs from 'fs';
const client = new Twenty();
const fileBuffer = fs.readFileSync('./invoice.pdf');
const uploadedFile = await client.uploadFile(
fileBuffer, // file contents as a Buffer
'invoice.pdf', // filename
'application/pdf', // MIME type (defaults to 'application/octet-stream')
'58a0a314-d7ea-4865-9850-7fb84e72f30b', // field universal identifier
);
console.log(uploadedFile);
// { id: '...', path: '...', size: 12345, createdAt: '...', url: 'https://...' }
```
توقيع الطريقة:
```typescript
uploadFile(
fileBuffer: Buffer,
filename: string,
contentType: string,
fieldMetadataUniversalIdentifier: string,
): Promise<{ id: string; path: string; size: number; createdAt: string; url: string }>
```
| المعلمة | النوع | الوصف |
| ---------------------------------- | -------- | ---------------------------------------------------------------------------------- |
| `fileBuffer` | `Buffer` | المحتوى الخام للملف |
| `filename` | `string` | اسم الملف (يُستخدم للتخزين والعرض) |
| `contentType` | `string` | نوع MIME للملف (القيمة الافتراضية هي `application/octet-stream` إذا لم يتم تحديده) |
| `fieldMetadataUniversalIdentifier` | `string` | قيمة `universalIdentifier` لحقل نوع الملف في كائنك |
النقاط الرئيسية:
* ترسل هذه الطريقة الملف إلى **نقطة نهاية البيانات الوصفية** (وليست نقطة النهاية الرئيسية لـ GraphQL)، حيث تُنفَّذ عملية الرفع.
* تستخدم `universalIdentifier` الخاص بالحقل (وليس المعرّف الخاص بمساحة العمل)، ليعمل كود الرفع لديك عبر أي مساحة عمل مُثبَّت فيها تطبيقك — بما يتماشى مع كيفية إشارة التطبيقات إلى الحقول في كل مكان آخر.
* العنوان `url` المُعاد هو عنوان URL موقّع يمكنك استخدامه للوصول إلى الملف المرفوع.
### مثال Hello World
استكشف مثالًا بسيطًا شاملًا من البداية إلى النهاية يوضح الكائنات والوظائف المنطقية والمكوّنات الأمامية ومشغّلات متعددة [هنا](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world):
@@ -639,13 +876,13 @@ yarn add -D twenty-sdk
}
```
الآن يمكنك تشغيل جميع الأوامر عبر `yarn twenty <command>`، مثلًا: `yarn twenty app:dev`، `yarn twenty app:generate`، `yarn twenty help`، إلخ.
الآن يمكنك تشغيل جميع الأوامر عبر `yarn twenty <command>`، مثلًا: `yarn twenty app:dev`، `yarn twenty help`، إلخ.
## استكشاف الأخطاء وإصلاحها
* أخطاء المصادقة: شغّل `yarn twenty auth:login` وتأكد من أن مفتاح واجهة برمجة التطبيقات لديك يمتلك الأذونات المطلوبة.
* يتعذّر الاتصال بالخادم: تحقق من عنوان URL لواجهة البرمجة وأن خادم Twenty قابل للوصول.
* الأنواع أو العميل مفقود/قديم: شغّل `yarn twenty app:generate`.
* الأنواع أو العميل مفقود/قديم: أعد تشغيل `yarn twenty app:dev` — فهو ينشئ العميل مضبوط الأنواع بشكل تلقائي.
* وضع التطوير لا يزامن: تأكد من أن `yarn twenty app:dev` قيد التشغيل وأن التغييرات ليست متجاهلة من بيئتك.
قناة المساعدة على Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -15,6 +15,7 @@ Aplikace vám umožňují vytvářet a spravovat přizpůsobení Twenty **jako k
* Definujte vlastní objekty a pole jako kód (spravovaný datový model)
* Vytvářejte logické funkce s vlastními spouštěči
* Definujte dovednosti agentů AI
* Nasazujte stejnou aplikaci do více pracovních prostorů
## Předpoklady
@@ -27,7 +28,7 @@ Aplikace vám umožňují vytvářet a spravovat přizpůsobení Twenty **jako k
Vytvořte novou aplikaci pomocí oficiálního scaffolderu, poté se ověřte a začněte vyvíjet:
```bash filename="Terminal"
# Vygenerujte kostru nové aplikace
# Vygenerujte kostru nové aplikace (ve výchozím nastavení zahrnuje všechny příklady)
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
@@ -42,21 +43,34 @@ yarn twenty auth:login
yarn twenty app:dev
```
Nástroj pro generování kostry podporuje tři režimy pro řízení toho, které ukázkové soubory jsou zahrnuty:
```bash filename="Terminal"
# Výchozí (úplný): všechny příklady (objekt, pole, logická funkce, front-endová komponenta, zobrazení, položka navigační nabídky, dovednost)
npx create-twenty-app@latest my-app
# Minimální: pouze základní soubory (application-config.ts a default-role.ts)
npx create-twenty-app@latest my-app --minimal
# Interaktivní: vyberte, které příklady zahrnout
npx create-twenty-app@latest my-app --interactive
```
Odtud můžete:
```bash filename="Terminal"
# Přidejte do vaší aplikace novou entitu (s průvodcem)
yarn twenty entity:add
# Vygenerujte typovaného klienta Twenty a typy entit pracovního prostoru
yarn twenty app:generate
# Sledujte logy funkcí vaší aplikace
yarn twenty function:logs
# Spusťte funkci podle názvu
yarn twenty function:execute -n my-function -p '{"name": "test"}'
# Spusťte postinstalační funkci
yarn twenty function:execute --postInstall
# Odinstalujte aplikaci z aktuálního pracovního prostoru
yarn twenty app:uninstall
@@ -73,9 +87,9 @@ Když spustíte `npx create-twenty-app@latest my-twenty-app`, scaffolder:
* Zkopíruje minimální základní aplikaci do `my-twenty-app/`
* Přidá lokální závislost `twenty-sdk` a konfiguraci pro Yarn 4
* Vytvoří konfigurační soubory a skripty napojené na `twenty` CLI
* Vygeneruje výchozí konfiguraci aplikace a výchozí roli funkcí
* Vygeneruje základní soubory (konfigurace aplikace, výchozí role funkcí, postinstalační funkce) a k nim ukázkové soubory podle zvoleného režimu generování kostry
Čerstvě vytvořená aplikace vypadá takto:
Čerstvě vygenerovaná aplikace s výchozím režimem `--exhaustive` vypadá takto:
```text filename="my-twenty-app/"
my-twenty-app/
@@ -94,12 +108,25 @@ my-twenty-app/
├── application-config.ts # Povinné hlavní konfigurace aplikace
├── roles/
│ └── default-role.ts # Výchozí role pro logické funkce
├── objects/
│ └── example-object.ts # Ukázková definice vlastního objektu
├── fields/
│ └── example-field.ts # Ukázková samostatná definice pole
├── logic-functions/
── hello-world.ts # Ukázková logická funkce
└── front-components/
└── hello-world.tsx # Ukázková front-endová komponenta
── hello-world.ts # Ukázková logická funkce
└── post-install.ts # Postinstalační logická funkce
├── front-components/
│ └── hello-world.tsx # Ukázková front-endová komponenta
├── views/
│ └── example-view.ts # Ukázková definice uloženého zobrazení
├── navigation-menu-items/
│ └── example-navigation-menu-item.ts # Ukázkový odkaz postranní navigace
└── skills/
└── example-skill.ts # Ukázková definice dovednosti agenta AI
```
S volbou `--minimal` se vytvoří pouze základní soubory (`application-config.ts`, `roles/default-role.ts` a `logic-functions/post-install.ts`). S volbou `--interactive` si vyberete, které ukázkové soubory chcete zahrnout.
V kostce:
* **package.json**: Deklaruje název aplikace, verzi, engines (Node 24+, Yarn 4) a přidává `twenty-sdk` plus skript `twenty`, který deleguje na lokální `twenty` CLI. Spusťte `yarn twenty help` pro výpis všech dostupných příkazů.
@@ -115,13 +142,16 @@ V kostce:
SDK detekuje entity analýzou vašich souborů TypeScript a hledá volání **`export default define<Entity>({...})`**. Každý typ entity má odpovídající pomocnou funkci exportovanou z `twenty-sdk`:
| Pomocná funkce | Typ entity |
| ------------------------ | ------------------------------------- |
| `defineObject()` | Definice vlastních objektů |
| `defineLogicFunction()` | Definice logických funkcí |
| `defineFrontComponent()` | Definice frontendových komponent |
| `defineRole()` | Definice rolí |
| `defineField()` | Rozšíření polí u existujících objektů |
| Pomocná funkce | Typ entity |
| ---------------------------- | ------------------------------------- |
| `defineObject()` | Definice vlastních objektů |
| `defineLogicFunction()` | Definice logických funkcí |
| `defineFrontComponent()` | Definice frontendových komponent |
| `defineRole()` | Definice rolí |
| `defineField()` | Rozšíření polí u existujících objektů |
| `defineView()` | Definice uložených zobrazení |
| `defineNavigationMenuItem()` | Definice položek navigační nabídky |
| `defineSkill()` | Definice dovedností agenta AI |
<Note>
**Pojmenování souborů je flexibilní.** Detekce entit je založená na AST — SDK prochází vaše zdrojové soubory a hledá vzor `export default define<Entity>({...})`. Soubory a složky můžete organizovat, jak chcete. Seskupování podle typu entity (např. `logic-functions/`, `roles/`) je pouze konvence pro organizaci kódu, nikoli požadavek.
@@ -142,8 +172,8 @@ export default defineObject({
Pozdější příkazy přidají další soubory a složky:
* `yarn twenty app:generate` vytvoří složku `generated/` (typovaný klient Twenty + typy pracovního prostoru).
* `yarn twenty entity:add` přidá soubory s definicemi entit do `src/` pro vaše vlastní objekty, funkce, frontové komponenty nebo role.
* `yarn twenty app:dev` automaticky vygeneruje typovaného klienta API v `node_modules/twenty-sdk/generated` (typovaný klient Twenty + typy pracovního prostoru).
* `yarn twenty entity:add` přidá soubory s definicemi entit do `src/` pro vaše vlastní objekty, funkce, frontové komponenty, role, dovednosti a další.
## Ověření
@@ -186,14 +216,17 @@ twenty-sdk poskytuje typované stavební bloky a pomocné funkce, které použí
SDK poskytuje pomocné funkce pro definování entit vaší aplikace. Jak je popsáno v [Detekce entit](#entity-detection), musíte použít `export default define<Entity>({...})`, aby byly vaše entity detekovány:
| Funkce | Účel |
| ------------------------ | ----------------------------------------------------------------- |
| `defineApplication()` | Nakonfigurujte metadata aplikace (povinné, jedno na aplikaci) |
| `defineObject()` | Definice vlastních objektů s poli |
| `defineLogicFunction()` | Definice logických funkcí s obslužnými funkcemi |
| `defineFrontComponent()` | Definujte frontendové komponenty pro vlastní uživatelské rozhraní |
| `defineRole()` | Konfigurace oprávnění rolí a přístupu k objektům |
| `defineField()` | Rozšiřte existující objekty o další pole |
| Funkce | Účel |
| ---------------------------- | ----------------------------------------------------------------- |
| `defineApplication()` | Nakonfigurujte metadata aplikace (povinné, jedno na aplikaci) |
| `defineObject()` | Definice vlastních objektů s poli |
| `defineLogicFunction()` | Definice logických funkcí s obslužnými funkcemi |
| `defineFrontComponent()` | Definujte frontendové komponenty pro vlastní uživatelské rozhraní |
| `defineRole()` | Konfigurace oprávnění rolí a přístupu k objektům |
| `defineField()` | Rozšiřte existující objekty o další pole |
| `defineView()` | Definujte uložená zobrazení pro objekty |
| `defineNavigationMenuItem()` | Definujte odkazy postranní navigace |
| `defineSkill()` | Definuje dovednosti agenta AI |
Tyto funkce validují vaši konfiguraci v době sestavení a poskytují automatické doplňování v IDE a typovou bezpečnost.
@@ -279,7 +312,11 @@ Hlavní body:
* Nové objekty můžete vygenerovat pomocí `yarn twenty entity:add`, který vás provede pojmenováním, poli a vztahy.
<Note>
**Základní pole jsou vytvořena automaticky.** Když definujete vlastní objekt, Twenty automaticky přidá standardní pole jako `name`, `createdAt`, `updatedAt`, `createdBy`, `position` a `deletedAt`. Nemusíte je definovat v poli `fields` — přidejte pouze svá vlastní pole.
**Základní pole jsou vytvořena automaticky.** Když definujete vlastní objekt, Twenty automaticky přidá standardní pole
jako `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` a `deletedAt`.
Nemusíte je definovat v poli `fields` — přidejte pouze svá vlastní pole.
Výchozí pole můžete přepsat definováním pole se stejným názvem v poli `fields`,
ale to se nedoporučuje.
</Note>
### Konfigurace aplikace (application-config.ts)
@@ -289,6 +326,7 @@ Každá aplikace má jeden soubor `application-config.ts`, který popisuje:
* **Identitu aplikace**: identifikátory, zobrazovaný název a popis.
* **Jak běží její funkce**: kterou roli používají pro oprávnění.
* **(Volitelné) proměnné**: dvojice klíč–hodnota zpřístupněné vašim funkcím jako proměnné prostředí.
* **(Volitelná) postinstalační funkce**: logická funkce, která se spouští po instalaci aplikace.
Use `defineApplication()` to define your application configuration:
@@ -296,6 +334,7 @@ Use `defineApplication()` to define your application configuration:
// src/application-config.ts
import { defineApplication } from 'twenty-sdk';
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
@@ -311,6 +350,7 @@ export default defineApplication({
},
},
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
@@ -319,6 +359,7 @@ Poznámky:
* Pole `universalIdentifier` jsou deterministická ID, která vlastníte; vygenerujte je jednou a udržujte je stabilní napříč synchronizacemi.
* `applicationVariables` se stanou proměnnými prostředí pro vaše funkce (například `DEFAULT_RECIPIENT_NAME` je dostupné jako `process.env.DEFAULT_RECIPIENT_NAME`).
* `defaultRoleUniversalIdentifier` se musí shodovat se souborem role (viz níže).
* `postInstallLogicFunctionUniversalIdentifier` (volitelné) odkazuje na logickou funkci, která se automaticky spustí po instalaci aplikace. Viz [Postinstalační funkce](#post-install-functions).
#### Role a oprávnění
@@ -457,6 +498,55 @@ Poznámky:
* Pole `triggers` je volitelné. Funkce bez spouštěčů lze použít jako pomocné funkce volané jinými funkcemi.
* V jedné funkci můžete kombinovat více typů spouštěčů.
### Postinstalační funkce
Postinstalační funkce je logická funkce, která se automaticky spouští po instalaci vaší aplikace do pracovního prostoru. To je užitečné pro jednorázové úlohy nastavení, jako je naplnění výchozími daty, vytvoření počátečních záznamů nebo konfigurace nastavení pracovního prostoru.
Když vygenerujete kostru nové aplikace pomocí `create-twenty-app`, vytvoří se pro vás postinstalační funkce v `src/logic-functions/post-install.ts`:
```typescript
// src/logic-functions/post-install.ts
import { defineLogicFunction } from 'twenty-sdk';
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
const handler = async (): Promise<void> => {
console.log('Post install logic function executed successfully!');
};
export default defineLogicFunction({
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
name: 'post-install',
description: 'Runs after installation to set up the application.',
timeoutSeconds: 300,
handler,
});
```
Funkce je připojena do vaší aplikace odkazem na její univerzální identifikátor v `application-config.ts`:
```typescript
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
// ...
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
Postinstalační funkci můžete také kdykoli spustit ručně pomocí CLI:
```bash filename="Terminal"
yarn twenty function:execute --postInstall
```
Hlavní body:
* Postinstalační funkce jsou standardní logické funkce — používají `defineLogicFunction()` stejně jako jakákoli jiná funkce.
* Pole `postInstallLogicFunctionUniversalIdentifier` v `defineApplication()` je volitelné. Pokud je vynecháno, po instalaci se nespustí žádná funkce.
* Výchozí časový limit je nastaven na 300 sekund (5 minut), aby umožnil delší úlohy nastavení, jako je naplnění daty.
* Postinstalační funkce nepotřebují spouštěče — jsou spouštěny platformou během instalace nebo ručně pomocí `function:execute --postInstall`.
### Payload spouštěče trasy
<Warning>
@@ -554,6 +644,71 @@ Nové funkce můžete vytvářet dvěma způsoby:
* **Vygenerované**: Spusťte `yarn twenty entity:add` a zvolte možnost přidat novou logickou funkci. Tím se vygeneruje startovací soubor s obslužnou funkcí a konfigurací.
* **Ruční**: Vytvořte nový soubor `*.logic-function.ts` a použijte `defineLogicFunction()` podle stejného vzoru.
### Označení logické funkce jako nástroje
Logické funkce lze zpřístupnit jako **nástroje** pro agenty AI a pracovní postupy. Když je funkce označena jako nástroj, stane se dohledatelnou funkcemi AI produktu Twenty a lze ji vybrat jako krok v automatizacích pracovních postupů.
Chcete-li označit logickou funkci jako nástroj, nastavte `isTool: true` a poskytněte `toolInputSchema` popisující očekávané vstupní parametry pomocí [JSON Schema](https://json-schema.org/):
```typescript
// src/logic-functions/enrich-company.logic-function.ts
import { defineLogicFunction } from 'twenty-sdk';
import Twenty from '~/generated';
const handler = async (params: { companyName: string; domain?: string }) => {
const client = new Twenty();
const result = await client.mutation({
createTask: {
__args: {
data: {
title: `Enrich data for ${params.companyName}`,
body: `Domain: ${params.domain ?? 'unknown'}`,
},
},
id: true,
},
});
return { taskId: result.createTask.id };
};
export default defineLogicFunction({
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
name: 'enrich-company',
description: 'Enrich a company record with external data',
timeoutSeconds: 10,
handler,
isTool: true,
toolInputSchema: {
type: 'object',
properties: {
companyName: {
type: 'string',
description: 'The name of the company to enrich',
},
domain: {
type: 'string',
description: 'The company website domain (optional)',
},
},
required: ['companyName'],
},
});
```
Hlavní body:
* **`isTool`** (`boolean`, výchozí: `false`): Když je nastaveno na `true`, funkce je zaregistrována jako nástroj a zpřístupní se agentům AI a automatizacím pracovních postupů.
* **`toolInputSchema`** (`object`, volitelné): Objekt JSON Schema, který popisuje parametry, jež vaše funkce přijímá. Agenti AI používají toto schéma k pochopení toho, jaké vstupy nástroj očekává, a k ověřování volání. Pokud je vynecháno, schéma má výchozí podobu `{ type: 'object', properties: {} }` (žádné parametry).
* Funkce s `isTool: false` (nebo není nastaveno) **nejsou** zpřístupněny jako nástroje. Stále je lze spouštět přímo nebo volat z jiných funkcí, ale neobjeví se ve vyhledávání nástrojů.
* **Pojmenování nástrojů**: Když je funkce zpřístupněna jako nástroj, její název se automaticky normalizuje na `logic_function_<name>` (převedeno na malá písmena, nealfanumerické znaky jsou nahrazeny podtržítky). Například `enrich-company` se změní na `logic_function_enrich_company`.
* Můžete kombinovat `isTool` se spouštěči — funkce může být zároveň nástrojem (volatelným agenty AI) i spouštěna událostmi (cron, databázové události, routes).
<Note>
**Napište kvalitní `description`.** Agenti AI se spoléhají na pole funkce `description` při rozhodování, kdy nástroj použít. Buďte konkrétní ohledně toho, co nástroj dělá a kdy se má volat.
</Note>
### Frontendové komponenty
Frontendové komponenty vám umožňují vytvářet vlastní React komponenty, které se vykreslují v rozhraní Twenty. K definování komponent s vestavěnou validací použijte `defineFrontComponent()`:
@@ -591,9 +746,44 @@ Nové frontendové komponenty můžete vytvořit dvěma způsoby:
* **Vygenerované**: Spusťte `yarn twenty entity:add` a zvolte možnost přidat novou frontendovou komponentu.
* **Ruční**: Vytvořte nový soubor `*.front-component.tsx` a použijte `defineFrontComponent()`.
### Dovednosti
Dovednosti definují znovupoužitelné pokyny a schopnosti, které mohou agenti AI používat ve vašem pracovním prostoru. K definování dovedností s vestavěnou validací použijte `defineSkill()`:
```typescript
// src/skills/example-skill.ts
import { defineSkill } from 'twenty-sdk';
export default defineSkill({
universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
name: 'sales-outreach',
label: 'Sales Outreach',
description: 'Guides the AI agent through a structured sales outreach process',
icon: 'IconBrain',
content: `You are a sales outreach assistant. When reaching out to a prospect:
1. Research the company and recent news
2. Identify the prospect's role and likely pain points
3. Draft a personalized message referencing specific details
4. Keep the tone professional but conversational`,
});
```
Hlavní body:
* `name` je jedinečný identifikátor dovednosti (doporučuje se kebab-case).
* `label` je uživatelsky čitelný název zobrazovaný v UI.
* `content` obsahuje pokyny dovednosti — je to text, který agent AI používá.
* `icon` (volitelné) nastavuje ikonu zobrazovanou v UI.
* `description` (volitelné) poskytuje doplňující kontext o účelu dovednosti.
Nové dovednosti můžete vytvářet dvěma způsoby:
* **Vygenerované**: Spusťte `yarn twenty entity:add` a zvolte možnost přidat novou dovednost.
* **Ruční**: Vytvořte nový soubor a použijte `defineSkill()` podle stejného vzoru.
### Generovaný typovaný klient
Spusťte `yarn twenty app:generate` a vytvořte lokálního typovaného klienta v `generated/` na základě schématu vašeho pracovního prostoru. Použijte jej ve svých funkcích:
Typovaný klient je automaticky generován pomocí `yarn twenty app:dev` a ukládá se do `node_modules/twenty-sdk/generated` podle schématu vašeho pracovního prostoru. Použijte jej ve svých funkcích:
```typescript
import Twenty from '~/generated';
@@ -602,7 +792,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
Klient je znovu generován příkazem `yarn twenty app:generate`. Spusťte znovu po změně vašich objektů nebo při připojování k novému pracovnímu prostoru.
Klient se automaticky znovu generuje pomocí `yarn twenty app:dev` kdykoli se změní vaše objekty nebo pole.
#### Běhové přihlašovací údaje v logických funkcích
@@ -617,6 +807,53 @@ Poznámky:
* Oprávnění klíče API jsou určena rolí odkazovanou ve vašem `application-config.ts` prostřednictvím `defaultRoleUniversalIdentifier`. Toto je výchozí role používaná logickými funkcemi vaší aplikace.
* Aplikace mohou definovat role podle principu nejmenších oprávnění. Udělte pouze oprávnění, která vaše funkce potřebují, a poté nastavte `defaultRoleUniversalIdentifier` na univerzální identifikátor této role.
#### Nahrávání souborů
Vygenerovaný klient `Twenty` obsahuje metodu `uploadFile` pro připojování souborů k polím typu souboru u objektů ve vašem pracovním prostoru. Protože standardní klienti GraphQL nativně nepodporují nahrávání souborů pomocí multipart, klient poskytuje tuto speciální metodu, která interně implementuje [specifikaci multipart požadavků GraphQL](https://github.com/jaydenseric/graphql-multipart-request-spec).
```typescript
import Twenty from '~/generated';
import * as fs from 'fs';
const client = new Twenty();
const fileBuffer = fs.readFileSync('./invoice.pdf');
const uploadedFile = await client.uploadFile(
fileBuffer, // file contents as a Buffer
'invoice.pdf', // filename
'application/pdf', // MIME type (defaults to 'application/octet-stream')
'58a0a314-d7ea-4865-9850-7fb84e72f30b', // field universal identifier
);
console.log(uploadedFile);
// { id: '...', path: '...', size: 12345, createdAt: '...', url: 'https://...' }
```
Signatura metody:
```typescript
uploadFile(
fileBuffer: Buffer,
filename: string,
contentType: string,
fieldMetadataUniversalIdentifier: string,
): Promise<{ id: string; path: string; size: number; createdAt: string; url: string }>
```
| Parametr | Typ | Popis |
| ---------------------------------- | -------- | --------------------------------------------------------------------------- |
| `fileBuffer` | `Buffer` | Surový obsah souboru |
| `filename` | `string` | Název souboru (používá se pro ukládání a zobrazení) |
| `contentType` | `string` | Typ MIME souboru (pokud je vynechán, výchozí je `application/octet-stream`) |
| `fieldMetadataUniversalIdentifier` | `string` | `universalIdentifier` pole typu souboru ve vašem objektu |
Hlavní body:
* Metoda odešle soubor na **koncový bod metadat** (nikoli na hlavní koncový bod GraphQL), kde se provede mutace nahrání.
* Používá `universalIdentifier` pole (nikoli jeho ID specifické pro pracovní prostor), takže váš kód pro nahrávání funguje ve všech pracovních prostorech, kde je vaše aplikace nainstalována — v souladu s tím, jak aplikace odkazují na pole všude jinde.
* Vrácená hodnota `url` je podepsaná adresa URL, kterou můžete použít k přístupu k nahranému souboru.
### Příklad Hello World
Prozkoumejte minimalistický end-to-end příklad, který demonstruje objekty, logické funkce, frontendové komponenty a více spouštěčů [zde](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world):
@@ -639,13 +876,13 @@ Poté přidejte skript `twenty`:
}
```
Nyní můžete spouštět všechny příkazy přes `yarn twenty <command>`, např. `yarn twenty app:dev`, `yarn twenty app:generate`, `yarn twenty help` atd.
Nyní můžete spouštět všechny příkazy přes `yarn twenty <command>`, např. `yarn twenty app:dev`, `yarn twenty help` atd.
## Řešení potíží
* Chyby ověření: spusťte `yarn twenty auth:login` a ujistěte se, že váš klíč API má požadovaná oprávnění.
* Nelze se připojit k serveru: ověřte URL API a že je server Twenty dosažitelný.
* Typy nebo klient chybí nebo jsou zastaralé: spusťte `yarn twenty app:generate`.
* Types or client missing/outdated: restart `yarn twenty app:dev` — it auto-generates the typed client.
* Režim vývoje se nesynchronizuje: ujistěte se, že běží `yarn twenty app:dev` a že vaše prostředí změny neignoruje.
Kanál podpory na Discordu: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -15,6 +15,7 @@ Mit Apps können Sie Twenty-Anpassungen **als Code** erstellen und verwalten. An
* Benutzerdefinierte Objekte und Felder als Code definieren (verwaltetes Datenmodell)
* Logikfunktionen mit benutzerdefinierten Triggern erstellen
* Fähigkeiten für KI-Agenten definieren
* Dieselbe App in mehreren Workspaces bereitstellen
## Voraussetzungen
@@ -27,7 +28,7 @@ Mit Apps können Sie Twenty-Anpassungen **als Code** erstellen und verwalten. An
Erstellen Sie mit dem offiziellen Scaffolder eine neue App, authentifizieren Sie sich und beginnen Sie mit der Entwicklung:
```bash filename="Terminal"
# Eine neue App erstellen
# Eine neue App erstellen (enthält standardmäßig alle Beispiele)
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
@@ -42,21 +43,34 @@ yarn twenty auth:login
yarn twenty app:dev
```
Das Scaffolding-Tool unterstützt drei Modi, um zu steuern, welche Beispieldateien enthalten sind:
```bash filename="Terminal"
# Standard (umfassend): alle Beispiele (Objekt, Feld, Logikfunktion, Frontend-Komponente, View, Navigationsmenüeintrag, Skill)
npx create-twenty-app@latest my-app
# Minimal: nur Kerndateien (application-config.ts und default-role.ts)
npx create-twenty-app@latest my-app --minimal
# Interaktiv: wähle aus, welche Beispiele enthalten sein sollen
npx create-twenty-app@latest my-app --interactive
```
Von hier aus können Sie:
```bash filename="Terminal"
# Eine neue Entität zu deiner Anwendung hinzufügen (geführt)
# Eine neue Entität zu Ihrer Anwendung hinzufügen (geführt)
yarn twenty entity:add
# Einen typisierten Twenty-Client und Entitätstypen für den Arbeitsbereich generieren
yarn twenty app:generate
# Die Funktionsprotokolle deiner Anwendung überwachen
# Die Funktionsprotokolle Ihrer Anwendung überwachen
yarn twenty function:logs
# Eine Funktion anhand ihres Namens ausführen
yarn twenty function:execute -n my-function -p '{"name": "test"}'
# Die Post-Installationsfunktion ausführen
yarn twenty function:execute --postInstall
# Die Anwendung aus dem aktuellen Arbeitsbereich deinstallieren
yarn twenty app:uninstall
@@ -73,9 +87,9 @@ Wenn Sie `npx create-twenty-app@latest my-twenty-app` ausführen, erledigt der S
* Kopiert eine minimale Basisanwendung nach `my-twenty-app/`
* Fügt eine lokale `twenty-sdk`-Abhängigkeit und die Yarn-4-Konfiguration hinzu
* Erstellt Konfigurationsdateien und Skripte, die an die `twenty`-CLI angebunden sind
* Generiert eine Standard-Anwendungskonfiguration und eine Standard-Funktionsrolle
* Erzeugt Kerndateien (Anwendungskonfiguration, Standardrolle für Logikfunktionen, Post-Installationsfunktion) sowie Beispieldateien entsprechend dem Scaffolding-Modus
Eine frisch erzeugte App sieht so aus:
Eine frisch erstellte App mit dem Standardmodus `--exhaustive` sieht so aus:
```text filename="my-twenty-app/"
my-twenty-app/
@@ -89,17 +103,30 @@ my-twenty-app/
eslint.config.mjs
tsconfig.json
README.md
public/ # Public assets folder (images, fonts, etc.)
public/ # Ordner für öffentliche Assets (Bilder, Schriftarten usw.)
src/
├── application-config.ts # Required - main application configuration
├── application-config.ts # Erforderlich - Hauptkonfiguration der Anwendung
├── roles/
│ └── default-role.ts # Default role for logic functions
│ └── default-role.ts # Standardrolle für Logikfunktionen
├── objects/
│ └── example-object.ts # Beispiel für eine benutzerdefinierte Objektdefinition
├── fields/
│ └── example-field.ts # Beispiel für eine eigenständige Felddefinition
├── logic-functions/
── hello-world.ts # Example logic function
└── front-components/
└── hello-world.tsx # Example front component
── hello-world.ts # Beispiel für eine Logikfunktion
└── post-install.ts # Post-Installations-Logikfunktion
├── front-components/
│ └── hello-world.tsx # Beispiel für eine Frontend-Komponente
├── views/
│ └── example-view.ts # Beispiel für eine gespeicherte View-Definition
├── navigation-menu-items/
│ └── example-navigation-menu-item.ts # Beispiel für einen Navigationslink in der Seitenleiste
└── skills/
└── example-skill.ts # Beispiel für eine Skill-Definition eines KI-Agenten
```
Mit `--minimal` werden nur die Kerndateien erstellt (`application-config.ts`, `roles/default-role.ts` und `logic-functions/post-install.ts`). Mit `--interactive` wählst du aus, welche Beispieldateien enthalten sein sollen.
Auf hoher Ebene:
* **package.json**: Deklariert den App-Namen, die Version und die Engines (Node 24+, Yarn 4) und fügt `twenty-sdk` sowie ein `twenty`-Skript hinzu, das an die lokale `twenty`-CLI delegiert. Führe `yarn twenty help` aus, um alle verfügbaren Befehle aufzulisten.
@@ -115,13 +142,16 @@ Auf hoher Ebene:
Das SDK erkennt Entitäten, indem es Ihre TypeScript-Dateien nach Aufrufen von **`export default define<Entity>({...})`** parst. Für jeden Entitätstyp gibt es eine entsprechende Hilfsfunktion, die aus `twenty-sdk` exportiert wird:
| Hilfsfunktion | Entitätstyp |
| ------------------------ | ---------------------------------------- |
| `defineObject()` | Benutzerdefinierte Objektdefinitionen |
| `defineLogicFunction()` | Definitionen von Logikfunktionen |
| `defineFrontComponent()` | Definitionen von Frontend-Komponenten |
| `defineRole()` | Rollendefinitionen |
| `defineField()` | Felderweiterungen für bestehende Objekte |
| Hilfsfunktion | Entitätstyp |
| ---------------------------- | ----------------------------------------- |
| `defineObject()` | Benutzerdefinierte Objektdefinitionen |
| `defineLogicFunction()` | Definitionen von Logikfunktionen |
| `defineFrontComponent()` | Definitionen von Frontend-Komponenten |
| `defineRole()` | Rollendefinitionen |
| `defineField()` | Felderweiterungen für bestehende Objekte |
| `defineView()` | Gespeicherte View-Definitionen |
| `defineNavigationMenuItem()` | Definitionen von Navigationsmenüeinträgen |
| `defineSkill()` | Skill-Definitionen für KI-Agenten |
<Note>
**Dateibenennung ist flexibel.** Die Entitätserkennung ist AST-basiert — das SDK durchsucht Ihre Quelldateien nach dem Muster `export default define<Entity>({...})`. Sie können Ihre Dateien und Ordner nach Belieben organisieren. Die Gruppierung nach Entitätstyp (z. B. `logic-functions/`, `roles/`) ist lediglich eine Konvention zur Codeorganisation, keine Voraussetzung.
@@ -142,8 +172,8 @@ export default defineObject({
Spätere Befehle fügen weitere Dateien und Ordner hinzu:
* `yarn twenty app:generate` erstellt einen `generated/`-Ordner (typisierter Twenty-Client + Workspace-Typen).
* `yarn twenty entity:add` fügt unter `src/` Entitätsdefinitionsdateien für benutzerdefinierte Objekte, Funktionen, Frontend-Komponenten oder Rollen hinzu.
* `yarn twenty app:dev` generiert automatisch einen typisierten API-Client in `node_modules/twenty-sdk/generated` (typisierter Twenty-Client + Arbeitsbereichs-Typen).
* `yarn twenty entity:add` fügt unter `src/` Entitätsdefinitionsdateien für Ihre benutzerdefinierten Objekte, Funktionen, Frontend-Komponenten, Rollen, Skills und mehr hinzu.
## Authentifizierung
@@ -186,14 +216,17 @@ Das twenty-sdk stellt typisierte Bausteine und Hilfsfunktionen bereit, die Sie i
Das SDK stellt Hilfsfunktionen bereit, um die Entitäten Ihrer App zu definieren. Wie in [Entitätserkennung](#entity-detection) beschrieben, müssen Sie `export default define<Entity>({...})` verwenden, damit Ihre Entitäten erkannt werden:
| Funktion | Zweck |
| ------------------------ | -------------------------------------------------------------- |
| `defineApplication()` | Anwendungsmetadaten konfigurieren (erforderlich, eine pro App) |
| `defineObject()` | Benutzerdefinierte Objekte mit Feldern definieren |
| `defineLogicFunction()` | Logikfunktionen mit Handlern definieren |
| `defineFrontComponent()` | Frontend-Komponenten für benutzerdefinierte UI definieren |
| `defineRole()` | Rollenberechtigungen und Objektzugriff konfigurieren |
| `defineField()` | Bestehende Objekte mit zusätzlichen Feldern erweitern |
| Funktion | Zweck |
| ---------------------------- | -------------------------------------------------------------- |
| `defineApplication()` | Anwendungsmetadaten konfigurieren (erforderlich, eine pro App) |
| `defineObject()` | Benutzerdefinierte Objekte mit Feldern definieren |
| `defineLogicFunction()` | Logikfunktionen mit Handlern definieren |
| `defineFrontComponent()` | Frontend-Komponenten für benutzerdefinierte UI definieren |
| `defineRole()` | Rollenberechtigungen und Objektzugriff konfigurieren |
| `defineField()` | Bestehende Objekte mit zusätzlichen Feldern erweitern |
| `defineView()` | Gespeicherte Views für Objekte definieren |
| `defineNavigationMenuItem()` | Seitenleisten-Navigationslinks definieren |
| `defineSkill()` | Definieren Sie Skills für KI-Agenten |
Diese Funktionen validieren Ihre Konfiguration zur Build-Zeit und bieten IDE-Autovervollständigung sowie Typsicherheit.
@@ -279,7 +312,11 @@ Hauptpunkte:
* Sie können mit `yarn twenty entity:add` neue Objekte erzeugen; der Assistent führt Sie durch Benennung, Felder und Beziehungen.
<Note>
**Basisfelder werden automatisch erstellt.** Wenn Sie ein benutzerdefiniertes Objekt definieren, fügt Twenty automatisch Standardfelder wie `name`, `createdAt`, `updatedAt`, `createdBy`, `position` und `deletedAt` hinzu. Sie müssen diese nicht in Ihrem `fields`-Array definieren — fügen Sie nur Ihre benutzerdefinierten Felder hinzu.
**Basisfelder werden automatisch erstellt.** Wenn Sie ein benutzerdefiniertes Objekt definieren, fügt Twenty automatisch Standardfelder hinzu
wie `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` und `deletedAt`.
Sie müssen diese nicht in Ihrem `fields`-Array definieren — fügen Sie nur Ihre benutzerdefinierten Felder hinzu.
Sie können Standardfelder überschreiben, indem Sie in Ihrem `fields`-Array ein Feld mit demselben Namen definieren,
dies wird jedoch nicht empfohlen.
</Note>
### Anwendungskonfiguration (application-config.ts)
@@ -289,6 +326,7 @@ Jede App hat eine einzelne Datei `application-config.ts`, die Folgendes beschrei
* **Was die App ist**: Bezeichner, Anzeigename und Beschreibung.
* **Wie ihre Funktionen ausgeführt werden**: welche Rolle sie für Berechtigungen verwenden.
* **(Optional) Variablen**: SchlüsselWert-Paare, die Ihren Funktionen als Umgebungsvariablen zur Verfügung gestellt werden.
* **(Optional) Post-Installationsfunktion**: eine Logikfunktion, die nach der Installation der App ausgeführt wird.
Verwenden Sie `defineApplication()`, um Ihre Anwendungskonfiguration zu definieren:
@@ -296,6 +334,7 @@ Verwenden Sie `defineApplication()`, um Ihre Anwendungskonfiguration zu definier
// src/application-config.ts
import { defineApplication } from 'twenty-sdk';
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
@@ -311,6 +350,7 @@ export default defineApplication({
},
},
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
@@ -319,6 +359,7 @@ Notizen:
* `universalIdentifier`-Felder sind deterministische IDs, die Sie besitzen; generieren Sie sie einmal und halten Sie sie über Synchronisierungen hinweg stabil.
* `applicationVariables` werden zu Umgebungsvariablen für Ihre Funktionen (zum Beispiel ist `DEFAULT_RECIPIENT_NAME` als `process.env.DEFAULT_RECIPIENT_NAME` verfügbar).
* `defaultRoleUniversalIdentifier` muss mit der Rollendatei übereinstimmen (siehe unten).
* `postInstallLogicFunctionUniversalIdentifier` (optional) verweist auf eine Logikfunktion, die nach der Installation der App automatisch ausgeführt wird. Siehe [Post-Installationsfunktionen](#post-install-functions).
#### Rollen und Berechtigungen
@@ -457,6 +498,55 @@ Notizen:
* Das Array `triggers` ist optional. Funktionen ohne Trigger können als von anderen Funktionen aufgerufene Utility-Funktionen verwendet werden.
* Sie können mehrere Trigger-Typen in einer Funktion kombinieren.
### Post-Installationsfunktionen
Eine Post-Installationsfunktion ist eine Logikfunktion, die automatisch ausgeführt wird, nachdem Ihre App in einem Arbeitsbereich installiert wurde. Dies ist nützlich für einmalige Einrichtungsvorgänge wie das Befüllen mit Standarddaten, das Erstellen erster Datensätze oder das Konfigurieren von Arbeitsbereichseinstellungen.
Wenn du mit `create-twenty-app` eine neue App erstellst, wird für dich eine Post-Installationsfunktion unter `src/logic-functions/post-install.ts` erzeugt:
```typescript
// src/logic-functions/post-install.ts
import { defineLogicFunction } from 'twenty-sdk';
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
const handler = async (): Promise<void> => {
console.log('Post install logic function executed successfully!');
};
export default defineLogicFunction({
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
name: 'post-install',
description: 'Runs after installation to set up the application.',
timeoutSeconds: 300,
handler,
});
```
Die Funktion wird in deine App eingebunden, indem ihr universeller Bezeichner in `application-config.ts` referenziert wird:
```typescript
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
// ...
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
Du kannst die Post-Installationsfunktion auch jederzeit manuell über die CLI ausführen:
```bash filename="Terminal"
yarn twenty function:execute --postInstall
```
Hauptpunkte:
* Post-Installationsfunktionen sind Standard-Logikfunktionen — sie verwenden `defineLogicFunction()` wie jede andere Funktion.
* Das Feld `postInstallLogicFunctionUniversalIdentifier` in `defineApplication()` ist optional. Wenn es weggelassen wird, wird nach der Installation keine Funktion ausgeführt.
* Das standardmäßige Timeout ist auf 300 Sekunden (5 Minuten) festgelegt, um längere Einrichtungsvorgänge wie Daten-Seeding zu ermöglichen.
* Post-Installationsfunktionen benötigen keine Trigger — sie werden von der Plattform während der Installation oder manuell über `function:execute --postInstall` aufgerufen.
### Routen-Trigger-Payload
<Warning>
@@ -554,6 +644,71 @@ Sie können neue Funktionen auf zwei Arten erstellen:
* **Generiert**: Führen Sie `yarn twenty entity:add` aus und wählen Sie die Option zum Hinzufügen einer neuen Logikfunktion. Dadurch wird eine Starterdatei mit Handler und Konfiguration erzeugt.
* **Manuell**: Erstellen Sie eine neue `*.logic-function.ts`-Datei und verwenden Sie `defineLogicFunction()` nach demselben Muster.
### Eine Logikfunktion als Tool markieren
Logikfunktionen können als **Tools** für KI-Agenten und Workflows verfügbar gemacht werden. Wenn eine Funktion als Tool markiert ist, wird sie von den KI-Funktionen von Twenty auffindbar und kann als Schritt in Workflow-Automatisierungen ausgewählt werden.
Um eine Logikfunktion als Tool zu markieren, setzen Sie `isTool: true` und geben Sie ein `toolInputSchema` an, das die erwarteten Eingabeparameter mithilfe von [JSON Schema](https://json-schema.org/) beschreibt:
```typescript
// src/logic-functions/enrich-company.logic-function.ts
import { defineLogicFunction } from 'twenty-sdk';
import Twenty from '~/generated';
const handler = async (params: { companyName: string; domain?: string }) => {
const client = new Twenty();
const result = await client.mutation({
createTask: {
__args: {
data: {
title: `Enrich data for ${params.companyName}`,
body: `Domain: ${params.domain ?? 'unknown'}`,
},
},
id: true,
},
});
return { taskId: result.createTask.id };
};
export default defineLogicFunction({
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
name: 'enrich-company',
description: 'Enrich a company record with external data',
timeoutSeconds: 10,
handler,
isTool: true,
toolInputSchema: {
type: 'object',
properties: {
companyName: {
type: 'string',
description: 'The name of the company to enrich',
},
domain: {
type: 'string',
description: 'The company website domain (optional)',
},
},
required: ['companyName'],
},
});
```
Hauptpunkte:
* **`isTool`** (`boolean`, Standard: `false`): Wenn auf `true` gesetzt, wird die Funktion als Tool registriert und steht KI-Agenten und Workflow-Automatisierungen zur Verfügung.
* **`toolInputSchema`** (`object`, optional): Ein JSON-Schema-Objekt, das die Parameter beschreibt, die Ihre Funktion akzeptiert. KI-Agenten verwenden dieses Schema, um zu verstehen, welche Eingaben das Tool erwartet, und um Aufrufe zu validieren. Falls weggelassen, lautet der Standardwert für das Schema `{ type: 'object', properties: {} }` (keine Parameter).
* Funktionen mit `isTool: false` (oder nicht gesetzt) werden **nicht** als Tools bereitgestellt. Sie können weiterhin direkt ausgeführt oder von anderen Funktionen aufgerufen werden, erscheinen jedoch nicht in der Tool-Erkennung.
* **Tool-Benennung**: Wenn als Tool bereitgestellt, wird der Funktionsname automatisch zu `logic_function_<name>` normalisiert (in Kleinbuchstaben umgewandelt, nicht alphanumerische Zeichen durch Unterstriche ersetzt). Beispielsweise wird `enrich-company` zu `logic_function_enrich_company`.
* Sie können `isTool` mit Triggern kombinieren — eine Funktion kann gleichzeitig sowohl ein Tool (von KI-Agenten aufrufbar) als auch durch Ereignisse (Cron, Datenbankereignisse, Routen) ausgelöst werden.
<Note>
**Schreiben Sie eine gute `description`.** KI-Agenten verlassen sich auf das `description`-Feld der Funktion, um zu entscheiden, wann das Tool verwendet werden soll. Seien Sie konkret darin, was das Tool tut und wann es aufgerufen werden soll.
</Note>
### Frontend-Komponenten
Frontend-Komponenten ermöglichen es Ihnen, benutzerdefinierte React-Komponenten zu erstellen, die innerhalb der Twenty-UI gerendert werden. Verwenden Sie `defineFrontComponent()`, um Komponenten mit eingebauter Validierung zu definieren:
@@ -591,9 +746,44 @@ Sie können neue Frontend-Komponenten auf zwei Arten erstellen:
* **Generiert**: Führen Sie `yarn twenty entity:add` aus und wählen Sie die Option zum Hinzufügen einer neuen Frontend-Komponente.
* **Manuell**: Erstellen Sie eine neue `*.front-component.tsx`-Datei und verwenden Sie `defineFrontComponent()`.
### Fähigkeiten
Skills definieren wiederverwendbare Anweisungen und Fähigkeiten, die KI-Agenten in Ihrem Arbeitsbereich verwenden können. Verwenden Sie `defineSkill()`, um Skills mit eingebauter Validierung zu definieren:
```typescript
// src/skills/example-skill.ts
import { defineSkill } from 'twenty-sdk';
export default defineSkill({
universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
name: 'sales-outreach',
label: 'Sales Outreach',
description: 'Guides the AI agent through a structured sales outreach process',
icon: 'IconBrain',
content: `You are a sales outreach assistant. When reaching out to a prospect:
1. Research the company and recent news
2. Identify the prospect's role and likely pain points
3. Draft a personalized message referencing specific details
4. Keep the tone professional but conversational`,
});
```
Hauptpunkte:
* `name` ist eine eindeutige Kennung (als Zeichenfolge) für den Skill (kebab-case empfohlen).
* `label` ist der menschenlesbare Anzeigename, der in der UI angezeigt wird.
* `content` enthält die Skill-Anweisungen — dies ist der Text, den der KI-Agent verwendet.
* `icon` (optional) legt das in der UI angezeigte Symbol fest.
* `description` (optional) liefert zusätzlichen Kontext zum Zweck des Skills.
Sie können neue Skills auf zwei Arten erstellen:
* **Generiert**: Führen Sie `yarn twenty entity:add` aus und wählen Sie die Option zum Hinzufügen eines neuen Skills.
* **Manuell**: Erstellen Sie eine neue Datei und verwenden Sie `defineSkill()` nach demselben Muster.
### Generierter typisierter Client
Führen Sie `yarn twenty app:generate` aus, um einen lokalen typisierten Client in `generated/` basierend auf Ihrem Arbeitsbereichs-Schema zu erstellen. Verwenden Sie ihn in Ihren Funktionen:
Der typisierte Client wird von `yarn twenty app:dev` automatisch generiert und basierend auf Ihrem Arbeitsbereichs-Schema in `node_modules/twenty-sdk/generated` gespeichert. Verwenden Sie ihn in Ihren Funktionen:
```typescript
import Twenty from '~/generated';
@@ -602,7 +792,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
Der Client wird durch `yarn twenty app:generate` erneut generiert. Führen Sie ihn nach Änderungen an Ihren Objekten oder beim Onboarding in einen neuen Workspace erneut aus.
Der Client wird von `yarn twenty app:dev` automatisch neu generiert, sobald sich Ihre Objekte oder Felder ändern.
#### Laufzeit-Anmeldedaten in Logikfunktionen
@@ -617,6 +807,53 @@ Notizen:
* Die Berechtigungen des API-Schlüssels werden durch die Rolle bestimmt, auf die in Ihrer `application-config.ts` über `defaultRoleUniversalIdentifier` verwiesen wird. Dies ist die Standardrolle, die von den Logikfunktionen Ihrer Anwendung verwendet wird.
* Anwendungen können Rollen definieren, um das Least-Privilege-Prinzip einzuhalten. Gewähren Sie nur die Berechtigungen, die Ihre Funktionen benötigen, und verweisen Sie dann mit `defaultRoleUniversalIdentifier` auf den universellen Bezeichner dieser Rolle.
#### Dateien hochladen
Der generierte `Twenty`-Client enthält eine Methode `uploadFile`, um Dateien an Felder des Typs Datei in Ihren Arbeitsbereichsobjekten anzuhängen. Da Standard-GraphQL-Clients Multipart-Datei-Uploads nicht nativ unterstützen, stellt der Client diese dedizierte Methode bereit, die unter der Haube die [GraphQL-Multipart-Anfragespezifikation](https://github.com/jaydenseric/graphql-multipart-request-spec) implementiert.
```typescript
import Twenty from '~/generated';
import * as fs from 'fs';
const client = new Twenty();
const fileBuffer = fs.readFileSync('./invoice.pdf');
const uploadedFile = await client.uploadFile(
fileBuffer, // file contents as a Buffer
'invoice.pdf', // filename
'application/pdf', // MIME type (defaults to 'application/octet-stream')
'58a0a314-d7ea-4865-9850-7fb84e72f30b', // field universal identifier
);
console.log(uploadedFile);
// { id: '...', path: '...', size: 12345, createdAt: '...', url: 'https://...' }
```
Die Methodensignatur:
```typescript
uploadFile(
fileBuffer: Buffer,
filename: string,
contentType: string,
fieldMetadataUniversalIdentifier: string,
): Promise<{ id: string; path: string; size: number; createdAt: string; url: string }>
```
| Parameter | Typ | Beschreibung |
| ---------------------------------- | -------- | ------------------------------------------------------------------------------- |
| `fileBuffer` | `Buffer` | Der Rohinhalt der Datei |
| `filename` | `string` | Der Name der Datei (wird für Speicherung und Anzeige verwendet) |
| `contentType` | `string` | MIME-Typ der Datei (standardmäßig `application/octet-stream`, wenn weggelassen) |
| `fieldMetadataUniversalIdentifier` | `string` | Der `universalIdentifier` des Dateityp-Felds in Ihrem Objekt |
Hauptpunkte:
* Die Methode sendet die Datei an den **metadata endpoint** (nicht den main GraphQL endpoint), wo die Upload-Mutation ausgeführt wird.
* Sie verwendet den `universalIdentifier` des Feldes (nicht dessen arbeitsbereichsspezifische ID), sodass Ihr Upload-Code in jedem Arbeitsbereich funktioniert, in dem Ihre App installiert ist — im Einklang damit, wie Apps Felder überall sonst referenzieren.
* Die zurückgegebene `url` ist eine signierte URL, mit der Sie auf die hochgeladene Datei zugreifen können.
### Hello-World-Beispiel
Ein minimales End-to-End-Beispiel, das Objekte, Logikfunktionen, Frontend-Komponenten und mehrere Trigger demonstriert, finden Sie [hier](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world):
@@ -639,13 +876,13 @@ Fügen Sie dann ein `twenty`-Skript hinzu:
}
```
Jetzt können Sie alle Befehle über `yarn twenty <command>` ausführen, z. B. `yarn twenty app:dev`, `yarn twenty app:generate`, `yarn twenty help` usw.
Jetzt können Sie alle Befehle über `yarn twenty <command>` ausführen, z. B. `yarn twenty app:dev`, `yarn twenty help` usw.
## Fehlerbehebung
* Authentifizierungsfehler: Führen Sie `yarn twenty auth:login` aus und stellen Sie sicher, dass Ihr API-Schlüssel die erforderlichen Berechtigungen hat.
* Verbindung zum Server nicht möglich: Überprüfen Sie die API-URL und dass der Twenty-Server erreichbar ist.
* Typen oder Client fehlen/veraltet: Führen Sie `yarn twenty app:generate` aus.
* Typen oder Client fehlen/veraltet: Starten Sie `yarn twenty app:dev` neu — der typisierte Client wird automatisch generiert.
* Dev-Modus synchronisiert nicht: Stellen Sie sicher, dass `yarn twenty app:dev` läuft und dass Änderungen von Ihrer Umgebung nicht ignoriert werden.
Discord-Hilfekanal: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -52,9 +52,6 @@ Desde aquí usted puede:
# Añade una nueva entidad a tu aplicación (guiado)
yarn entity:add
# Genera un cliente tipado de Twenty y tipos de entidad del espacio de trabajo
yarn app:generate
# Supervisa los registros de funciones de tu aplicación
yarn function:logs
@@ -157,7 +154,7 @@ src/
A grandes rasgos:
* **package.json**: Declara el nombre de la aplicación, la versión, los entornos (Node 24+, Yarn 4) y agrega `twenty-sdk` además de scripts como `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` y `auth:login` que delegan en la CLI local `twenty`.
* **package.json**: Declara el nombre de la aplicación, la versión, los entornos (Node 24+, Yarn 4) y agrega `twenty-sdk` además de scripts como `app:dev`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` y `auth:login` que delegan en la CLI local `twenty`.
* **.gitignore**: Ignora artefactos comunes como `node_modules`, `.yarn`, `generated/` (cliente tipado), `dist/`, `build/`, carpetas de cobertura, archivos de registro y archivos `.env*`.
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Bloquean y configuran la cadena de herramientas Yarn 4 utilizada por el proyecto.
* **.nvmrc**: Fija la versión de Node.js esperada por el proyecto.
@@ -173,7 +170,7 @@ A grandes rasgos:
Comandos posteriores añadirán más archivos y carpetas:
* `yarn app:generate` creará una carpeta `generated/` (cliente tipado de Twenty + tipos del espacio de trabajo).
* `yarn app:dev` genera automáticamente el cliente Twenty tipado en `node_modules/twenty-sdk/generated`.
* `yarn entity:add` añadirá archivos de definición de entidades en `src/` para tus objetos, funciones, componentes de interfaz o roles personalizados.
## Autenticación
@@ -585,7 +582,7 @@ Puedes crear funciones nuevas de dos maneras:
### Cliente tipado generado
Ejecuta yarn app:generate para crear un cliente tipado local en generated/ basado en el esquema de tu espacio de trabajo. Úsalo en tus funciones:
`yarn app:dev` genera automáticamente el cliente Twenty tipado en `node_modules/twenty-sdk/generated`. Úsalo en tus funciones:
```typescript
import Twenty from '~/generated';
@@ -594,7 +591,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
El cliente se vuelve a generar con `yarn app:generate`. Vuelve a ejecutarlo después de cambiar tus objetos o al incorporarte a un nuevo espacio de trabajo.
El cliente se regenera automáticamente durante la ejecución de `app:dev`. Reinicia `app:dev` después de cambiar tus objetos o al incorporarte a un nuevo espacio de trabajo.
#### Credenciales en tiempo de ejecución en funciones de lógica
@@ -632,7 +629,6 @@ Luego agrega scripts como estos:
"auth:switch": "twenty auth:switch",
"auth:list": "twenty auth:list",
"app:dev": "twenty app:dev",
"app:generate": "twenty app:generate",
"app:uninstall": "twenty app:uninstall",
"entity:add": "twenty entity:add",
"function:logs": "twenty function:logs",
@@ -642,13 +638,13 @@ Luego agrega scripts como estos:
}
```
Ahora puedes ejecutar los mismos comandos mediante Yarn, p. ej., `yarn app:dev`, `yarn app:generate`, etc.
Ahora puedes ejecutar los mismos comandos mediante Yarn, p. ej., `yarn app:dev`, etc.
## Solución de problemas
* Errores de autenticación: ejecuta `yarn auth:login` y asegúrate de que tu clave de API tenga los permisos necesarios.
* No se puede conectar al servidor: verifica la URL de la API y que el servidor de Twenty sea accesible.
* Tipos o cliente faltantes/obsoletos: ejecuta `yarn app:generate`.
* Tipos o cliente faltantes/obsoletos: reinicia `yarn app:dev`.
* El modo de desarrollo no sincroniza: asegúrate de que `yarn app:dev` esté ejecutándose y de que los cambios no sean ignorados por tu entorno.
Canal de ayuda en Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -52,9 +52,6 @@ yarn app:dev
# Ajouter une nouvelle entité à votre application (assisté)
yarn entity:add
# Générer un client Twenty typé et les types d'entité de l'espace de travail
yarn app:generate
# Surveiller les journaux des fonctions de votre application
yarn function:logs
@@ -157,7 +154,7 @@ src/
Dans les grandes lignes :
* **package.json** : Déclare le nom de lapplication, la version, les moteurs (Node 24+, Yarn 4), et ajoute `twenty-sdk` ainsi que des scripts comme `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` et `auth:login` qui délèguent à la CLI locale `twenty`.
* **package.json** : Déclare le nom de lapplication, la version, les moteurs (Node 24+, Yarn 4), et ajoute `twenty-sdk` ainsi que des scripts comme `app:dev`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` et `auth:login` qui délèguent à la CLI locale `twenty`.
* **.gitignore** : Ignore les artefacts courants tels que `node_modules`, `.yarn`, `generated/` (client typé), `dist/`, `build/`, les dossiers de couverture, les fichiers journaux et les fichiers `.env*`.
* **yarn.lock**, **.yarnrc.yml**, **.yarn/** : Verrouillent et configurent la chaîne doutils Yarn 4 utilisée par le projet.
* **.nvmrc** : Fige la version de Node.js attendue par le projet.
@@ -173,7 +170,7 @@ Dans les grandes lignes :
Des commandes ultérieures ajouteront dautres fichiers et dossiers :
* `yarn app:generate` créera un dossier `generated/` (client Twenty typé + types de lespace de travail).
* `yarn app:dev` génère automatiquement le client Twenty typé dans `node_modules/twenty-sdk/generated`.
* `yarn entity:add` ajoutera des fichiers de définition dentité sous `src/` pour vos objets, fonctions, composants front-end ou rôles personnalisés.
## Authentification
@@ -585,7 +582,7 @@ Vous pouvez créer de nouvelles fonctions de deux façons :
### Client typé généré
Exécutez yarn app:generate pour créer un client typé local dans generated/ basé sur le schéma de votre espace de travail. Utilisez-le dans vos fonctions :
`yarn app:dev` génère automatiquement le client Twenty typé dans `node_modules/twenty-sdk/generated`. Utilisez-le dans vos fonctions :
```typescript
import Twenty from '~/generated';
@@ -594,7 +591,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
Le client est régénéré par `yarn app:generate`. Relancez après avoir modifié vos objets ou lors de lintégration à un nouvel espace de travail.
Le client est régénéré automatiquement pendant l'exécution de `app:dev`. Redémarrez `app:dev` après avoir modifié vos objets ou lors de lintégration à un nouvel espace de travail.
#### Identifiants dexécution dans les fonctions logiques
@@ -632,7 +629,6 @@ Ajoutez ensuite des scripts comme ceux-ci :
"auth:switch": "twenty auth:switch",
"auth:list": "twenty auth:list",
"app:dev": "twenty app:dev",
"app:generate": "twenty app:generate",
"app:uninstall": "twenty app:uninstall",
"entity:add": "twenty entity:add",
"function:logs": "twenty function:logs",
@@ -642,13 +638,13 @@ Ajoutez ensuite des scripts comme ceux-ci :
}
```
Vous pouvez désormais exécuter les mêmes commandes via Yarn, par exemple `yarn app:dev`, `yarn app:generate`, etc.
Vous pouvez désormais exécuter les mêmes commandes via Yarn, par exemple `yarn app:dev`, etc.
## Résolution des problèmes
* Erreurs dauthentification : exécutez `yarn auth:login` et assurez-vous que votre clé API dispose des autorisations requises.
* Impossible de se connecter au serveur : vérifiez lURL de lAPI et que le serveur Twenty est accessible.
* Types ou client manquants/obsolètes : exécutez `yarn app:generate`.
* Types ou client manquants/obsolètes : redémarrez `yarn app:dev`.
* Le mode dev ne se synchronise pas : assurez-vous que `yarn app:dev` est en cours dexécution et que les modifications ne sont pas ignorées par votre environnement.
Canal daide Discord : https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -15,6 +15,7 @@ Le app ti consentono di creare e gestire le personalizzazioni di Twenty **come c
* Definisci oggetti e campi personalizzati come codice (modello dati gestito)
* Crea funzioni logiche con trigger personalizzati
* Definire le abilità per gli agenti IA
* Distribuisci la stessa app su più spazi di lavoro
## Prerequisiti
@@ -27,7 +28,7 @@ Le app ti consentono di creare e gestire le personalizzazioni di Twenty **come c
Crea una nuova app utilizzando lo scaffolder ufficiale, quindi autenticati e inizia a sviluppare:
```bash filename="Terminal"
# Crea lo scaffold di una nuova app
# Crea lo scaffold di una nuova app (include tutti gli esempi per impostazione predefinita)
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
@@ -42,20 +43,33 @@ yarn twenty auth:login
yarn twenty app:dev
```
Lo strumento di scaffolding supporta tre modalità per controllare quali file di esempio vengono inclusi:
```bash filename="Terminal"
# Default (exhaustive): all examples (object, field, logic function, front component, view, navigation menu item, skill)
npx create-twenty-app@latest my-app
# Minimal: only core files (application-config.ts and default-role.ts)
npx create-twenty-app@latest my-app --minimal
# Interactive: select which examples to include
npx create-twenty-app@latest my-app --interactive
```
Da qui puoi:
```bash filename="Terminal"
# Aggiungi una nuova entità alla tua applicazione (guidata)
yarn twenty entity:add
# Genera un client Twenty tipizzato e i tipi di entità dell'area di lavoro
yarn twenty app:generate
# Monitora i log delle funzioni della tua applicazione
yarn twenty function:logs
# Esegui una funzione per nome
yarn twenty function:execute -n my-function -p '{\"name\": \"test\"}'
yarn twenty function:execute -n my-function -p '{"name": "test"}'
# Esegui la funzione post-installazione
yarn twenty function:execute --postInstall
# Disinstalla l'applicazione dallo spazio di lavoro corrente
yarn twenty app:uninstall
@@ -73,9 +87,9 @@ Quando esegui `npx create-twenty-app@latest my-twenty-app`, lo scaffolder:
* Copia un'applicazione base minimale in `my-twenty-app/`
* Aggiunge una dipendenza locale `twenty-sdk` e la configurazione di Yarn 4
* Crea file di configurazione e script collegati alla CLI `twenty`
* Genera una configurazione applicativa predefinita e un ruolo funzione predefinito
* Genera i file principali (configurazione dell'applicazione, ruolo predefinito per le funzioni logiche, funzione di post-installazione) più i file di esempio in base alla modalità di scaffolding
Un'app appena generata dallo scaffolder si presenta così:
Un'app appena creata con la modalità predefinita `--exhaustive` si presenta così:
```text filename="my-twenty-app/"
my-twenty-app/
@@ -89,17 +103,30 @@ my-twenty-app/
eslint.config.mjs
tsconfig.json
README.md
public/ # Cartella delle risorse pubbliche (immagini, font, ecc.)
public/ # Public assets folder (images, fonts, etc.)
src/
├── application-config.ts # Obbligatorio - configurazione principale dell'applicazione
├── application-config.ts # Required - main application configuration
├── roles/
│ └── default-role.ts # Ruolo predefinito per le funzioni logiche
│ └── default-role.ts # Default role for logic functions
├── objects/
│ └── example-object.ts # Example custom object definition
├── fields/
│ └── example-field.ts # Example standalone field definition
├── logic-functions/
── hello-world.ts # Funzione logica di esempio
└── front-components/
└── hello-world.tsx # Componente front-end di esempio
── hello-world.ts # Example logic function
└── post-install.ts # Post-install logic function
├── front-components/
│ └── hello-world.tsx # Example front component
├── views/
│ └── example-view.ts # Example saved view definition
├── navigation-menu-items/
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
└── skills/
└── example-skill.ts # Example AI agent skill definition
```
Con `--minimal`, vengono creati solo i file principali (`application-config.ts`, `roles/default-role.ts` e `logic-functions/post-install.ts`). Con `--interactive`, scegli quali file di esempio includere.
A livello generale:
* **package.json**: Dichiara il nome dell'app, la versione, i motori (Node 24+, Yarn 4) e aggiunge `twenty-sdk` più uno script `twenty` che delega alla CLI locale `twenty`. Esegui `yarn twenty help` per elencare tutti i comandi disponibili.
@@ -115,13 +142,16 @@ A livello generale:
L'SDK rileva le entità analizzando i tuoi file TypeScript alla ricerca di chiamate **`export default define<Entity>({...})`**. Ogni tipo di entità ha una corrispondente funzione helper esportata da `twenty-sdk`:
| Funzione helper | Tipo di entità |
| ------------------------ | ----------------------------------------- |
| `defineObject()` | Definizioni di oggetti personalizzati |
| `defineLogicFunction()` | Definizioni di funzioni logiche |
| `defineFrontComponent()` | Definizioni dei componenti front-end |
| `defineRole()` | Definizioni di ruoli |
| `defineField()` | Estensioni di campo per oggetti esistenti |
| Funzione helper | Tipo di entità |
| ---------------------------- | ---------------------------------------------- |
| `defineObject()` | Definizioni di oggetti personalizzati |
| `defineLogicFunction()` | Definizioni di funzioni logiche |
| `defineFrontComponent()` | Definizioni dei componenti front-end |
| `defineRole()` | Definizioni di ruoli |
| `defineField()` | Estensioni di campo per oggetti esistenti |
| `defineView()` | Definizioni di viste salvate |
| `defineNavigationMenuItem()` | Definizioni delle voci del menu di navigazione |
| `defineSkill()` | AI agent skill definitions |
<Note>
**La denominazione dei file è flessibile.** Il rilevamento delle entità è basato sull'AST — l'SDK esegue la scansione dei file sorgente alla ricerca del pattern `export default define<Entity>({...})`. Puoi organizzare file e cartelle come preferisci. Raggruppare per tipo di entità (ad es., `logic-functions/`, `roles/`) è solo una convenzione per l'organizzazione del codice, non un requisito.
@@ -142,8 +172,8 @@ export default defineObject({
Comandi successivi aggiungeranno altri file e cartelle:
* `yarn twenty app:generate` creerà una cartella `generated/` (client Twenty tipizzato + tipi dello spazio di lavoro).
* `yarn twenty entity:add` aggiungerà file di definizione delle entità sotto `src/` per i tuoi oggetti, funzioni, componenti front-end o ruoli personalizzati.
* `yarn twenty app:dev` genererà automaticamente un client API tipizzato in `node_modules/twenty-sdk/generated` (client Twenty tipizzato + tipi dell'area di lavoro).
* `yarn twenty entity:add` will add entity definition files under `src/` for your custom objects, functions, front components, roles, skills, and more.
## Autenticazione
@@ -186,14 +216,17 @@ Il pacchetto twenty-sdk fornisce blocchi tipizzati e funzioni helper da usare ne
L'SDK fornisce funzioni helper per definire le entità della tua app. Come descritto in [Rilevamento delle entità](#entity-detection), devi usare `export default define<Entity>({...})` affinché le tue entità vengano rilevate:
| Funzione | Scopo |
| ------------------------ | ----------------------------------------------------------------------- |
| `defineApplication()` | Configura i metadati dell'applicazione (obbligatorio, uno per app) |
| `defineObject()` | Definisci oggetti personalizzati con campi |
| `defineLogicFunction()` | Definisci funzioni logiche con handler |
| `defineFrontComponent()` | Definisci componenti front-end per un'interfaccia utente personalizzata |
| `defineRole()` | Configura i permessi dei ruoli e l'accesso agli oggetti |
| `defineField()` | Estendi gli oggetti esistenti con campi aggiuntivi |
| Funzione | Scopo |
| ---------------------------- | ----------------------------------------------------------------------- |
| `defineApplication()` | Configura i metadati dell'applicazione (obbligatorio, uno per app) |
| `defineObject()` | Definisci oggetti personalizzati con campi |
| `defineLogicFunction()` | Definisci funzioni logiche con handler |
| `defineFrontComponent()` | Definisci componenti front-end per un'interfaccia utente personalizzata |
| `defineRole()` | Configura i permessi dei ruoli e l'accesso agli oggetti |
| `defineField()` | Estendi gli oggetti esistenti con campi aggiuntivi |
| `defineView()` | Definisce viste salvate per gli oggetti |
| `defineNavigationMenuItem()` | Definisce i link di navigazione della barra laterale |
| `defineSkill()` | Define AI agent skills |
Queste funzioni convalidano la configurazione in fase di build e offrono il completamento automatico nell'IDE e la sicurezza dei tipi.
@@ -279,7 +312,11 @@ Punti chiave:
* Puoi generare nuovi oggetti con `yarn twenty entity:add`, che ti guida nella denominazione, nei campi e nelle relazioni.
<Note>
**I campi base vengono creati automaticamente.** Quando definisci un oggetto personalizzato, Twenty aggiunge automaticamente i campi standard come `name`, `createdAt`, `updatedAt`, `createdBy`, `position` e `deletedAt`. Non è necessario definirli nel tuo array `fields` — aggiungi solo i tuoi campi personalizzati.
**I campi base vengono creati automaticamente.** Quando definisci un oggetto personalizzato, Twenty aggiunge automaticamente i campi standard
come `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` e `deletedAt`.
Non è necessario definirli nel tuo array `fields` — aggiungi solo i tuoi campi personalizzati.
Puoi sovrascrivere i campi predefiniti definendo un campo con lo stesso nome nel tuo array `fields`,
ma non è consigliato.
</Note>
### Configurazione dell'applicazione (application-config.ts)
@@ -289,6 +326,7 @@ Ogni app ha un singolo file `application-config.ts` che descrive:
* **Identità dell'app**: identificatori, nome visualizzato e descrizione.
* **Come vengono eseguite le sue funzioni**: quale ruolo usano per i permessi.
* **Variabili (opzionali)**: coppie chiavevalore esposte alle funzioni come variabili d'ambiente.
* **(Opzionale) funzione post-installazione**: una funzione logica che viene eseguita dopo l'installazione dell'app.
Usa `defineApplication()` per definire la configurazione della tua applicazione:
@@ -296,6 +334,7 @@ Usa `defineApplication()` per definire la configurazione della tua applicazione:
// src/application-config.ts
import { defineApplication } from 'twenty-sdk';
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
@@ -311,6 +350,7 @@ export default defineApplication({
},
},
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
@@ -319,6 +359,7 @@ Note:
* I campi `universalIdentifier` sono ID deterministici sotto il tuo controllo; generali una volta e mantienili stabili tra le sincronizzazioni.
* `applicationVariables` diventano variabili d'ambiente per le tue funzioni (ad esempio, `DEFAULT_RECIPIENT_NAME` è disponibile come `process.env.DEFAULT_RECIPIENT_NAME`).
* `defaultRoleUniversalIdentifier` deve corrispondere al file del ruolo (vedi sotto).
* `postInstallLogicFunctionUniversalIdentifier` (opzionale) fa riferimento a una funzione logica che viene eseguita automaticamente dopo l'installazione dell'app. Vedi [Funzioni post-installazione](#post-install-functions).
#### Ruoli e permessi
@@ -457,6 +498,55 @@ Note:
* L'array `triggers` è facoltativo. Le funzioni senza trigger possono essere utilizzate come funzioni di utilità richiamate da altre funzioni.
* Puoi combinare più tipi di trigger in un'unica funzione.
### Funzioni post-installazione
Una funzione post-installazione è una funzione logica che viene eseguita automaticamente dopo che la tua app è stata installata in uno spazio di lavoro. Questo è utile per attività di configurazione una tantum come il popolamento di dati predefiniti, la creazione di record iniziali o la configurazione delle impostazioni dello spazio di lavoro.
Quando esegui lo scaffolding di una nuova app con `create-twenty-app`, viene generata automaticamente una funzione di post-installazione in `src/logic-functions/post-install.ts`:
```typescript
// src/logic-functions/post-install.ts
import { defineLogicFunction } from 'twenty-sdk';
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
const handler = async (): Promise<void> => {
console.log('Post install logic function executed successfully!');
};
export default defineLogicFunction({
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
name: 'post-install',
description: 'Runs after installation to set up the application.',
timeoutSeconds: 300,
handler,
});
```
La funzione viene collegata alla tua app facendo riferimento al suo identificatore universale in `application-config.ts`:
```typescript
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
// ...
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
Puoi anche eseguire manualmente la funzione di post-installazione in qualsiasi momento utilizzando la CLI:
```bash filename="Terminal"
yarn twenty function:execute --postInstall
```
Punti chiave:
* Le funzioni di post-installazione sono funzioni logiche standard — usano `defineLogicFunction()` come qualsiasi altra funzione.
* Il campo `postInstallLogicFunctionUniversalIdentifier` in `defineApplication()` è facoltativo. Se omesso, nessuna funzione viene eseguita dopo l'installazione.
* Il timeout predefinito è impostato a 300 secondi (5 minuti) per consentire attività di configurazione più lunghe, come il popolamento dei dati.
* Le funzioni di post-installazione non necessitano di trigger — vengono invocate dalla piattaforma durante l'installazione o manualmente tramite `function:execute --postInstall`.
### Payload del trigger di route
<Warning>
@@ -554,6 +644,71 @@ Puoi creare nuove funzioni in due modi:
* **Generata dallo scaffolder**: Esegui `yarn twenty entity:add` e scegli l'opzione per aggiungere una nuova funzione logica. Questo genera un file iniziale con un handler e una configurazione.
* **Manuale**: Crea un nuovo file `*.logic-function.ts` e usa `defineLogicFunction()`, seguendo lo stesso schema.
### Contrassegnare una funzione logica come strumento
Le funzioni logiche possono essere esposte come **strumenti** per gli agenti di IA e i flussi di lavoro. Quando una funzione è contrassegnata come strumento, diventa individuabile dalle funzionalità di IA di Twenty e può essere selezionata come passaggio nelle automazioni dei flussi di lavoro.
Per contrassegnare una funzione logica come strumento, imposta `isTool: true` e fornisci un `toolInputSchema` che descriva i parametri di input attesi utilizzando [JSON Schema](https://json-schema.org/):
```typescript
// src/logic-functions/enrich-company.logic-function.ts
import { defineLogicFunction } from 'twenty-sdk';
import Twenty from '~/generated';
const handler = async (params: { companyName: string; domain?: string }) => {
const client = new Twenty();
const result = await client.mutation({
createTask: {
__args: {
data: {
title: `Enrich data for ${params.companyName}`,
body: `Domain: ${params.domain ?? 'unknown'}`,
},
},
id: true,
},
});
return { taskId: result.createTask.id };
};
export default defineLogicFunction({
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
name: 'enrich-company',
description: 'Enrich a company record with external data',
timeoutSeconds: 10,
handler,
isTool: true,
toolInputSchema: {
type: 'object',
properties: {
companyName: {
type: 'string',
description: 'The name of the company to enrich',
},
domain: {
type: 'string',
description: 'The company website domain (optional)',
},
},
required: ['companyName'],
},
});
```
Punti chiave:
* **`isTool`** (`boolean`, predefinito: `false`): Quando impostato su `true`, la funzione viene registrata come strumento e diventa disponibile per gli agenti IA e le automazioni dei flussi di lavoro.
* **`toolInputSchema`** (`object`, opzionale): Un oggetto JSON Schema che descrive i parametri accettati dalla funzione. Gli agenti IA utilizzano questo schema per capire quali input si aspetta lo strumento e per convalidare le chiamate. Se omesso, lo schema assume il valore predefinito `{ type: 'object', properties: {} }` (nessun parametro).
* Le funzioni con `isTool: false` (o non impostato) **non** vengono esposte come strumenti. Possono comunque essere eseguite direttamente o chiamate da altre funzioni, ma non compariranno nell'individuazione degli strumenti.
* **Denominazione dello strumento**: Quando esposta come strumento, il nome della funzione viene normalizzato automaticamente in `logic_function_<name>` (in minuscolo, i caratteri non alfanumerici vengono sostituiti da trattini bassi). Ad esempio, `enrich-company` diventa `logic_function_enrich_company`.
* È possibile combinare `isTool` con i trigger — una funzione può essere sia uno strumento (invocabile dagli agenti IA) sia attivata da eventi (cron, eventi del database, routes) contemporaneamente.
<Note>
**Scrivi una buona `description`.** Gli agenti IA fanno affidamento sul campo `description` della funzione per decidere quando usare lo strumento. Sii specifico su cosa fa lo strumento e quando dovrebbe essere invocato.
</Note>
### Componenti front-end
I componenti front-end ti consentono di creare componenti React personalizzati che vengono renderizzati all'interno dell'interfaccia di Twenty. Usa `defineFrontComponent()` per definire componenti con convalida integrata:
@@ -591,9 +746,44 @@ Puoi creare nuovi componenti front-end in due modi:
* **Generata dallo scaffolder**: Esegui `yarn twenty entity:add` e scegli l'opzione per aggiungere un nuovo componente front-end.
* **Manuale**: Crea un nuovo file `*.front-component.tsx` e usa `defineFrontComponent()`.
### Abilità
Skills define reusable instructions and capabilities that AI agents can use within your workspace. Use `defineSkill()` to define skills with built-in validation:
```typescript
// src/skills/example-skill.ts
import { defineSkill } from 'twenty-sdk';
export default defineSkill({
universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
name: 'sales-outreach',
label: 'Sales Outreach',
description: 'Guides the AI agent through a structured sales outreach process',
icon: 'IconBrain',
content: `You are a sales outreach assistant. When reaching out to a prospect:
1. Research the company and recent news
2. Identify the prospect's role and likely pain points
3. Draft a personalized message referencing specific details
4. Keep the tone professional but conversational`,
});
```
Punti chiave:
* `name` is a unique identifier string for the skill (kebab-case recommended).
* `label` is the human-readable display name shown in the UI.
* `content` contains the skill instructions — this is the text the AI agent uses.
* `icon` (optional) sets the icon displayed in the UI.
* `description` (optional) provides additional context about the skill's purpose.
You can create new skills in two ways:
* **Scaffolded**: Run `yarn twenty entity:add` and choose the option to add a new skill.
* **Manual**: Create a new file and use `defineSkill()`, following the same pattern.
### Client tipizzato generato
Esegui `yarn twenty app:generate` per creare un client tipizzato locale in `generated/` basato sullo schema del tuo spazio di lavoro. Usalo nelle tue funzioni:
Il client tipizzato è generato automaticamente da `yarn twenty app:dev` e salvato in `node_modules/twenty-sdk/generated` in base allo schema della tua area di lavoro. Usalo nelle tue funzioni:
```typescript
import Twenty from '~/generated';
@@ -602,7 +792,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
Il client viene rigenerato da `yarn twenty app:generate`. Eseguilo nuovamente dopo aver modificato i tuoi oggetti oppure quando effettui l'onboarding su un nuovo spazio di lavoro.
Il client viene rigenerato automaticamente da `yarn twenty app:dev` ogni volta che i tuoi oggetti o campi cambiano.
#### Credenziali di runtime nelle funzioni logiche
@@ -617,6 +807,53 @@ Note:
* I permessi della chiave API sono determinati dal ruolo referenziato nel tuo `application-config.ts` tramite `defaultRoleUniversalIdentifier`. Questo è il ruolo predefinito utilizzato dalle funzioni logiche della tua applicazione.
* Le applicazioni possono definire ruoli per seguire il principio del privilegio minimo. Concedi solo i permessi necessari alle tue funzioni, quindi punta `defaultRoleUniversalIdentifier` all'identificatore universale di quel ruolo.
#### Caricamento dei file
Il client `Twenty` generato include un metodo `uploadFile` per allegare file ai campi di tipo file sugli oggetti del tuo spazio di lavoro. Poiché i client GraphQL standard non supportano nativamente il caricamento di file multipart, il client fornisce questo metodo dedicato che implementa la [specifica della richiesta GraphQL multipart](https://github.com/jaydenseric/graphql-multipart-request-spec) dietro le quinte.
```typescript
import Twenty from '~/generated';
import * as fs from 'fs';
const client = new Twenty();
const fileBuffer = fs.readFileSync('./invoice.pdf');
const uploadedFile = await client.uploadFile(
fileBuffer, // file contents as a Buffer
'invoice.pdf', // filename
'application/pdf', // MIME type (defaults to 'application/octet-stream')
'58a0a314-d7ea-4865-9850-7fb84e72f30b', // field universal identifier
);
console.log(uploadedFile);
// { id: '...', path: '...', size: 12345, createdAt: '...', url: 'https://...' }
```
La firma del metodo:
```typescript
uploadFile(
fileBuffer: Buffer,
filename: string,
contentType: string,
fieldMetadataUniversalIdentifier: string,
): Promise<{ id: string; path: string; size: number; createdAt: string; url: string }>
```
| Parametro | Tipo | Descrizione |
| ---------------------------------- | -------- | ------------------------------------------------------------------------ |
| `fileBuffer` | `Buffer` | Il contenuto grezzo del file |
| `filename` | `string` | Il nome del file (utilizzato per l'archiviazione e la visualizzazione) |
| `contentType` | `string` | Tipo MIME del file (predefinito su `application/octet-stream` se omesso) |
| `fieldMetadataUniversalIdentifier` | `string` | L'`universalIdentifier` del campo di tipo file nel tuo oggetto |
Punti chiave:
* Il metodo invia il file al **metadata endpoint** (non all'endpoint GraphQL principale), dove la mutation di upload viene risolta.
* Usa l'`universalIdentifier` del campo (non il suo ID specifico dello spazio di lavoro), quindi il tuo codice di upload funziona in qualsiasi spazio di lavoro in cui la tua app è installata — coerentemente con il modo in cui le app fanno riferimento ai campi altrove.
* L'`url` restituito è un URL firmato che puoi usare per accedere al file caricato.
### Esempio Hello World
Esplora un esempio minimale end-to-end che dimostra oggetti, funzioni logiche, componenti front-end e trigger multipli [qui](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world):
@@ -639,13 +876,13 @@ Quindi aggiungi uno script `twenty`:
}
```
Ora puoi eseguire tutti i comandi tramite `yarn twenty <command>`, ad es. `yarn twenty app:dev`, `yarn twenty app:generate`, `yarn twenty help`, ecc.
Ora puoi eseguire tutti i comandi tramite `yarn twenty <command>`, ad es. `yarn twenty app:dev`, `yarn twenty help`, ecc.
## Risoluzione dei problemi
* Errori di autenticazione: esegui `yarn twenty auth:login` e assicurati che la tua chiave API abbia i permessi richiesti.
* Impossibile connettersi al server: verifica l'URL dell'API e che il server Twenty sia raggiungibile.
* Tipi o client mancanti/obsoleti: esegui `yarn twenty app:generate`.
* Types or client missing/outdated: restart `yarn twenty app:dev` — it auto-generates the typed client.
* Modalità di sviluppo non sincronizzata: assicurati che `yarn twenty app:dev` sia in esecuzione e che le modifiche non vengano ignorate dal tuo ambiente.
Canale di supporto su Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -52,9 +52,6 @@ yarn app:dev
# アプリケーションに新しいエンティティを追加(ガイド付き)
yarn entity:add
# 型付きの Twenty クライアントとワークスペースのエンティティ型を生成
yarn app:generate
# アプリケーションの関数のログを監視
yarn function:logs
@@ -156,7 +153,7 @@ src/
概要:
* **package.json**: Declares the app name, version, engines (Node 24+, Yarn 4), and adds `twenty-sdk` plus scripts like `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall`, and `auth:login` that delegate to the local `twenty` CLI.
* **package.json**: Declares the app name, version, engines (Node 24+, Yarn 4), and adds `twenty-sdk` plus scripts like `app:dev`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall`, and `auth:login` that delegate to the local `twenty` CLI.
* **.gitignore**: `node_modules`、`.yarn`、`generated/`(型付きクライアント)、`dist/`、`build/`、カバレッジ用フォルダー、ログファイル、`.env*` ファイルなどの一般的な生成物を無視します。
* **yarn.lock**、**.yarnrc.yml**、**.yarn/**: プロジェクトで使用する Yarn 4 ツールチェーンをロックおよび構成します。
* **.nvmrc**: プロジェクトで想定する Node.js バージョンを固定します。
@@ -171,7 +168,7 @@ src/
後続のコマンドにより、さらにファイルやフォルダーが追加されます:
* `yarn app:generate` は `generated/` フォルダー(型付き Twenty クライアント + ワークスペースの型)を作成します。
* `yarn app:dev` は `node_modules/twenty-sdk/generated` 型付き Twenty クライアントを自動生成します。
* `yarn entity:add` will add entity definition files under `src/` for your custom objects, functions, front components, or roles.
## 認証
@@ -583,7 +580,7 @@ const handler = async (event: RoutePayload) => {
### 生成された型付きクライアント
ワークスペースのスキーマに基づき、generated/ローカルの型付きクライアントを作成するには yarn app:generate を実行します。 関数内で使用します:
`yarn app:dev` は `node_modules/twenty-sdk/generated`型付き Twenty クライアントを自動生成します。 関数内で使用します:
```typescript
import Twenty from '~/generated';
@@ -592,7 +589,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
このクライアントは `yarn app:generate` によって再生成されます。 Re-run after changing your objects or when onboarding to a new workspace.
このクライアントは `app:dev` 実行中に自動的に再生成されます。 オブジェクトを変更した後、または新しいワークスペースにオンボーディングする際は、`app:dev` を再起動してください。
#### Runtime credentials in logic functions
@@ -630,7 +627,6 @@ yarn add -D twenty-sdk
"auth:switch": "twenty auth:switch",
"auth:list": "twenty auth:list",
"app:dev": "twenty app:dev",
"app:generate": "twenty app:generate",
"app:uninstall": "twenty app:uninstall",
"entity:add": "twenty entity:add",
"function:logs": "twenty function:logs",
@@ -640,13 +636,13 @@ yarn add -D twenty-sdk
}
```
Now you can run the same commands via Yarn, e.g. `yarn app:dev`, `yarn app:generate`, etc.
Now you can run the same commands via Yarn, e.g. `yarn app:dev`, etc.
## トラブルシューティング
* 認証エラー: `yarn auth:login` を実行し、API キーに必要な権限があることを確認してください。
* サーバーに接続できません: API URL と、Twenty サーバーに到達可能であることを確認してください。
* Types or client missing/outdated: run `yarn app:generate`.
* Types or client missing/outdated: restart `yarn app:dev`.
* 開発モードで同期されない: `yarn app:dev` が実行中であり、環境によって変更が無視されていないことを確認してください。
Discord ヘルプチャンネル: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -52,9 +52,6 @@ yarn app:dev
# Add a new entity to your application (guided)
yarn entity:add
# Generate a typed Twenty client and workspace entity types
yarn app:generate
# Watch your application's function logs
yarn function:logs
@@ -157,7 +154,7 @@ src/
개요:
* **package.json**: 앱 이름, 버전, 엔진(Node 24+, Yarn 4)을 선언하고, `twenty-sdk`와 함께 `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall`, `auth:login` 같은 스크립트를 추가합니다. 이 스크립트들은 로컬 `twenty` CLI에 위임됩니다.
* **package.json**: 앱 이름, 버전, 엔진(Node 24+, Yarn 4)을 선언하고, `twenty-sdk`와 함께 `app:dev`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall`, `auth:login` 같은 스크립트를 추가합니다. 이 스크립트들은 로컬 `twenty` CLI에 위임됩니다.
* **.gitignore**: `node_modules`, `.yarn`, `generated/`(타입드 클라이언트), `dist/`, `build/`, 커버리지 폴더, 로그 파일, `.env*` 파일 등의 일반 산출물을 무시합니다.
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: 프로젝트에서 사용하는 Yarn 4 툴체인을 고정하고 구성합니다.
* **.nvmrc**: 프로젝트에서 예상하는 Node.js 버전을 고정합니다.
@@ -173,7 +170,7 @@ src/
이후 명령을 실행하면 더 많은 파일과 폴더가 추가됩니다:
* `yarn app:generate`는 `generated/` 폴더를 생성합니다(타입드 Twenty 클라이언트 + 워크스페이스 타입).
* `yarn app:dev`는 `node_modules/twenty-sdk/generated`에 타입드 Twenty 클라이언트를 자동으로 생성합니다.
* `yarn entity:add`는 사용자 정의 객체, 함수, 프런트 컴포넌트 또는 역할에 대한 엔티티 정의 파일을 `src/` 아래에 추가합니다.
## 인증
@@ -585,7 +582,7 @@ const handler = async (event: RoutePayload) => {
### 생성된 타입드 클라이언트
워크스페이스 스키마를 기반으로 generated/ 로컬 타입드 클라이언트를 생성하려면 yarn app:generate를 실행하세요. 함수에서 사용하세요:
`yarn app:dev`는 `node_modules/twenty-sdk/generated`에 타입드 Twenty 클라이언트를 자동으로 생성합니다. 함수에서 사용하세요:
```typescript
import Twenty from '~/generated';
@@ -594,7 +591,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
클라이언트는 `yarn app:generate`로 다시 생성됩니다. 객체를 변경한 후 또는 새 워크스페이스에 온보딩할 때 다시 실행하세요.
클라이언트는 `app:dev` 실행 중 자동으로 다시 생성됩니다. 객체를 변경한 후 또는 새 워크스페이스에 온보딩할 때 `app:dev`를 다시 시작하세요.
#### 로직 함수의 런타임 자격 증명
@@ -632,7 +629,6 @@ yarn add -D twenty-sdk
"auth:switch": "twenty auth:switch",
"auth:list": "twenty auth:list",
"app:dev": "twenty app:dev",
"app:generate": "twenty app:generate",
"app:uninstall": "twenty app:uninstall",
"entity:add": "twenty entity:add",
"function:logs": "twenty function:logs",
@@ -642,13 +638,13 @@ yarn add -D twenty-sdk
}
```
이제 Yarn을 통해 동일한 명령을 실행할 수 있습니다. 예: `yarn app:dev`, `yarn app:generate` 등.
이제 Yarn을 통해 동일한 명령을 실행할 수 있습니다. 예: `yarn app:dev` 등.
## 문제 해결
* 인증 오류: `yarn auth:login`를 실행하고 API 키에 필요한 권한이 있는지 확인하세요.
* 서버에 연결할 수 없음: API URL과 Twenty 서버에 접근 가능한지 확인하세요.
* 타입 또는 클라이언트가 없거나 오래된 경우: `yarn app:generate`를 실행하세요.
* 타입 또는 클라이언트가 없거나 오래된 경우: `yarn app:dev`를 다시 시작하세요.
* 개발 모드가 동기화되지 않음: `yarn app:dev`가 실행 중인지, 환경에서 변경 사항을 무시하지 않는지 확인하세요.
Discord 도움말 채널: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -15,6 +15,7 @@ Os aplicativos permitem criar e gerenciar personalizações do Twenty **como có
* Defina objetos e campos personalizados como código (modelo de dados gerenciado)
* Crie funções de lógica com gatilhos personalizados
* Definir habilidades para agentes de IA
* Implemente o mesmo aplicativo em vários espaços de trabalho
## Pré-requisitos
@@ -27,35 +28,48 @@ Os aplicativos permitem criar e gerenciar personalizações do Twenty **como có
Crie um novo aplicativo usando o gerador oficial, depois autentique-se e comece a desenvolver:
```bash filename="Terminal"
# Scaffold a new app
# Criar a estrutura de um novo app (inclui todos os exemplos por padrão)
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
# If you don't use yarn@4
# Se você não usa yarn@4
corepack enable
yarn install
# Authenticate using your API key (you'll be prompted)
# Autentique-se usando sua chave de API (você será solicitado)
yarn twenty auth:login
# Start dev mode: automatically syncs local changes to your workspace
# Iniciar modo de desenvolvimento: sincroniza automaticamente as alterações locais com seu workspace
yarn twenty app:dev
```
O gerador de estrutura oferece suporte a três modos para controlar quais arquivos de exemplo são incluídos:
```bash filename="Terminal"
# Padrão (exhaustivo): todos os exemplos (objeto, campo, função de lógica, componente de front-end, visualização, item do menu de navegação, habilidade)
npx create-twenty-app@latest my-app
# Mínimo: apenas arquivos principais (application-config.ts e default-role.ts)
npx create-twenty-app@latest my-app --minimal
# Interativo: selecione quais exemplos incluir
npx create-twenty-app@latest my-app --interactive
```
A partir daqui você pode:
```bash filename="Terminal"
# Adicionar uma nova entidade à sua aplicação (assistido)
yarn twenty entity:add
# Gerar um cliente Twenty tipado e tipos de entidades do espaço de trabalho
yarn twenty app:generate
# Acompanhar os logs das funções da sua aplicação
yarn twenty function:logs
# Executar uma função pelo nome
yarn twenty function:execute -n my-function -p '{"name": "test"}'
yarn twenty function:execute -n my-function -p '{\"name\": \"test\"}'
# Executar a função de pós-instalação
yarn twenty function:execute --postInstall
# Desinstalar a aplicação do espaço de trabalho atual
yarn twenty app:uninstall
@@ -73,9 +87,9 @@ Ao executar `npx create-twenty-app@latest my-twenty-app`, o gerador:
* Copia um aplicativo base mínimo para `my-twenty-app/`
* Adiciona uma dependência local `twenty-sdk` e a configuração do Yarn 4
* Cria arquivos de configuração e scripts conectados à CLI `twenty`
* Gera uma configuração de aplicativo padrão e um papel padrão para as funções
* Gera arquivos principais (configuração da aplicação, papel padrão para funções de lógica, função de pós-instalação) além de arquivos de exemplo com base no modo de geração de estrutura
Um aplicativo recém-criado pelo scaffold fica assim:
Um app recém-criado com o modo padrão `--exhaustive` fica assim:
```text filename="my-twenty-app/"
my-twenty-app/
@@ -94,12 +108,25 @@ my-twenty-app/
├── application-config.ts # Obrigatório - configuração principal da aplicação
├── roles/
│ └── default-role.ts # Papel padrão para funções de lógica
├── objects/
│ └── example-object.ts # Exemplo de definição de objeto personalizado
├── fields/
│ └── example-field.ts # Exemplo de definição de campo independente
├── logic-functions/
── hello-world.ts # Exemplo de função de lógica
└── front-components/
└── hello-world.tsx # Exemplo de componente de front-end
── hello-world.ts # Exemplo de função de lógica
└── post-install.ts # Função de lógica de pós-instalação
├── front-components/
│ └── hello-world.tsx # Exemplo de componente de front-end
├── views/
│ └── example-view.ts # Exemplo de definição de visualização salva
├── navigation-menu-items/
│ └── example-navigation-menu-item.ts # Exemplo de link de navegação da barra lateral
└── skills/
└── example-skill.ts # Exemplo de definição de habilidade de agente de IA
```
Com `--minimal`, apenas os arquivos principais são criados (`application-config.ts`, `roles/default-role.ts` e `logic-functions/post-install.ts`). Com `--interactive`, você escolhe quais arquivos de exemplo incluir.
Em alto nível:
* **package.json**: Declara o nome do app, versão, engines (Node 24+, Yarn 4), e adiciona `twenty-sdk` além de um script `twenty` que delega para a CLI `twenty` local. Execute `yarn twenty help` para listar todos os comandos disponíveis.
@@ -115,13 +142,16 @@ Em alto nível:
O SDK detecta entidades analisando seus arquivos TypeScript em busca de chamadas **`export default define<Entity>({...})`**. Cada tipo de entidade tem uma função utilitária correspondente exportada de `twenty-sdk`:
| Função utilitária | Tipo de entidade |
| ------------------------ | ------------------------------------------- |
| `defineObject()` | Definições de objetos personalizados |
| `defineLogicFunction()` | Definições de funções de lógica |
| `defineFrontComponent()` | Definições de componentes de front-end |
| `defineRole()` | Definições de papéis |
| `defineField()` | Extensões de campos para objetos existentes |
| Função utilitária | Tipo de entidade |
| ---------------------------- | ------------------------------------------- |
| `defineObject()` | Definições de objetos personalizados |
| `defineLogicFunction()` | Definições de funções de lógica |
| `defineFrontComponent()` | Definições de componentes de front-end |
| `defineRole()` | Definições de papéis |
| `defineField()` | Extensões de campos para objetos existentes |
| `defineView()` | Definições de visualizações salvas |
| `defineNavigationMenuItem()` | Definições de itens do menu de navegação |
| `defineSkill()` | Definições de habilidades de agente de IA |
<Note>
**A nomeação de arquivos é flexível.** A detecção de entidades é baseada em AST — o SDK varre seus arquivos fonte em busca do padrão `export default define<Entity>({...})`. Você pode organizar seus arquivos e pastas como quiser. Agrupar por tipo de entidade (por exemplo, `logic-functions/`, `roles/`) é apenas uma convenção para organização do código, não um requisito.
@@ -142,8 +172,8 @@ export default defineObject({
Comandos posteriores adicionarão mais arquivos e pastas:
* `yarn twenty app:generate` criará uma pasta `generated/` (cliente tipado do Twenty + tipos do espaço de trabalho).
* `yarn twenty entity:add` adicionará arquivos de definição de entidade em `src/` para seus objetos, funções, componentes de front-end ou papéis personalizados.
* `yarn twenty app:dev` vai gerar automaticamente um cliente de API tipado em `node_modules/twenty-sdk/generated` (cliente Twenty tipado + tipos do espaço de trabalho).
* `yarn twenty entity:add` adicionará arquivos de definição de entidade em `src/` para seus objetos, funções, componentes de front-end, papéis e habilidades personalizados, entre outros.
## Autenticação
@@ -186,14 +216,17 @@ O twenty-sdk fornece blocos de construção tipados e funções utilitárias que
O SDK fornece funções utilitárias para definir as entidades do seu app. Conforme descrito em [Detecção de entidades](#entity-detection), você deve usar `export default define<Entity>({...})` para que suas entidades sejam detectadas:
| Função | Finalidade |
| ------------------------ | ------------------------------------------------------------ |
| `defineApplication()` | Configurar metadados do aplicativo (obrigatório, um por app) |
| `defineObject()` | Define objetos personalizados com campos |
| `defineLogicFunction()` | Defina funções de lógica com handlers |
| `defineFrontComponent()` | Definir componentes de front-end para UI personalizada |
| `defineRole()` | Configura permissões de papéis e acesso a objetos |
| `defineField()` | Estender objetos existentes com campos adicionais |
| Função | Finalidade |
| ---------------------------- | ------------------------------------------------------------ |
| `defineApplication()` | Configurar metadados do aplicativo (obrigatório, um por app) |
| `defineObject()` | Define objetos personalizados com campos |
| `defineLogicFunction()` | Defina funções de lógica com handlers |
| `defineFrontComponent()` | Definir componentes de front-end para UI personalizada |
| `defineRole()` | Configura permissões de papéis e acesso a objetos |
| `defineField()` | Estender objetos existentes com campos adicionais |
| `defineView()` | Define visualizações salvas para objetos |
| `defineNavigationMenuItem()` | Define links de navegação da barra lateral |
| `defineSkill()` | Define habilidades de agente de IA |
Essas funções validam sua configuração em tempo de compilação e oferecem autocompletar na IDE e segurança de tipos.
@@ -279,7 +312,11 @@ Pontos-chave:
* Você pode criar novos objetos usando `yarn twenty entity:add`, que orienta você sobre nomeação, campos e relacionamentos.
<Note>
**Os campos base são criados automaticamente.** Quando você define um objeto personalizado, o Twenty adiciona automaticamente campos padrão como `name`, `createdAt`, `updatedAt`, `createdBy`, `position` e `deletedAt`. Você não precisa definir esses no seu array `fields` — adicione apenas seus campos personalizados.
**Os campos base são criados automaticamente.** Quando você define um objeto personalizado, o Twenty adiciona automaticamente campos padrão
como `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` e `deletedAt`.
Você não precisa definir esses no seu array `fields` — adicione apenas seus campos personalizados.
Você pode substituir os campos padrão definindo um campo com o mesmo nome no seu array `fields`,
mas isso não é recomendado.
</Note>
### Configuração do aplicativo (application-config.ts)
@@ -289,6 +326,7 @@ Todo aplicativo tem um único arquivo `application-config.ts` que descreve:
* **O que é o aplicativo**: identificadores, nome de exibição e descrição.
* **Como suas funções são executadas**: qual papel usam para permissões.
* **Variáveis (opcional)**: pares chavevalor expostos às suas funções como variáveis de ambiente.
* **(Opcional) função de pós-instalação**: uma função de lógica que é executada após a instalação da aplicação.
Use `defineApplication()` to define your application configuration:
@@ -296,6 +334,7 @@ Use `defineApplication()` to define your application configuration:
// src/application-config.ts
import { defineApplication } from 'twenty-sdk';
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
@@ -311,6 +350,7 @@ export default defineApplication({
},
},
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
@@ -319,6 +359,7 @@ Notas:
* `universalIdentifier` são IDs determinísticos que você controla; gere-os uma vez e mantenha-os estáveis entre sincronizações.
* `applicationVariables` tornam-se variáveis de ambiente para suas funções (por exemplo, `DEFAULT_RECIPIENT_NAME` fica disponível como `process.env.DEFAULT_RECIPIENT_NAME`).
* `defaultRoleUniversalIdentifier` deve corresponder ao arquivo do papel (veja abaixo).
* `postInstallLogicFunctionUniversalIdentifier` (opcional) aponta para uma função de lógica que é executada automaticamente após a instalação da aplicação. Consulte [Funções de pós-instalação](#post-install-functions).
#### Papéis e permissões
@@ -457,6 +498,55 @@ Notas:
* O array `triggers` é opcional. Funções sem gatilhos podem ser usadas como funções utilitárias chamadas por outras funções.
* Você pode misturar vários tipos de gatilho em uma única função.
### Funções de pós-instalação
Uma função de pós-instalação é uma função de lógica que é executada automaticamente após a sua aplicação ser instalada em um espaço de trabalho. Isso é útil para tarefas de configuração únicas, como preencher dados padrão, criar registros iniciais ou configurar as configurações do espaço de trabalho.
Ao criar a estrutura de um novo app com `create-twenty-app`, uma função de pós-instalação é gerada para você em `src/logic-functions/post-install.ts`:
```typescript
// src/logic-functions/post-install.ts
import { defineLogicFunction } from 'twenty-sdk';
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
const handler = async (): Promise<void> => {
console.log('Post install logic function executed successfully!');
};
export default defineLogicFunction({
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
name: 'post-install',
description: 'Runs after installation to set up the application.',
timeoutSeconds: 300,
handler,
});
```
A função é conectada ao seu app referenciando seu identificador universal em `application-config.ts`:
```typescript
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
// ...
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
Você também pode executar manualmente a função de pós-instalação a qualquer momento usando a CLI:
```bash filename="Terminal"
yarn twenty function:execute --postInstall
```
Pontos-chave:
* As funções de pós-instalação são funções de lógica padrão — elas usam `defineLogicFunction()` como qualquer outra função.
* O campo `postInstallLogicFunctionUniversalIdentifier` em `defineApplication()` é opcional. Se omitido, nenhuma função é executada após a instalação.
* O tempo limite padrão é definido como 300 segundos (5 minutos) para permitir tarefas de configuração mais longas, como o pré-carregamento de dados.
* As funções de pós-instalação não precisam de gatilhos — elas são invocadas pela plataforma durante a instalação ou manualmente via `function:execute --postInstall`.
### Payload de gatilho de rota
<Warning>
@@ -554,6 +644,71 @@ Você pode criar novas funções de duas formas:
* **Gerado automaticamente**: Execute `yarn twenty entity:add` e escolha a opção para adicionar uma nova função de lógica. Isso gera um arquivo inicial com um handler e configuração.
* **Manual**: Crie um novo arquivo `*.logic-function.ts` e use `defineLogicFunction()`, seguindo o mesmo padrão.
### Marcar uma função lógica como ferramenta
Funções lógicas podem ser expostas como **ferramentas** para agentes de IA e fluxos de trabalho. Quando uma função é marcada como ferramenta, ela fica disponível para os recursos de IA do Twenty e pode ser selecionada como uma etapa em automações de fluxos de trabalho.
Para marcar uma função lógica como ferramenta, defina `isTool: true` e forneça um `toolInputSchema` descrevendo os parâmetros de entrada esperados usando [JSON Schema](https://json-schema.org/):
```typescript
// src/logic-functions/enrich-company.logic-function.ts
import { defineLogicFunction } from 'twenty-sdk';
import Twenty from '~/generated';
const handler = async (params: { companyName: string; domain?: string }) => {
const client = new Twenty();
const result = await client.mutation({
createTask: {
__args: {
data: {
title: `Enrich data for ${params.companyName}`,
body: `Domain: ${params.domain ?? 'unknown'}`,
},
},
id: true,
},
});
return { taskId: result.createTask.id };
};
export default defineLogicFunction({
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
name: 'enrich-company',
description: 'Enrich a company record with external data',
timeoutSeconds: 10,
handler,
isTool: true,
toolInputSchema: {
type: 'object',
properties: {
companyName: {
type: 'string',
description: 'The name of the company to enrich',
},
domain: {
type: 'string',
description: 'The company website domain (optional)',
},
},
required: ['companyName'],
},
});
```
Pontos-chave:
* **`isTool`** (`boolean`, padrão: `false`): Quando definido como `true`, a função é registrada como uma ferramenta e fica disponível para agentes de IA e automações de fluxos de trabalho.
* **`toolInputSchema`** (`object`, opcional): Um objeto JSON Schema que descreve os parâmetros que sua função aceita. Os agentes de IA usam esse esquema para entender quais entradas a ferramenta espera e para validar as chamadas. Se omitido, o esquema tem como padrão `{ type: 'object', properties: {} }` (sem parâmetros).
* Funções com `isTool: false` (ou não definido) **não** são expostas como ferramentas. Elas ainda podem ser executadas diretamente ou chamadas por outras funções, mas não aparecerão na descoberta de ferramentas.
* **Nomenclatura de ferramentas**: Quando exposta como uma ferramenta, o nome da função é automaticamente normalizado para `logic_function_<name>` (em minúsculas, caracteres não alfanuméricos substituídos por sublinhados). Por exemplo, `enrich-company` torna-se `logic_function_enrich_company`.
* Você pode combinar `isTool` com gatilhos — uma função pode ser ao mesmo tempo uma ferramenta (chamável por agentes de IA) e acionada por eventos (cron, eventos de banco de dados, rotas) simultaneamente.
<Note>
**Escreva uma boa `description`.** Os agentes de IA dependem do campo `description` da função para decidir quando usar a ferramenta. Seja específico sobre o que a ferramenta faz e quando ela deve ser chamada.
</Note>
### Componentes de front-end
Componentes de front-end permitem criar componentes React personalizados que são renderizados na UI do Twenty. Use `defineFrontComponent()` para definir componentes com validação integrada:
@@ -591,9 +746,44 @@ Você pode criar novos componentes de front-end de duas formas:
* **Gerado automaticamente**: Execute `yarn twenty entity:add` e escolha a opção para adicionar um novo componente de front-end.
* **Manual**: Crie um novo arquivo `*.front-component.tsx` e use `defineFrontComponent()`.
### Habilidades
As habilidades definem instruções e capacidades reutilizáveis que os agentes de IA podem usar no seu espaço de trabalho. Use `defineSkill()` para definir habilidades com validação integrada:
```typescript
// src/skills/example-skill.ts
import { defineSkill } from 'twenty-sdk';
export default defineSkill({
universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
name: 'sales-outreach',
label: 'Sales Outreach',
description: 'Guides the AI agent through a structured sales outreach process',
icon: 'IconBrain',
content: `You are a sales outreach assistant. When reaching out to a prospect:
1. Research the company and recent news
2. Identify the prospect's role and likely pain points
3. Draft a personalized message referencing specific details
4. Keep the tone professional but conversational`,
});
```
Pontos-chave:
* `name` é uma string de identificador exclusivo para a habilidade (recomenda-se kebab-case).
* `label` é o nome de exibição legível por humanos mostrado na UI.
* `content` contém as instruções da habilidade — este é o texto que o agente de IA usa.
* `icon` (opcional) define o ícone exibido na UI.
* `description` (opcional) fornece contexto adicional sobre a finalidade da habilidade.
Você pode criar novas habilidades de duas formas:
* **Gerado automaticamente**: Execute `yarn twenty entity:add` e escolha a opção para adicionar uma nova habilidade.
* **Manual**: Crie um novo arquivo e use `defineSkill()`, seguindo o mesmo padrão.
### Cliente tipado gerado
Execute `yarn twenty app:generate` para criar um cliente tipado local em `generated/` com base no esquema do seu espaço de trabalho. Use-o em suas funções:
O cliente tipado é gerado automaticamente pelo `yarn twenty app:dev` e armazenado em `node_modules/twenty-sdk/generated` com base no esquema do seu espaço de trabalho. Use-o em suas funções:
```typescript
import Twenty from '~/generated';
@@ -602,7 +792,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
O cliente é regenerado pelo `yarn twenty app:generate`. Execute novamente após alterar seus objetos ou ao ingressar em um novo workspace.
O cliente é regenerado automaticamente pelo `yarn twenty app:dev` sempre que seus objetos ou campos forem alterados.
#### Credenciais em tempo de execução em funções de lógica
@@ -617,6 +807,53 @@ Notas:
* As permissões da chave de API são determinadas pelo papel referenciado no seu `application-config.ts` via `defaultRoleUniversalIdentifier`. Este é o papel padrão usado pelas funções de lógica do seu app.
* Os aplicativos podem definir papéis para seguir o princípio do menor privilégio. Conceda apenas as permissões de que suas funções precisam e, em seguida, aponte `defaultRoleUniversalIdentifier` para o identificador universal desse papel.
#### Carregamento de ficheiros
O cliente `Twenty` gerado inclui um método `uploadFile` para anexar ficheiros a campos do tipo ficheiro nos objetos do seu espaço de trabalho. Como os clientes GraphQL padrão não suportam nativamente o carregamento de ficheiros multipart, o cliente fornece este método dedicado que implementa, nos bastidores, a [especificação de pedidos multipart do GraphQL](https://github.com/jaydenseric/graphql-multipart-request-spec).
```typescript
import Twenty from '~/generated';
import * as fs from 'fs';
const client = new Twenty();
const fileBuffer = fs.readFileSync('./invoice.pdf');
const uploadedFile = await client.uploadFile(
fileBuffer, // file contents as a Buffer
'invoice.pdf', // filename
'application/pdf', // MIME type (defaults to 'application/octet-stream')
'58a0a314-d7ea-4865-9850-7fb84e72f30b', // field universal identifier
);
console.log(uploadedFile);
// { id: '...', path: '...', size: 12345, createdAt: '...', url: 'https://...' }
```
A assinatura do método:
```typescript
uploadFile(
fileBuffer: Buffer,
filename: string,
contentType: string,
fieldMetadataUniversalIdentifier: string,
): Promise<{ id: string; path: string; size: number; createdAt: string; url: string }>
```
| Parâmetro | Tipo | Descrição |
| ---------------------------------- | -------- | ------------------------------------------------------------------------ |
| `fileBuffer` | `Buffer` | O conteúdo bruto do arquivo |
| `filename` | `string` | O nome do arquivo (usado para armazenamento e exibição) |
| `contentType` | `string` | Tipo MIME do arquivo (padrão para `application/octet-stream` se omitido) |
| `fieldMetadataUniversalIdentifier` | `string` | O `universalIdentifier` do campo do tipo arquivo no seu objeto |
Pontos-chave:
* O método envia o arquivo para o **endpoint de metadados** (não para o endpoint GraphQL principal), onde a mutação de upload é resolvida.
* Ele usa o `universalIdentifier` do campo (não o ID específico do espaço de trabalho), de modo que seu código de upload funcione em qualquer espaço de trabalho onde seu app esteja instalado — consistente com a forma como os apps referenciam campos em qualquer outro lugar.
* A `url` retornada é um URL assinado que você pode usar para acessar o arquivo enviado.
### Exemplo Hello World
Explore um exemplo mínimo de ponta a ponta que demonstra objetos, funções de lógica, componentes de front-end e vários gatilhos [aqui](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world):
@@ -639,13 +876,13 @@ Em seguida, adicione um script `twenty`:
}
```
Agora você pode executar todos os comandos via `yarn twenty <command>`, por exemplo, `yarn twenty app:dev`, `yarn twenty app:generate`, `yarn twenty help`, etc.
Agora você pode executar todos os comandos via `yarn twenty <command>`, por exemplo, `yarn twenty app:dev`, `yarn twenty help`, etc.
## Resolução de Problemas
* Erros de autenticação: execute `yarn twenty auth:login` e certifique-se de que sua chave de API tenha as permissões necessárias.
* Não é possível conectar ao servidor: verifique a URL da API e se o servidor do Twenty está acessível.
* Tipos ou cliente ausentes/desatualizados: execute `yarn twenty app:generate`.
* Tipos ou cliente ausentes/desatualizados: reinicie `yarn twenty app:dev` — ele gera automaticamente o cliente tipado.
* Modo de desenvolvimento não sincronizando: certifique-se de que `yarn twenty app:dev` esteja em execução e de que as alterações não estejam sendo ignoradas pelo seu ambiente.
Canal de ajuda no Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -15,6 +15,7 @@ Aplicațiile vă permit să construiți și să gestionați personalizările Twe
* Definiți obiecte și câmpuri personalizate sub formă de cod (model de date gestionat)
* Creați funcții de logică cu declanșatoare personalizate
* Definiți abilități pentru agenți de IA
* Implementați aceeași aplicație în mai multe spații de lucru
## Cerințe
@@ -27,7 +28,7 @@ Aplicațiile vă permit să construiți și să gestionați personalizările Twe
Creați o aplicație nouă folosind generatorul oficial, apoi autentificați-vă și începeți să dezvoltați:
```bash filename="Terminal"
# Creează scheletul unei aplicații noi
# Creează scheletul unei aplicații noi (include toate exemplele în mod implicit)
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
@@ -42,21 +43,34 @@ yarn twenty auth:login
yarn twenty app:dev
```
Generatorul de schelet acceptă trei moduri pentru a controla ce fișiere de exemplu sunt incluse:
```bash filename="Terminal"
# Implicit (exhaustiv): toate exemplele (obiect, câmp, funcție logică, componentă de interfață, vizualizare, element de meniu de navigare, abilitate)
npx create-twenty-app@latest my-app
# Minimal: doar fișierele de bază (application-config.ts și default-role.ts)
npx create-twenty-app@latest my-app --minimal
# Interactiv: selectezi ce exemple să incluzi
npx create-twenty-app@latest my-app --interactive
```
De aici puteți:
```bash filename="Terminal"
# Adaugă o entitate nouă în aplicația ta (ghidat)
yarn twenty entity:add
# Generează un client Twenty tipizat și tipurile de entități ale spațiului de lucru
yarn twenty app:generate
# Urmărește jurnalele funcțiilor aplicației tale
yarn twenty function:logs
# Execută o funcție după nume
yarn twenty function:execute -n my-function -p '{"name": "test"}'
# Execută funcția post-instalare
yarn twenty function:execute --postInstall
# Dezinstalează aplicația din spațiul de lucru curent
yarn twenty app:uninstall
@@ -73,9 +87,9 @@ Când rulați `npx create-twenty-app@latest my-twenty-app`, generatorul:
* Copiază o aplicație de bază minimală în `my-twenty-app/`
* Adaugă o dependență locală `twenty-sdk` și configurația Yarn 4
* Creează fișiere de configurare și scripturi conectate la CLI-ul `twenty`
* Generează o configurație implicită a aplicației și un rol implicit pentru funcții
* Generează fișierele de bază (configurația aplicației, rolul implicit al funcțiilor, funcția post-instalare) plus fișiere de exemplu în funcție de modul de generare a scheletului
O aplicație nou generată arată astfel:
O aplicație proaspăt generată cu modul implicit `--exhaustive` arată astfel:
```text filename="my-twenty-app/"
my-twenty-app/
@@ -89,17 +103,30 @@ my-twenty-app/
eslint.config.mjs
tsconfig.json
README.md
public/ # Public assets folder (images, fonts, etc.)
public/ # Director pentru resurse publice (imagini, fonturi etc.)
src/
├── application-config.ts # Required - main application configuration
├── application-config.ts # Obligatoriu - configurația principală a aplicației
├── roles/
│ └── default-role.ts # Default role for logic functions
│ └── default-role.ts # Rol implicit pentru funcțiile logice
├── objects/
│ └── example-object.ts # Exemplu de definiție a unui obiect personalizat
├── fields/
│ └── example-field.ts # Exemplu de definiție de câmp independent
├── logic-functions/
── hello-world.ts # Example logic function
└── front-components/
└── hello-world.tsx # Example front component
── hello-world.ts # Exemplu de funcție logică
└── post-install.ts # Funcție logică post-instalare
├── front-components/
│ └── hello-world.tsx # Exemplu de componentă de interfață
├── views/
│ └── example-view.ts # Exemplu de definiție a unei vizualizări salvate
├── navigation-menu-items/
│ └── example-navigation-menu-item.ts # Exemplu de link de navigare în bara laterală
└── skills/
└── example-skill.ts # Exemplu de definiție a unei abilități a agentului AI
```
Cu `--minimal`, sunt create doar fișierele de bază (`application-config.ts`, `roles/default-role.ts` și `logic-functions/post-install.ts`). Cu `--interactive`, alegi ce fișiere de exemplu să incluzi.
Pe scurt:
* **package.json**: Declară numele aplicației, versiunea, motoarele (Node 24+, Yarn 4) și adaugă `twenty-sdk` plus un script `twenty` care deleagă către CLI-ul local `twenty`. Rulează `yarn twenty help` pentru a lista toate comenzile disponibile.
@@ -115,13 +142,16 @@ Pe scurt:
SDK-ul detectează entitățile analizând fișierele TypeScript pentru apeluri **`export default define<Entity>({...})`**. Fiecare tip de entitate are o funcție ajutătoare corespunzătoare, exportată din `twenty-sdk`:
| Funcție ajutătoare | Tipul entității |
| ------------------------ | ------------------------------------------- |
| `defineObject()` | Definiții de obiecte personalizate |
| `defineLogicFunction()` | Definiții de funcții de logică |
| `defineFrontComponent()` | Definiții ale componentelor de interfață |
| `defineRole()` | Definiții de rol |
| `defineField()` | Extensii de câmp pentru obiectele existente |
| Funcție ajutătoare | Tipul entității |
| ---------------------------- | ---------------------------------------------- |
| `defineObject()` | Definiții de obiecte personalizate |
| `defineLogicFunction()` | Definiții de funcții de logică |
| `defineFrontComponent()` | Definiții ale componentelor de interfață |
| `defineRole()` | Definiții de rol |
| `defineField()` | Extensii de câmp pentru obiectele existente |
| `defineView()` | Definiții pentru vizualizări salvate |
| `defineNavigationMenuItem()` | Definiții pentru elemente de meniu de navigare |
| `defineSkill()` | Definiții ale abilităților agentului AI |
<Note>
**Denumirea fișierelor este flexibilă.** Detectarea entităților se bazează pe AST — SDK-ul scanează fișierele sursă pentru tiparul `export default define<Entity>({...})`. Puteți organiza fișierele și folderele cum doriți. Gruparea după tipul de entitate (de exemplu, `logic-functions/`, `roles/`) este doar o convenție pentru organizarea codului, nu o cerință.
@@ -142,8 +172,8 @@ export default defineObject({
Comenzile ulterioare vor adăuga mai multe fișiere și foldere:
* `yarn twenty app:generate` va crea un folder `generated/` (client Twenty tipizat + tipuri pentru spațiul de lucru).
* `yarn twenty entity:add` va adăuga fișiere de definire a entităților în `src/` pentru obiectele, funcțiile, componentele front-end sau rolurile personalizate.
* `yarn twenty app:dev` va genera automat un client API tipizat în `node_modules/twenty-sdk/generated` (client Twenty tipizat + tipuri ale spațiului de lucru).
* `yarn twenty entity:add` va adăuga fișiere de definire a entităților în `src/` pentru obiectele, funcțiile, componentele front-end, rolurile, abilitățile și altele.
## Autentificare
@@ -186,14 +216,17 @@ Biblioteca twenty-sdk oferă blocuri de bază tipizate și funcții ajutătoare
SDK-ul oferă funcții ajutătoare pentru definirea entităților aplicației. După cum este descris în [Detectarea entităților](#entity-detection), trebuie să folosiți `export default define<Entity>({...})` pentru ca entitățile să fie detectate:
| Funcție | Scop |
| ------------------------ | ---------------------------------------------------------------------- |
| `defineApplication()` | Configurați metadatele aplicației (obligatoriu, una per aplicație) |
| `defineObject()` | Definiți obiecte personalizate cu câmpuri |
| `defineLogicFunction()` | Definiți funcții de logică cu handleri |
| `defineFrontComponent()` | Definiți componente Front pentru interfața de utilizator personalizată |
| `defineRole()` | Configurați permisiunile rolurilor și accesul la obiecte |
| `defineField()` | Extindeți obiectele existente cu câmpuri suplimentare |
| Funcție | Scop |
| ---------------------------- | ---------------------------------------------------------------------- |
| `defineApplication()` | Configurați metadatele aplicației (obligatoriu, una per aplicație) |
| `defineObject()` | Definiți obiecte personalizate cu câmpuri |
| `defineLogicFunction()` | Definiți funcții de logică cu handleri |
| `defineFrontComponent()` | Definiți componente Front pentru interfața de utilizator personalizată |
| `defineRole()` | Configurați permisiunile rolurilor și accesul la obiecte |
| `defineField()` | Extindeți obiectele existente cu câmpuri suplimentare |
| `defineView()` | Definește vizualizări salvate pentru obiecte |
| `defineNavigationMenuItem()` | Definește linkuri de navigare în bara laterală |
| `defineSkill()` | Definiți abilități pentru agentul AI |
Aceste funcții validează configurația în timpul build-ului și oferă completare automată în IDE și siguranța tipurilor.
@@ -279,7 +312,11 @@ Puncte cheie:
* Puteți genera obiecte noi folosind `yarn twenty entity:add`, care vă ghidează prin denumire, câmpuri și relații.
<Note>
**Câmpurile de bază sunt create automat.** Când definiți un obiect personalizat, Twenty adaugă automat câmpuri standard precum `name`, `createdAt`, `updatedAt`, `createdBy`, `position` și `deletedAt`. Nu trebuie să le definiți în tabloul `fields` — adăugați doar câmpurile personalizate proprii.
**Câmpurile de bază sunt create automat.** Când definiți un obiect personalizat, Twenty adaugă automat câmpuri standard
precum `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` și `deletedAt`.
Nu trebuie să le definiți în tabloul `fields` — adăugați doar câmpurile personalizate proprii.
Puteți suprascrie câmpurile implicite definind un câmp cu același nume în tabloul `fields`,
dar acest lucru nu este recomandat.
</Note>
### Configurația aplicației (application-config.ts)
@@ -289,6 +326,7 @@ Fiecare aplicație are un singur fișier `application-config.ts` care descrie:
* **Cine este aplicația**: identificatori, nume de afișare și descriere.
* **Cum rulează funcțiile**: ce rol folosesc pentru permisiuni.
* **(Opțional) variabile**: perechi cheievaloare expuse funcțiilor ca variabile de mediu.
* **(Opțional) funcție post-instalare**: o funcție logică care rulează după instalarea aplicației.
Folosiți `defineApplication()` pentru a defini configurația aplicației:
@@ -296,6 +334,7 @@ Folosiți `defineApplication()` pentru a defini configurația aplicației:
// src/application-config.ts
import { defineApplication } from 'twenty-sdk';
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
@@ -311,6 +350,7 @@ export default defineApplication({
},
},
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
@@ -319,6 +359,7 @@ Notițe:
* Câmpurile `universalIdentifier` sunt ID-uri deterministe pe care le dețineți; generați-le o singură dată și păstrați-le stabile între sincronizări.
* `applicationVariables` devin variabile de mediu pentru funcțiile dvs. (de exemplu, `DEFAULT_RECIPIENT_NAME` este disponibil ca `process.env.DEFAULT_RECIPIENT_NAME`).
* `defaultRoleUniversalIdentifier` trebuie să corespundă fișierului de rol (vedeți mai jos).
* `postInstallLogicFunctionUniversalIdentifier` (opțional) indică o funcție logică care rulează automat după instalarea aplicației. Vezi [Funcții post-instalare](#post-install-functions).
#### Roluri și permisiuni
@@ -457,6 +498,55 @@ Notițe:
* Matricea `triggers` este opțională. Funcțiile fără declanșatoare pot fi folosite ca funcții utilitare apelate de alte funcții.
* Puteți combina mai multe tipuri de declanșatoare într-o singură funcție.
### Funcții post-instalare
O funcție post-instalare este o funcție logică care rulează automat după instalarea aplicației într-un spațiu de lucru. Aceasta este utilă pentru sarcini de configurare unice, cum ar fi popularea cu date implicite, crearea înregistrărilor inițiale sau configurarea setărilor spațiului de lucru.
Când creezi scheletul unei aplicații noi cu `create-twenty-app`, este generată o funcție post-instalare la `src/logic-functions/post-install.ts`:
```typescript
// src/logic-functions/post-install.ts
import { defineLogicFunction } from 'twenty-sdk';
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
const handler = async (): Promise<void> => {
console.log('Post install logic function executed successfully!');
};
export default defineLogicFunction({
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
name: 'post-install',
description: 'Runs after installation to set up the application.',
timeoutSeconds: 300,
handler,
});
```
Funcția este integrată în aplicația ta prin referirea la identificatorul său universal în `application-config.ts`:
```typescript
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
// ...
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
Poți, de asemenea, să execuți manual funcția post-instalare oricând folosind CLI:
```bash filename="Terminal"
yarn twenty function:execute --postInstall
```
Puncte cheie:
* Funcțiile post-instalare sunt funcții logice standard — folosesc `defineLogicFunction()` la fel ca orice altă funcție.
* Câmpul `postInstallLogicFunctionUniversalIdentifier` din `defineApplication()` este opțional. Dacă este omis, nu rulează nicio funcție după instalare.
* Timpul de expirare implicit este setat la 300 de secunde (5 minute) pentru a permite sarcini de configurare mai lungi, cum ar fi popularea datelor.
* Funcțiile post-instalare nu au nevoie de declanșatoare — sunt invocate de platformă în timpul instalării sau manual prin `function:execute --postInstall`.
### Payload-ul declanșatorului de rută
<Warning>
@@ -554,6 +644,71 @@ Puteți crea funcții noi în două moduri:
* **Generat**: Rulați `yarn twenty entity:add` și alegeți opțiunea de a adăuga o funcție logică nouă. Aceasta generează un fișier inițial cu un handler și o configurație.
* **Manual**: Creați un fișier nou `*.logic-function.ts` și folosiți `defineLogicFunction()`, urmând același model.
### Marcarea unei funcții logice drept instrument
Funcțiile logice pot fi expuse ca **instrumente** pentru agenți de IA și fluxuri de lucru. Când o funcție este marcată ca instrument, poate fi descoperită de funcționalitățile de IA ale Twenty și poate fi selectată ca pas în automatizări ale fluxurilor de lucru.
Pentru a marca o funcție logică drept instrument, setați `isTool: true` și furnizați un `toolInputSchema` care descrie parametrii de intrare așteptați folosind [JSON Schema](https://json-schema.org/):
```typescript
// src/logic-functions/enrich-company.logic-function.ts
import { defineLogicFunction } from 'twenty-sdk';
import Twenty from '~/generated';
const handler = async (params: { companyName: string; domain?: string }) => {
const client = new Twenty();
const result = await client.mutation({
createTask: {
__args: {
data: {
title: `Enrich data for ${params.companyName}`,
body: `Domain: ${params.domain ?? 'unknown'}`,
},
},
id: true,
},
});
return { taskId: result.createTask.id };
};
export default defineLogicFunction({
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
name: 'enrich-company',
description: 'Enrich a company record with external data',
timeoutSeconds: 10,
handler,
isTool: true,
toolInputSchema: {
type: 'object',
properties: {
companyName: {
type: 'string',
description: 'The name of the company to enrich',
},
domain: {
type: 'string',
description: 'The company website domain (optional)',
},
},
required: ['companyName'],
},
});
```
Puncte cheie:
* **`isTool`** (`boolean`, implicit: `false`): Când este setat la `true`, funcția este înregistrată ca instrument și devine disponibilă pentru agenții AI și automatizările de fluxuri de lucru.
* **`toolInputSchema`** (`object`, opțional): Un obiect JSON Schema care descrie parametrii pe care îi acceptă funcția dvs. Agenții AI folosesc această schemă pentru a înțelege ce intrări așteaptă instrumentul și pentru a valida apelurile. Dacă este omisă, schema are implicit valoarea `{ type: 'object', properties: {} }` (fără parametri).
* Funcțiile cu `isTool: false` (sau nedefinit) **nu** sunt expuse ca instrumente. Pot totuși fi executate direct sau apelate de alte funcții, dar nu vor apărea în descoperirea instrumentelor.
* **Denumierea instrumentelor**: Când este expusă ca instrument, denumirea funcției este normalizată automat la `logic_function_<name>` (convertită la litere mici, iar caracterele non-alfanumerice sunt înlocuite cu caractere de subliniere). De exemplu, `enrich-company` devine `logic_function_enrich_company`.
* Puteți combina `isTool` cu declanșatoare — o funcție poate fi atât un instrument (apelabilă de agenții AI), cât și declanșată de evenimente (cron, evenimente de bază de date, rute) în același timp.
<Note>
**Scrieți o `description` bună.** Agenții AI se bazează pe câmpul `description` al funcției pentru a decide când să folosească instrumentul. Fiți specifici cu privire la ceea ce face instrumentul și când ar trebui apelat.
</Note>
### Componente Front
Componentele Front vă permit să construiți componente React personalizate care sunt randate în interfața Twenty. Utilizați `defineFrontComponent()` pentru a defini componente cu validare încorporată:
@@ -591,9 +746,44 @@ Puteți crea componente Front noi în două moduri:
* **Generat**: Rulați `yarn twenty entity:add` și alegeți opțiunea de a adăuga o componentă frontend nouă.
* **Manual**: Creați un fișier nou `*.front-component.tsx` și folosiți `defineFrontComponent()`.
### Abilități
Abilitățile definesc instrucțiuni și capabilități reutilizabile pe care agenții AI le pot folosi în spațiul dvs. de lucru. Folosiți `defineSkill()` pentru a defini abilități cu validare încorporată:
```typescript
// src/skills/example-skill.ts
import { defineSkill } from 'twenty-sdk';
export default defineSkill({
universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
name: 'sales-outreach',
label: 'Abordare de vânzări',
description: 'Ghidează agentul AI printr-un proces structurat de abordare de vânzări',
icon: 'IconBrain',
content: `Ești un asistent pentru abordare de vânzări. Când contactezi un potențial client:
1. Cercetează compania și noutățile recente
2. Identifică rolul potențialului client și probabilele puncte sensibile
3. Redactează un mesaj personalizat care face referire la detalii specifice
4. Păstrează un ton profesionist, dar conversațional`,
});
```
Puncte cheie:
* `name` este un șir identificator unic pentru abilitate (se recomandă kebab-case).
* `label` este numele lizibil afișat în interfața cu utilizatorul (UI).
* `content` conține instrucțiunile abilității — acesta este textul pe care agentul AI îl folosește.
* `icon` (opțional) setează pictograma afișată în UI.
* `description` (opțional) oferă context suplimentar despre scopul abilității.
Puteți crea abilități noi în două moduri:
* **Generat**: Rulați `yarn twenty entity:add` și alegeți opțiunea de a adăuga o abilitate nouă.
* **Manual**: Creați un fișier nou și folosiți `defineSkill()`, urmând același model.
### Client tipizat generat
Rulați `yarn twenty app:generate` pentru a crea un client tipizat local în `generated/`, pe baza schemei spațiului de lucru. Folosiți-l în funcțiile dvs.:
Clientul tipizat este generat automat de `yarn twenty app:dev` și stocat în `node_modules/twenty-sdk/generated`, pe baza schemei spațiului tău de lucru. Folosiți-l în funcțiile dvs.:
```typescript
import Twenty from '~/generated';
@@ -602,7 +792,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
Clientul este regenerat de `yarn twenty app:generate`. Rulați din nou după ce vă modificați obiectele sau când vă integrați într-un spațiu de lucru nou.
Clientul este regenerat automat de `yarn twenty app:dev` ori de câte ori obiectele sau câmpurile tale se schimbă.
#### Acreditări la runtime în funcțiile de logică
@@ -617,6 +807,53 @@ Notițe:
* Permisiunile cheii API sunt determinate de rolul referențiat în `application-config.ts` prin `defaultRoleUniversalIdentifier`. Acesta este rolul implicit folosit de funcțiile de logică ale aplicației.
* Aplicațiile pot defini roluri pentru a urma principiul celui mai mic privilegiu. Acordați doar permisiunile de care au nevoie funcțiile, apoi setați `defaultRoleUniversalIdentifier` la identificatorul universal al acelui rol.
#### Încărcarea fișierelor
Clientul `Twenty` generat include o metodă `uploadFile` pentru atașarea fișierelor la câmpuri de tip fișier ale obiectelor din spațiul de lucru. Deoarece clienții GraphQL standard nu acceptă în mod nativ încărcarea fișierelor multipart, clientul oferă această metodă dedicată care implementează, sub capotă, [specificația cererilor GraphQL multipart](https://github.com/jaydenseric/graphql-multipart-request-spec).
```typescript
import Twenty from '~/generated';
import * as fs from 'fs';
const client = new Twenty();
const fileBuffer = fs.readFileSync('./invoice.pdf');
const uploadedFile = await client.uploadFile(
fileBuffer, // file contents as a Buffer
'invoice.pdf', // filename
'application/pdf', // MIME type (defaults to 'application/octet-stream')
'58a0a314-d7ea-4865-9850-7fb84e72f30b', // field universal identifier
);
console.log(uploadedFile);
// { id: '...', path: '...', size: 12345, createdAt: '...', url: 'https://...' }
```
Semnătura metodei:
```typescript
uploadFile(
fileBuffer: Buffer,
filename: string,
contentType: string,
fieldMetadataUniversalIdentifier: string,
): Promise<{ id: string; path: string; size: number; createdAt: string; url: string }>
```
| Parametru | Tip | Descriere |
| ---------------------------------- | -------- | ------------------------------------------------------------------------------------------- |
| `fileBuffer` | `Buffer` | Conținutul brut al fișierului |
| `filename` | `string` | Numele fișierului (folosit pentru stocare și afișare) |
| `contentType` | `string` | Tipul MIME al fișierului (are valoarea implicită `application/octet-stream` dacă este omis) |
| `fieldMetadataUniversalIdentifier` | `string` | `universalIdentifier` al câmpului de tip fișier de pe obiectul tău |
Puncte cheie:
* Metoda trimite fișierul către **metadata endpoint** (nu către endpoint-ul principal GraphQL), unde mutația de încărcare este rezolvată.
* Folosește `universalIdentifier` al câmpului (nu ID-ul specific spațiului de lucru), astfel încât codul tău de încărcare funcționează în orice spațiu de lucru în care aplicația ta este instalată — în concordanță cu modul în care aplicațiile fac referire la câmpuri în rest.
* `url` returnat este un URL semnat pe care îl poți folosi pentru a accesa fișierul încărcat.
### Exemplu Hello World
Explorați un exemplu minim, cap la cap, care demonstrează obiecte, funcții de logică, componente Front și declanșatoare multiple [aici](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world):
@@ -639,13 +876,13 @@ Apoi adăugați un script `twenty`:
}
```
Acum puteți rula toate comenzile prin `yarn twenty <command>`, de ex. `yarn twenty app:dev`, `yarn twenty app:generate`, `yarn twenty help`, etc.
Acum poți rula toate comenzile prin `yarn twenty <command>`, de ex. `yarn twenty app:dev`, `yarn twenty help`, etc.
## Depanare
* Erori de autentificare: rulați `yarn twenty auth:login` și asigurați-vă că cheia API are permisiunile necesare.
* Nu se poate conecta la server: verificați URL-ul API și că serverul Twenty este accesibil.
* Tipuri sau client lipsă/învechite: rulați `yarn twenty app:generate`.
* Types or client missing/outdated: restart `yarn twenty app:dev` — it auto-generates the typed client.
* Modul dev nu sincronizează: asigurați-vă că `yarn twenty app:dev` rulează și că modificările nu sunt ignorate de mediul dvs.
Canal de ajutor pe Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -15,6 +15,7 @@ description: Создавайте и управляйте настройками
* Определяйте пользовательские объекты и поля в виде кода (управляемая модель данных)
* Создавайте логические функции с пользовательскими триггерами
* Определите навыки для ИИ-агентов
* Развёртывайте одно и то же приложение в нескольких рабочих пространствах
## Требования
@@ -27,7 +28,7 @@ description: Создавайте и управляйте настройками
Создайте новое приложение с помощью официального генератора, затем выполните аутентификацию и начните разработку:
```bash filename="Terminal"
# Создать каркас нового приложения
# Создать каркас нового приложения (по умолчанию включает все примеры)
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
@@ -42,21 +43,34 @@ yarn twenty auth:login
yarn twenty app:dev
```
Генератор каркаса поддерживает три режима для управления тем, какие примерные файлы включаются:
```bash filename="Terminal"
# По умолчанию (полный набор): все примеры (объект, поле, логическая функция, фронтенд-компонент, представление, пункт меню навигации, навык)
npx create-twenty-app@latest my-app
# Минимальный: только основные файлы (application-config.ts и default-role.ts)
npx create-twenty-app@latest my-app --minimal
# Интерактивный: выбрать, какие примеры включить
npx create-twenty-app@latest my-app --interactive
```
Отсюда вы можете:
```bash filename="Terminal"
# Добавить новую сущность в ваше приложение (с мастером)
yarn twenty entity:add
# Сгенерировать типизированный клиент Twenty и типы сущностей рабочего пространства
yarn twenty app:generate
# Просматривать логи функций вашего приложения
yarn twenty function:logs
# Выполнить функцию по имени
yarn twenty function:execute -n my-function -p '{\"name\": \"test\"}'
# Выполнить послеустановочную функцию
yarn twenty function:execute --postInstall
# Удалить приложение из текущего рабочего пространства
yarn twenty app:uninstall
@@ -73,9 +87,9 @@ yarn twenty help
* Копирует минимальное базовое приложение в `my-twenty-app/`
* Добавляет локальную зависимость `twenty-sdk` и конфигурацию Yarn 4
* Создаёт файлы конфигурации и скрипты, подключённые к CLI `twenty`
* Генерирует конфигурацию приложения по умолчанию и роль функции по умолчанию
* Генерирует основные файлы (конфигурацию приложения, роль функций по умолчанию, постустановочную функцию), а также примерные файлы в зависимости от выбранного режима создания каркаса
Свежесгенерированное приложение выглядит так:
Сгенерированное с помощью каркаса приложение с режимом по умолчанию `--exhaustive` выглядит так:
```text filename="my-twenty-app/"
my-twenty-app/
@@ -89,17 +103,30 @@ my-twenty-app/
eslint.config.mjs
tsconfig.json
README.md
public/ # Папка общедоступных ресурсов (изображения, шрифты и т. п.)
public/ # Папка публичных ресурсов (изображения, шрифты и т. д.)
src/
├── application-config.ts # Обязательный — основная конфигурация приложения
├── roles/
│ └── default-role.ts # Роль по умолчанию для логических функций
├── objects/
│ └── example-object.ts # Пример определения пользовательского объекта
├── fields/
│ └── example-field.ts # Пример определения отдельного поля
├── logic-functions/
── hello-world.ts # Пример логической функции
└── front-components/
└── hello-world.tsx # Пример фронтенд-компонента
── hello-world.ts # Пример логической функции
└── post-install.ts # Постустановочная логическая функция
├── front-components/
│ └── hello-world.tsx # Пример фронтенд-компонента
├── views/
│ └── example-view.ts # Пример определения сохранённого представления
├── navigation-menu-items/
│ └── example-navigation-menu-item.ts # Пример ссылки боковой панели навигации
└── skills/
└── example-skill.ts # Пример определения навыка агента ИИ
```
С `--minimal` создаются только основные файлы (`application-config.ts`, `roles/default-role.ts` и `logic-functions/post-install.ts`). С `--interactive` вы выбираете, какие примерные файлы включить.
В общих чертах:
* **package.json**: Объявляет имя приложения, версию, движки (Node 24+, Yarn 4) и добавляет `twenty-sdk`, а также скрипт `twenty`, который делегирует выполнение локальному CLI `twenty`. Выполните `yarn twenty help`, чтобы вывести список всех доступных команд.
@@ -115,13 +142,16 @@ my-twenty-app/
SDK обнаруживает сущности, разбирая ваши файлы TypeScript в поисках вызовов **`export default define<Entity>({...})`**. Для каждого типа сущности существует соответствующая вспомогательная функция, экспортируемая из `twenty-sdk`:
| Вспомогательная функция | Тип сущности |
| ------------------------ | ------------------------------------------ |
| `defineObject()` | Определения пользовательских объектов |
| `defineLogicFunction()` | Определения логических функций |
| `defineFrontComponent()` | Определения компонентов фронтенда |
| `defineRole()` | Определения ролей |
| `defineField()` | Расширения полей для существующих объектов |
| Вспомогательная функция | Тип сущности |
| ---------------------------- | ------------------------------------------ |
| `defineObject()` | Определения пользовательских объектов |
| `defineLogicFunction()` | Определения логических функций |
| `defineFrontComponent()` | Определения компонентов фронтенда |
| `defineRole()` | Определения ролей |
| `defineField()` | Расширения полей для существующих объектов |
| `defineView()` | Определения сохранённых представлений |
| `defineNavigationMenuItem()` | Определения пунктов меню навигации |
| `defineSkill()` | Определения навыков агента ИИ |
<Note>
**Имена файлов заданы гибко.** Обнаружение сущностей основано на AST — SDK сканирует ваши исходные файлы в поисках шаблона `export default define<Entity>({...})`. Вы можете организовывать файлы и папки как угодно. Группировка по типу сущности (например, `logic-functions/`, `roles/`) — это лишь соглашение для организации кода, а не требование.
@@ -142,8 +172,8 @@ export default defineObject({
Позднее команды добавят больше файлов и папок:
* `yarn twenty app:generate` создаст папку `generated/` (типизированный клиент Twenty + типы рабочего пространства).
* `yarn twenty entity:add` добавит файлы определений сущностей в `src/` для ваших пользовательских объектов, функций, фронтенд-компонентов или ролей.
* `yarn twenty app:dev` автоматически сгенерирует типизированный клиент API в `node_modules/twenty-sdk/generated` (типизированный клиент Twenty + типы рабочего пространства).
* `yarn twenty entity:add` добавит файлы определений сущностей в `src/` для ваших пользовательских объектов, функций, фронтенд-компонентов, ролей, навыков и многого другого.
## Аутентификация
@@ -186,14 +216,17 @@ yarn twenty auth:status
SDK предоставляет вспомогательные функции для определения сущностей вашего приложения. Как описано в [Обнаружение сущностей](#entity-detection), вы должны использовать `export default define<Entity>({...})`, чтобы ваши сущности были обнаружены:
| Функция | Назначение |
| ------------------------ | ---------------------------------------------------------------------- |
| `defineApplication()` | Настройка метаданных приложения (обязательно, по одному на приложение) |
| `defineObject()` | Определяет пользовательские объекты с полями |
| `defineLogicFunction()` | Определение логических функций с обработчиками |
| `defineFrontComponent()` | Определение фронт-компонентов для настраиваемого интерфейса |
| `defineRole()` | Настраивает права роли и доступ к объектам |
| `defineField()` | Расширение существующих объектов дополнительными полями |
| Функция | Назначение |
| ---------------------------- | ---------------------------------------------------------------------- |
| `defineApplication()` | Настройка метаданных приложения (обязательно, по одному на приложение) |
| `defineObject()` | Определяет пользовательские объекты с полями |
| `defineLogicFunction()` | Определение логических функций с обработчиками |
| `defineFrontComponent()` | Определение фронт-компонентов для настраиваемого интерфейса |
| `defineRole()` | Настраивает права роли и доступ к объектам |
| `defineField()` | Расширение существующих объектов дополнительными полями |
| `defineView()` | Определяйте сохранённые представления для объектов |
| `defineNavigationMenuItem()` | Определяйте ссылки боковой панели навигации |
| `defineSkill()` | Определение навыков агента ИИ |
Эти функции проверяют вашу конфигурацию на этапе сборки и обеспечивают автодополнение в IDE и безопасность типов.
@@ -279,7 +312,11 @@ export default defineObject({
* Вы можете сгенерировать новые объекты с помощью `yarn twenty entity:add`, который проведёт вас через настройку имени, полей и связей.
<Note>
**Базовые поля создаются автоматически.** Когда вы определяете пользовательский объект, Twenty автоматически добавляет стандартные поля, такие как `name`, `createdAt`, `updatedAt`, `createdBy`, `position` и `deletedAt`. Вам не нужно определять их в массиве `fields` — добавляйте только свои пользовательские поля.
**Базовые поля создаются автоматически.** Когда вы определяете пользовательский объект, Twenty автоматически добавляет стандартные поля,
такие как `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` и `deletedAt`.
Вам не нужно определять их в массиве `fields` — добавляйте только свои пользовательские поля.
Вы можете переопределить поля по умолчанию, определив поле с тем же именем в массиве `fields`,
но это не рекомендуется.
</Note>
### Конфигурация приложения (application-config.ts)
@@ -289,6 +326,7 @@ export default defineObject({
* **Что это за приложение**: идентификаторы, отображаемое имя и описание.
* **Как запускаются его функции**: какую роль они используют для прав доступа.
* **(Необязательно) переменные**: пары ключ-значение, предоставляемые вашим функциям как переменные окружения.
* **(Необязательно) послеустановочная функция**: функция логики, которая запускается после установки приложения.
Используйте `defineApplication()` для определения конфигурации вашего приложения:
@@ -296,6 +334,7 @@ export default defineObject({
// src/application-config.ts
import { defineApplication } from 'twenty-sdk';
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
@@ -311,6 +350,7 @@ export default defineApplication({
},
},
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
@@ -319,6 +359,7 @@ export default defineApplication({
* `universalIdentifier` — это детерминированные идентификаторы, которыми вы управляете; сгенерируйте их один раз и сохраняйте стабильными между синхронизациями.
* `applicationVariables` становятся переменными окружения для ваших функций (например, `DEFAULT_RECIPIENT_NAME` доступна как `process.env.DEFAULT_RECIPIENT_NAME`).
* `defaultRoleUniversalIdentifier` должен соответствовать файлу роли (см. ниже).
* `postInstallLogicFunctionUniversalIdentifier` (необязательно) указывает на логическую функцию, которая автоматически выполняется после установки приложения. См. [Послеустановочные функции](#post-install-functions).
#### Роли и разрешения
@@ -457,6 +498,55 @@ export default defineLogicFunction({
* Массив `triggers` необязателен. Функции без триггеров можно использовать как вспомогательные, вызываемые другими функциями.
* Вы можете сочетать несколько типов триггеров в одной функции.
### Послеустановочные функции
Послеустановочная функция — это функция логики, которая автоматически выполняется после установки вашего приложения в рабочем пространстве. Это полезно для одноразовых задач настройки, таких как инициализация данных по умолчанию, создание начальных записей или настройка параметров рабочего пространства.
Когда вы создаёте каркас нового приложения с помощью `create-twenty-app`, для вас генерируется постустановочная функция по пути `src/logic-functions/post-install.ts`:
```typescript
// src/logic-functions/post-install.ts
import { defineLogicFunction } from 'twenty-sdk';
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
const handler = async (): Promise<void> => {
console.log('Post install logic function executed successfully!');
};
export default defineLogicFunction({
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
name: 'post-install',
description: 'Runs after installation to set up the application.',
timeoutSeconds: 300,
handler,
});
```
Функция подключается к вашему приложению посредством ссылки на её универсальный идентификатор в `application-config.ts`:
```typescript
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
// ...
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
Вы также можете вручную выполнить постустановочную функцию в любое время с помощью CLI:
```bash filename="Terminal"
yarn twenty function:execute --postInstall
```
Основные моменты:
* Постустановочные функции — это стандартные логические функции: они используют `defineLogicFunction()` как и любые другие функции.
* Поле `postInstallLogicFunctionUniversalIdentifier` в `defineApplication()` является необязательным. Если его опустить, после установки никакая функция выполняться не будет.
* Тайм-аут по умолчанию установлен на 300 секунд (5 минут), чтобы позволить выполнять более длительные задачи настройки, такие как инициализация данных.
* Постустановочным функциям не нужны триггеры — платформа вызывает их во время установки или вручную через `function:execute --postInstall`.
### Полезная нагрузка триггера маршрута
<Warning>
@@ -554,6 +644,71 @@ const handler = async (event: RoutePayload) => {
* **Сгенерировано**: Запустите `yarn twenty entity:add` и выберите опцию добавления новой функции логики. Это создаёт стартовый файл с обработчиком и конфигурацией.
* **Вручную**: Создайте новый файл `*.logic-function.ts` и используйте `defineLogicFunction()`, следуя тому же шаблону.
### Пометка логической функции как инструмента
Логические функции можно предоставлять как **инструменты** для ИИ-агентов и рабочих процессов. Когда функция помечена как инструмент, она становится доступной для ИИ Twenty и может быть выбрана в качестве шага в автоматизациях рабочих процессов.
Чтобы пометить логическую функцию как инструмент, установите `isTool: true` и укажите `toolInputSchema` для описания ожидаемых входных параметров с помощью [схемы JSON](https://json-schema.org/):
```typescript
// src/logic-functions/enrich-company.logic-function.ts
import { defineLogicFunction } from 'twenty-sdk';
import Twenty from '~/generated';
const handler = async (params: { companyName: string; domain?: string }) => {
const client = new Twenty();
const result = await client.mutation({
createTask: {
__args: {
data: {
title: `Enrich data for ${params.companyName}`,
body: `Domain: ${params.domain ?? 'unknown'}`,
},
},
id: true,
},
});
return { taskId: result.createTask.id };
};
export default defineLogicFunction({
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
name: 'enrich-company',
description: 'Enrich a company record with external data',
timeoutSeconds: 10,
handler,
isTool: true,
toolInputSchema: {
type: 'object',
properties: {
companyName: {
type: 'string',
description: 'The name of the company to enrich',
},
domain: {
type: 'string',
description: 'The company website domain (optional)',
},
},
required: ['companyName'],
},
});
```
Основные моменты:
* **`isTool`** (`boolean`, по умолчанию: `false`): Если значение равно `true`, функция регистрируется как инструмент и становится доступной агентам ИИ и автоматизациям рабочих процессов.
* **`toolInputSchema`** (`object`, необязательно): Объект JSON Schema, который описывает параметры, которые принимает ваша функция. Агенты ИИ используют эту схему, чтобы понять, какие входные данные ожидает инструмент, и проверять корректность вызовов. Если опущено, по умолчанию используется схема `{ type: 'object', properties: {} }` (без параметров).
* Функции с `isTool: false` (или без указания) **не** выставляются как инструменты. Их по-прежнему можно выполнять напрямую или вызывать из других функций, но они не будут отображаться при обнаружении инструментов.
* **Именование инструмента**: При публикации как инструмента имя функции автоматически нормализуется до `logic_function_<name>` (в нижнем регистре, небуквенно-цифровые символы заменяются на подчёркивания). Например, `enrich-company` становится `logic_function_enrich_company`.
* Вы можете комбинировать `isTool` с триггерами — функция может одновременно быть инструментом (вызываемым агентами ИИ) и запускаться событиями (cron, события базы данных, маршруты).
<Note>
**Напишите хорошее описание в поле `description`.** Агенты ИИ опираются на поле `description` функции, чтобы решить, когда использовать инструмент. Чётко опишите, что делает инструмент и когда его следует вызывать.
</Note>
### Фронт-компоненты
Фронт-компоненты позволяют создавать пользовательские компоненты React, которые рендерятся внутри интерфейса Twenty. Используйте `defineFrontComponent()` для определения компонентов со встроенной валидацией:
@@ -591,9 +746,44 @@ export default defineFrontComponent({
* **Сгенерировано**: Запустите `yarn twenty entity:add` и выберите опцию добавления нового фронтенд-компонента.
* **Вручную**: Создайте новый файл `*.front-component.tsx` и используйте `defineFrontComponent()`.
### Навыки
Навыки определяют многократно используемые инструкции и возможности, которые агенты ИИ могут использовать в вашем рабочем пространстве. Используйте `defineSkill()` для определения навыков со встроенной валидацией:
```typescript
// src/skills/example-skill.ts
import { defineSkill } from 'twenty-sdk';
export default defineSkill({
universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
name: 'sales-outreach',
label: 'Sales Outreach',
description: 'Guides the AI agent through a structured sales outreach process',
icon: 'IconBrain',
content: `You are a sales outreach assistant. When reaching out to a prospect:
1. Research the company and recent news
2. Identify the prospect's role and likely pain points
3. Draft a personalized message referencing specific details
4. Keep the tone professional but conversational`,
});
```
Основные моменты:
* `name` — уникальная строка-идентификатор навыка (рекомендуется kebab-case).
* `label` — читаемое человеком отображаемое имя, показываемое в UI.
* `content` содержит инструкции навыка — это текст, который использует агент ИИ.
* `icon` (необязательно) задаёт значок, отображаемый в UI.
* `description` (необязательно) предоставляет дополнительный контекст о назначении навыка.
Вы можете создать новые навыки двумя способами:
* **Сгенерировано**: Запустите `yarn twenty entity:add` и выберите опцию добавления нового навыка.
* **Вручную**: Создайте новый файл и используйте `defineSkill()`, следуя тому же шаблону.
### Сгенерированный типизированный клиент
Запустите `yarn twenty app:generate`, чтобы создать локальный типизированный клиент в `generated/` на основе схемы вашего рабочего пространства. Используйте его в своих функциях:
Типизированный клиент автоматически генерируется с помощью `yarn twenty app:dev` и сохраняется в `node_modules/twenty-sdk/generated` на основе схемы вашего рабочего пространства. Используйте его в своих функциях:
```typescript
import Twenty from '~/generated';
@@ -602,7 +792,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
Клиент повторно генерируется командой `yarn twenty app:generate`. Запускайте повторно после изменения ваших объектов или при подключении к новому рабочему пространству.
Клиент автоматически перегенерируется с помощью `yarn twenty app:dev` при изменении ваших объектов или полей.
#### Учётные данные времени выполнения в логических функциях
@@ -617,6 +807,53 @@ const { me } = await client.query({ me: { id: true, displayName: true } });
* Права ключа API определяются ролью, на которую ссылается ваш `application-config.ts` через `defaultRoleUniversalIdentifier`. Это роль по умолчанию, используемая логическими функциями вашего приложения.
* Приложения могут определять роли, чтобы следовать принципу наименьших привилегий. Предоставляйте только те права, которые нужны вашим функциям, затем укажите в `defaultRoleUniversalIdentifier` универсальный идентификатор этой роли.
#### Загрузка файлов
Сгенерированный клиент `Twenty` включает метод `uploadFile` для прикрепления файлов к полям типа «файл» в объектах вашего рабочего пространства. Поскольку стандартные клиенты GraphQL изначально не поддерживают многочастовую загрузку файлов, клиент предоставляет специальный метод, который под капотом реализует [спецификацию многочастных запросов GraphQL](https://github.com/jaydenseric/graphql-multipart-request-spec).
```typescript
import Twenty from '~/generated';
import * as fs from 'fs';
const client = new Twenty();
const fileBuffer = fs.readFileSync('./invoice.pdf');
const uploadedFile = await client.uploadFile(
fileBuffer, // file contents as a Buffer
'invoice.pdf', // filename
'application/pdf', // MIME type (defaults to 'application/octet-stream')
'58a0a314-d7ea-4865-9850-7fb84e72f30b', // field universal identifier
);
console.log(uploadedFile);
// { id: '...', path: '...', size: 12345, createdAt: '...', url: 'https://...' }
```
Сигнатура метода:
```typescript
uploadFile(
fileBuffer: Buffer,
filename: string,
contentType: string,
fieldMetadataUniversalIdentifier: string,
): Promise<{ id: string; path: string; size: number; createdAt: string; url: string }>
```
| Параметр | Тип | Описание |
| ---------------------------------- | -------- | ------------------------------------------------------------------------ |
| `fileBuffer` | `Buffer` | Необработанное содержимое файла |
| `filename` | `строка` | Имя файла (используется для хранения и отображения) |
| `contentType` | `строка` | Тип MIME файла (по умолчанию `application/octet-stream`, если не указан) |
| `fieldMetadataUniversalIdentifier` | `строка` | Значение `universalIdentifier` для поля типа файла в вашем объекте |
Основные моменты:
* Метод отправляет файл на **metadata endpoint** (не на основной GraphQL endpoint), где обрабатывается мутация загрузки.
* Он использует `universalIdentifier` поля (а не его идентификатор, специфичный для рабочего пространства), поэтому ваш код загрузки будет работать в любом рабочем пространстве, где установлено ваше приложение — в соответствии с тем, как приложения ссылаются на поля повсюду.
* Возвращаемый `url` — это подписанный URL, который можно использовать для доступа к загруженному файлу.
### Пример Hello World
Ознакомьтесь с минимальным сквозным примером, демонстрирующим объекты, логические функции, фронт-компоненты и несколько триггеров, [здесь](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world):
@@ -639,13 +876,13 @@ yarn add -D twenty-sdk
}
```
Теперь вы можете запускать все команды через `yarn twenty <command>`, например, `yarn twenty app:dev`, `yarn twenty app:generate`, `yarn twenty help` и т. д.
Теперь вы можете запускать все команды через `yarn twenty <command>`, например, `yarn twenty app:dev`, `yarn twenty help` и т. д.
## Устранение неполадок
* Ошибки аутентификации: выполните `yarn twenty auth:login` и убедитесь, что у вашего ключа API есть необходимые права.
* Не удаётся подключиться к серверу: проверьте URL API и доступность сервера Twenty.
* Типы или клиент отсутствуют/устарели: выполните `yarn twenty app:generate`.
* Types or client missing/outdated: restart `yarn twenty app:dev` — it auto-generates the typed client.
* Режим разработки не синхронизируется: убедитесь, что запущен `yarn twenty app:dev`, и что ваша среда не игнорирует изменения.
Канал помощи в Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -15,6 +15,7 @@ Uygulamalar, Twenty özelleştirmelerini **kod olarak** oluşturup yönetmenizi
* Özel nesneleri ve alanları kod olarak tanımlayın (yönetilen veri modeli)
* Özel tetikleyicilerle mantık fonksiyonları oluşturun
* Yapay zekâ ajanları için becerileri tanımlayın
* Aynı uygulamayı birden çok çalışma alanına dağıtın
## Ön Gereksinimler
@@ -27,7 +28,7 @@ Uygulamalar, Twenty özelleştirmelerini **kod olarak** oluşturup yönetmenizi
Resmi scaffolder aracını kullanarak yeni bir uygulama oluşturun, ardından kimlik doğrulaması yapıp geliştirmeye başlayın:
```bash filename="Terminal"
# Scaffold a new app
# Scaffold a new app (includes all examples by default)
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
@@ -42,21 +43,34 @@ yarn twenty auth:login
yarn twenty app:dev
```
İskelet oluşturucu, hangi örnek dosyaların dahil edileceğini kontrol etmek için üç modu destekler:
```bash filename="Terminal"
# Varsayılan (kapsamlı): tüm örnekler (nesne, alan, mantık fonksiyonu, ön bileşen, görünüm, gezinme menüsü öğesi, yetenek)
npx create-twenty-app@latest my-app
# Minimal: yalnızca çekirdek dosyalar (application-config.ts ve default-role.ts)
npx create-twenty-app@latest my-app --minimal
# Etkileşimli: dahil edilecek örnekleri seçin
npx create-twenty-app@latest my-app --interactive
```
Buradan şunları yapabilirsiniz:
```bash filename="Terminal"
# Add a new entity to your application (guided)
yarn twenty entity:add
# Generate a typed Twenty client and workspace entity types
yarn twenty app:generate
# Watch your application's function logs
yarn twenty function:logs
# Execute a function by name
yarn twenty function:execute -n my-function -p '{"name": "test"}'
# Execute the post-install function
yarn twenty function:execute --postInstall
# Uninstall the application from the current workspace
yarn twenty app:uninstall
@@ -73,9 +87,9 @@ Ayrıca bkz.: [create-twenty-app](https://www.npmjs.com/package/create-twenty-ap
* Minimal bir temel uygulamayı `my-twenty-app/` içine kopyalar
* Yerel bir `twenty-sdk` bağımlılığı ve Yarn 4 yapılandırması ekler
* `twenty` CLI ile bağlantılı yapılandırma dosyaları ve betikler oluşturur
* Varsayılan bir uygulama yapılandırması ve varsayılan bir fonksiyon rolü üretir
* İskelet oluşturma moduna bağlı olarak çekirdek dosyaları (uygulama yapılandırması, varsayılan işlev rolü, kurulum sonrası işlev) ile örnek dosyaları üretir
Yeni şablondan oluşturulan bir uygulama şöyle görünür:
Varsayılan `--exhaustive` moduyla yeni oluşturulmuş bir uygulama şu şekilde görünür:
```text filename="my-twenty-app/"
my-twenty-app/
@@ -93,13 +107,26 @@ my-twenty-app/
src/
├── application-config.ts # Gerekli - ana uygulama yapılandırması
├── roles/
│ └── default-role.ts # Mantık işlevleri için varsayılan rol
│ └── default-role.ts # Mantık fonksiyonları için varsayılan rol
├── objects/
│ └── example-object.ts # Örnek özel nesne tanımı
├── fields/
│ └── example-field.ts # Örnek bağımsız alan tanımı
├── logic-functions/
── hello-world.ts # Örnek mantık işlevi
└── front-components/
└── hello-world.tsx # Örnek ön uç bileşeni
── hello-world.ts # Örnek mantık fonksiyonu
└── post-install.ts # Kurulum sonrası mantık fonksiyonu
├── front-components/
│ └── hello-world.tsx # Örnek ön bileşen
├── views/
│ └── example-view.ts # Örnek kaydedilmiş görünüm tanımı
├── navigation-menu-items/
│ └── example-navigation-menu-item.ts # Örnek kenar çubuğu gezinme bağlantısı
└── skills/
└── example-skill.ts # Örnek yapay zekâ ajanı yetenek tanımı
```
`--minimal` ile yalnızca çekirdek dosyalar oluşturulur (`application-config.ts`, `roles/default-role.ts` ve `logic-functions/post-install.ts`). `--interactive` ile hangi örnek dosyaların dahil edileceğini siz seçersiniz.
Genel hatlarıyla:
* **package.json**: Uygulama adını, sürümünü, motorları (Node 24+, Yarn 4) bildirir ve `twenty-sdk` ile yerel `twenty` CLI'sine yetki devreden bir `twenty` betiği ekler. Tüm mevcut komutları listelemek için `yarn twenty help` komutunu çalıştırın.
@@ -115,13 +142,16 @@ Genel hatlarıyla:
SDK, TypeScript dosyalarınızı **`export default define<Entity>({...})`** çağrılarını arayarak ayrıştırıp varlıkları algılar. Her varlık türünün, `twenty-sdk` tarafından dışa aktarılan karşılık gelen bir yardımcı fonksiyonu vardır:
| Yardımcı fonksiyon | Varlık türü |
| ------------------------ | ---------------------------------------- |
| `defineObject()` | Özel nesne tanımları |
| `defineLogicFunction()` | Mantık fonksiyon tanımları |
| `defineFrontComponent()` | Front component definitions |
| `defineRole()` | Rol tanımları |
| `defineField()` | Mevcut nesneler için alan genişletmeleri |
| Yardımcı fonksiyon | Varlık türü |
| ---------------------------- | ---------------------------------------- |
| `defineObject()` | Özel nesne tanımları |
| `defineLogicFunction()` | Mantık fonksiyon tanımları |
| `defineFrontComponent()` | Front component definitions |
| `defineRole()` | Rol tanımları |
| `defineField()` | Mevcut nesneler için alan genişletmeleri |
| `defineView()` | Kaydedilmiş görünüm tanımları |
| `defineNavigationMenuItem()` | Gezinme menüsü öğesi tanımları |
| `defineSkill()` | Yapay zekâ ajanı yetenek tanımları |
<Note>
**Dosya adlandırma esnektir.** Varlık algılama AST tabanlıdır — SDK, kaynak dosyalarınızı `export default define<Entity>({...})` desenini bulmak için tarar. Dosyalarınızı ve klasörlerinizi dilediğiniz gibi düzenleyebilirsiniz. Varlık türüne göre gruplama (örn. `logic-functions/`, `roles/`) bir gereklilik değil, yalnızca kod organizasyonu için bir gelenektir.
@@ -142,8 +172,8 @@ export default defineObject({
İlerideki komutlar daha fazla dosya ve klasör ekleyecektir:
* `yarn twenty app:generate`, `generated/` klasörünü oluşturur (türlendirilmiş Twenty istemcisi + çalışma alanı türleri).
* `yarn twenty entity:add`, özel nesneleriniz, fonksiyonlarınız, ön bileşenleriniz veya rolleriniz için `src/` altında varlık tanım dosyaları ekler.
* `yarn twenty app:dev`, `node_modules/twenty-sdk/generated` içinde tipli bir API istemcisini otomatik olarak oluşturur (tipli Twenty istemcisi + çalışma alanı türleri).
* `yarn twenty entity:add`, özel nesneleriniz, fonksiyonlarınız, ön bileşenleriniz, rolleriniz, yetenekleriniz ve daha fazlası için `src/` altında varlık tanım dosyaları ekler.
## Kimlik Doğrulama
@@ -186,14 +216,17 @@ twenty-sdk, uygulamanız içinde kullandığınız türlendirilmiş yapı taşla
SDK, uygulama varlıklarınızı tanımlamak için yardımcı fonksiyonlar sağlar. [Varlık algılama](#entity-detection) bölümünde açıklandığı gibi, varlıklarınızın algılanması için `export default define<Entity>({...})` kullanmalısınız:
| Fonksiyon | Amaç |
| ------------------------ | ------------------------------------------------------------------------- |
| `defineApplication()` | Uygulama meta verilerini yapılandırın (zorunlu, uygulama başına bir adet) |
| `defineObject()` | Alanlara sahip özel nesneler tanımlayın |
| `defineLogicFunction()` | İşleyicilerle mantık fonksiyonları tanımlayın |
| `defineFrontComponent()` | Özel kullanıcı arayüzü için ön uç bileşenlerini tanımlayın |
| `defineRole()` | Rol izinlerini ve nesne erişimini yapılandırın |
| `defineField()` | Mevcut nesneleri ek alanlarla genişletin |
| Fonksiyon | Amaç |
| ---------------------------- | ------------------------------------------------------------------------- |
| `defineApplication()` | Uygulama meta verilerini yapılandırın (zorunlu, uygulama başına bir adet) |
| `defineObject()` | Alanlara sahip özel nesneler tanımlayın |
| `defineLogicFunction()` | İşleyicilerle mantık fonksiyonları tanımlayın |
| `defineFrontComponent()` | Özel kullanıcı arayüzü için ön uç bileşenlerini tanımlayın |
| `defineRole()` | Rol izinlerini ve nesne erişimini yapılandırın |
| `defineField()` | Mevcut nesneleri ek alanlarla genişletin |
| `defineView()` | Nesneler için kaydedilmiş görünümler tanımlayın |
| `defineNavigationMenuItem()` | Kenar çubuğu gezinme bağlantılarını tanımlayın |
| `defineSkill()` | Yapay zekâ ajanı yeteneklerini tanımlayın |
Bu fonksiyonlar, derleme zamanında yapılandırmanızı doğrular ve IDE otomatik tamamlama ile tür güvenliği sağlar.
@@ -279,7 +312,11 @@ export default defineObject({
* `yarn twenty entity:add` kullanarak, adlandırma, alanlar ve ilişkiler konusunda sizi yönlendirerek yeni nesneler oluşturabilirsiniz.
<Note>
**Temel alanlar otomatik olarak oluşturulur.** Özel bir nesne tanımladığınızda Twenty, `name`, `createdAt`, `updatedAt`, `createdBy`, `position` ve `deletedAt` gibi standart alanları otomatik olarak ekler. Bunları `fields` dizinizde tanımlamanız gerekmez — yalnızca özel alanlarınızı ekleyin.
**Temel alanlar otomatik olarak oluşturulur.** Özel bir nesne tanımladığınızda Twenty, standart alanları otomatik olarak ekler
örneğin `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` ve `deletedAt`.
Bunları `fields` dizinizde tanımlamanız gerekmez — yalnızca özel alanlarınızı ekleyin.
`fields` dizinizde aynı ada sahip bir alan tanımlayarak varsayılan alanları geçersiz kılabilirsiniz,
ancak bu önerilmez.
</Note>
### Uygulama yapılandırması (application-config.ts)
@@ -289,6 +326,7 @@ Her uygulamanın aşağıdakileri açıklayan tek bir `application-config.ts` do
* **Uygulamanın kim olduğu**: tanımlayıcılar, görünen ad ve açıklama.
* **Fonksiyonlarının nasıl çalıştığı**: izinler için hangi rolü kullandıkları.
* **(İsteğe bağlı) değişkenler**: fonksiyonlarınıza ortam değişkenleri olarak sunulan anahtardeğer çiftleri.
* **(İsteğe bağlı) kurulum sonrası işlev**: uygulama yüklendikten sonra çalışan bir mantık işlevi.
Uygulama yapılandırmanızı tanımlamak için `defineApplication()` kullanın:
@@ -296,6 +334,7 @@ Uygulama yapılandırmanızı tanımlamak için `defineApplication()` kullanın:
// src/application-config.ts
import { defineApplication } from 'twenty-sdk';
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
@@ -311,6 +350,7 @@ export default defineApplication({
},
},
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
@@ -319,6 +359,7 @@ Notlar:
* `universalIdentifier` alanları size ait belirleyici kimliklerdir; bunları bir kez oluşturun ve eşitlemeler boyunca kararlı tutun.
* `applicationVariables`, fonksiyonlarınız için ortam değişkenlerine dönüşür (örneğin, `DEFAULT_RECIPIENT_NAME` değeri `process.env.DEFAULT_RECIPIENT_NAME` olarak kullanılabilir).
* `defaultRoleUniversalIdentifier`, rol dosyasıyla eşleşmelidir (aşağıya bakın).
* `postInstallLogicFunctionUniversalIdentifier` (isteğe bağlı), uygulama yüklendikten sonra otomatik olarak çalışan bir mantık işlevine işaret eder. Bkz. [Kurulum sonrası işlevler](#post-install-functions).
#### Roller ve izinler
@@ -457,6 +498,55 @@ Notlar:
* `triggers` dizisi isteğe bağlıdır. Tetikleyicisi olmayan fonksiyonlar, diğer fonksiyonlar tarafından çağrılan yardımcı fonksiyonlar olarak kullanılabilir.
* Tek bir fonksiyonda birden çok tetikleyici türünü birleştirebilirsiniz.
### Kurulum sonrası işlevler
Kurulum sonrası işlev, uygulamanız bir çalışma alanına yüklendikten sonra otomatik olarak çalışan bir mantık işlevidir. Bu, varsayılan verileri tohumlama, ilk kayıtları oluşturma veya çalışma alanı ayarlarını yapılandırma gibi tek seferlik kurulum görevleri için yararlıdır.
`create-twenty-app` ile yeni bir uygulama iskeleti oluşturduğunuzda, `src/logic-functions/post-install.ts` konumunda sizin için bir kurulum sonrası işlevi oluşturulur:
```typescript
// src/logic-functions/post-install.ts
import { defineLogicFunction } from 'twenty-sdk';
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
const handler = async (): Promise<void> => {
console.log('Post install logic function executed successfully!');
};
export default defineLogicFunction({
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
name: 'post-install',
description: 'Runs after installation to set up the application.',
timeoutSeconds: 300,
handler,
});
```
İşlev, `application-config.ts` içinde evrensel tanımlayıcısına başvurularak uygulamanıza bağlanır:
```typescript
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
// ...
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
Ayrıca kurulum sonrası işlevi istediğiniz zaman CLI kullanarak manuel olarak çalıştırabilirsiniz:
```bash filename="Terminal"
yarn twenty function:execute --postInstall
```
Önemli noktalar:
* Kurulum sonrası işlevleri standart mantık işlevleridir — diğer herhangi bir işlev gibi `defineLogicFunction()` kullanırlar.
* `defineApplication()` içindeki `postInstallLogicFunctionUniversalIdentifier` alanı isteğe bağlıdır. Atlanırsa, kurulumdan sonra hiçbir işlev çalıştırılmaz.
* Varsayılan zaman aşımı, veri tohumlama gibi daha uzun kurulum görevlerine izin vermek için 300 saniye (5 dakika) olarak ayarlanmıştır.
* Kurulum sonrası işlevlerin tetikleyicilere ihtiyacı yoktur — kurulum sırasında platform tarafından veya `function:execute --postInstall` aracılığıyla manuel olarak çağrılırlar.
### Rota tetikleyicisi yükü
<Warning>
@@ -554,6 +644,71 @@ Yeni fonksiyonları iki şekilde oluşturabilirsiniz:
* **Şablondan**: `yarn twenty entity:add` çalıştırın ve yeni bir mantık fonksiyonu ekleme seçeneğini seçin. Bu, bir işleyici ve yapılandırma içeren bir başlangıç dosyası oluşturur.
* **Manuel**: Yeni bir `*.logic-function.ts` dosyası oluşturun ve aynı deseni izleyerek `defineLogicFunction()` kullanın.
### Bir mantık işlevini araç olarak işaretleme
Mantık işlevleri, yapay zeka ajanları ve iş akışları için **araçlar** olarak sunulabilir. Bir işlev bir araç olarak işaretlendiğinde, Twenty'nin yapay zeka özellikleri tarafından keşfedilebilir hâle gelir ve iş akışı otomasyonlarında bir adım olarak seçilebilir.
Bir mantık işlevini bir araç olarak işaretlemek için `isTool: true` olarak ayarlayın ve beklenen giriş parametrelerini açıklayan bir `toolInputSchema`yı [JSON Şeması](https://json-schema.org/) kullanarak sağlayın:
```typescript
// src/logic-functions/enrich-company.logic-function.ts
import { defineLogicFunction } from 'twenty-sdk';
import Twenty from '~/generated';
const handler = async (params: { companyName: string; domain?: string }) => {
const client = new Twenty();
const result = await client.mutation({
createTask: {
__args: {
data: {
title: `Enrich data for ${params.companyName}`,
body: `Domain: ${params.domain ?? 'unknown'}`,
},
},
id: true,
},
});
return { taskId: result.createTask.id };
};
export default defineLogicFunction({
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
name: 'enrich-company',
description: 'Enrich a company record with external data',
timeoutSeconds: 10,
handler,
isTool: true,
toolInputSchema: {
type: 'object',
properties: {
companyName: {
type: 'string',
description: 'The name of the company to enrich',
},
domain: {
type: 'string',
description: 'The company website domain (optional)',
},
},
required: ['companyName'],
},
});
```
Önemli noktalar:
* **`isTool`** (`boolean`, varsayılan: `false`): `true` olarak ayarlandığında, işlev bir araç olarak kaydedilir ve AI ajanları ile iş akışı otomasyonları tarafından kullanılabilir hale gelir.
* **`toolInputSchema`** (`object`, isteğe bağlı): İşlevinizin kabul ettiği parametreleri tanımlayan bir JSON Schema nesnesi. AI ajanları, aracın hangi girdileri beklediğini anlamak ve çağrıları doğrulamak için bu şemayı kullanır. Atlanırsa, şema varsayılan olarak `{ type: 'object', properties: {} }` olur (parametre yok).
* `isTool: false` (veya ayarlanmamış) olan işlevler araç olarak **sunulmaz**. Yine de doğrudan yürütülebilir veya diğer işlevler tarafından çağrılabilirler, ancak araç keşfinde görünmezler.
* **Araç adlandırma**: Bir araç olarak sunulduğunda, işlev adı otomatik olarak `logic_function_<name>` biçimine dönüştürülür (küçük harfe çevrilir, alfasayısal olmayan karakterler alt çizgi ile değiştirilir). Örneğin, `enrich-company` `logic_function_enrich_company` haline gelir.
* `isTool` özelliğini tetikleyicilerle birleştirebilirsiniz — bir işlev aynı anda hem bir araç (AI ajanları tarafından çağrılabilir) olabilir hem de olaylar tarafından tetiklenebilir (cron, veritabanı olayları, routes).
<Note>
**İyi bir `description` yazın.** AI ajanları, aracı ne zaman kullanacaklarına karar vermek için işlevin `description` alanına güvenir. Aracın ne yaptığını ve ne zaman çağrılması gerektiğini açıkça belirtin.
</Note>
### Ön uç bileşenleri
Ön uç bileşenleri, Twenty'nin kullanıcı arayüzünde görüntülenen özel React bileşenleri oluşturmanıza olanak tanır. Yerleşik doğrulamayla bileşenleri tanımlamak için `defineFrontComponent()` kullanın:
@@ -591,9 +746,44 @@ Yeni ön uç bileşenlerini iki şekilde oluşturabilirsiniz:
* **Şablondan**: `yarn twenty entity:add` çalıştırın ve yeni bir ön uç bileşeni ekleme seçeneğini seçin.
* **Manuel**: Yeni bir `*.front-component.tsx` dosyası oluşturun ve `defineFrontComponent()` kullanın.
### Beceriler
Yetenekler, yapay zekâ ajanlarının çalışma alanınızda kullanabileceği yeniden kullanılabilir yönergeleri ve kabiliyetleri tanımlar. Yerleşik doğrulamayla yetenekleri tanımlamak için `defineSkill()` kullanın:
```typescript
// src/skills/example-skill.ts
import { defineSkill } from 'twenty-sdk';
export default defineSkill({
universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
name: 'sales-outreach',
label: 'Sales Outreach',
description: 'Guides the AI agent through a structured sales outreach process',
icon: 'IconBrain',
content: `You are a sales outreach assistant. When reaching out to a prospect:
1. Research the company and recent news
2. Identify the prospect's role and likely pain points
3. Draft a personalized message referencing specific details
4. Keep the tone professional but conversational`,
});
```
Önemli noktalar:
* `name`, yetenek için benzersiz bir tanımlayıcı dizedir (kebab-case önerilir).
* `label`, UI'de gösterilen, insan tarafından okunabilir addır.
* `content`, yetenek yönergelerini içerir — bu, yapay zekâ ajanının kullandığı metindir.
* `icon` (isteğe bağlı), UI'de gösterilen simgeyi ayarlar.
* `description` (isteğe bağlı), yeteneğin amacı hakkında ek bağlam sağlar.
Yeni yetenekleri iki şekilde oluşturabilirsiniz:
* **Şablondan**: `yarn twenty entity:add` komutunu çalıştırın ve yeni bir yetenek ekleme seçeneğini seçin.
* **Manuel**: Yeni bir dosya oluşturun ve aynı deseni izleyerek `defineSkill()` kullanın.
### Oluşturulmuş türlendirilmiş istemci
Çalışma alanı şemanıza göre `generated/` içinde yerel bir türlendirilmiş istemci oluşturmak için `yarn twenty app:generate` çalıştırın. Fonksiyonlarınızda kullanın:
Tipli istemci, `yarn twenty app:dev` tarafından otomatik olarak oluşturulur ve çalışma alanı şemanıza göre `node_modules/twenty-sdk/generated` içine kaydedilir. Fonksiyonlarınızda kullanın:
```typescript
import Twenty from '~/generated';
@@ -602,7 +792,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
İstemci `yarn twenty app:generate` tarafından yeniden oluşturulur. Nesnelerinizi değiştirdikten sonra veya yeni bir çalışma alanına katılırken yeniden çalıştırın.
Nesneleriniz veya alanlarınız değiştiğinde, istemci `yarn twenty app:dev` tarafından otomatik olarak yeniden oluşturulur.
#### Mantık fonksiyonlarında çalışma zamanı kimlik bilgileri
@@ -617,6 +807,53 @@ Notlar:
* API anahtarının izinleri, `application-config.ts` içinde `defaultRoleUniversalIdentifier` aracılığıyla referans verilen role göre belirlenir. Bu, uygulamanızın mantık fonksiyonları tarafından kullanılan varsayılan roldür.
* Uygulamalar, en az ayrıcalık ilkesini izlemek için roller tanımlayabilir. Yalnızca fonksiyonlarınızın ihtiyaç duyduğu izinleri verin ve ardından `defaultRoleUniversalIdentifier` değerini o rolün evrensel tanımlayıcısına yönlendirin.
#### Dosya yükleme
Oluşturulan `Twenty` istemcisi, çalışma alanı nesnelerinizdeki dosya türündeki alanlara dosya eklemek için bir `uploadFile` yöntemi içerir. Standart GraphQL istemcileri çok parçalı dosya yüklemelerini yerel olarak desteklemediğinden, istemci arka planda [GraphQL çok parçalı istek belirtimi](https://github.com/jaydenseric/graphql-multipart-request-spec) uygulayan bu özel yöntemi sağlar.
```typescript
import Twenty from '~/generated';
import * as fs from 'fs';
const client = new Twenty();
const fileBuffer = fs.readFileSync('./invoice.pdf');
const uploadedFile = await client.uploadFile(
fileBuffer, // file contents as a Buffer
'invoice.pdf', // filename
'application/pdf', // MIME type (defaults to 'application/octet-stream')
'58a0a314-d7ea-4865-9850-7fb84e72f30b', // field universal identifier
);
console.log(uploadedFile);
// { id: '...', path: '...', size: 12345, createdAt: '...', url: 'https://...' }
```
Yöntem imzası:
```typescript
uploadFile(
fileBuffer: Buffer,
filename: string,
contentType: string,
fieldMetadataUniversalIdentifier: string,
): Promise<{ id: string; path: string; size: number; createdAt: string; url: string }>
```
| Parametre | Tür | Açıklama |
| ---------------------------------- | -------- | ------------------------------------------------------------------------------------------ |
| `fileBuffer` | `Buffer` | Dosyanın ham içeriği |
| `filename` | `string` | Dosyanın adı (depolama ve görüntüleme için kullanılır) |
| `contentType` | `string` | Dosyanın MIME türü (belirtilmezse varsayılan olarak `application/octet-stream` kullanılır) |
| `fieldMetadataUniversalIdentifier` | `string` | Nesnenizdeki dosya türü alanının `universalIdentifier` değeri |
Önemli noktalar:
* Yöntem dosyayı, yükleme mutasyonunun çözümlendiği **metadata endpoint**'e (ana GraphQL endpoint'ine değil) gönderir.
* Alan için `universalIdentifier` kullanılır (çalışma alanına özgü kimliği değil), böylece yükleme kodunuz uygulamanızın yüklü olduğu herhangi bir çalışma alanında çalışır — uygulamaların başka her yerde alanlara nasıl atıfta bulunduğuyla tutarlıdır.
* Döndürülen `url`, yüklenen dosyaya erişmek için kullanabileceğiniz imzalı bir URL'dir.
### Hello World örneği
Nesneleri, mantık fonksiyonlarını, ön uç bileşenlerini ve birden çok tetikleyiciyi gösteren minimal, uçtan uca bir örneği [buradan](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world) inceleyin:
@@ -639,13 +876,13 @@ Ardından bir `twenty` betiği ekleyin:
}
```
Artık tüm komutları `yarn twenty <command>` üzerinden çalıştırabilirsiniz; örn. `yarn twenty app:dev`, `yarn twenty app:generate`, `yarn twenty help` vb.
Artık tüm komutları `yarn twenty <command>` üzerinden çalıştırabilirsiniz; örn. `yarn twenty app:dev`, `yarn twenty help` vb.
## Sorun Giderme
* Kimlik doğrulama hataları: `yarn twenty auth:login` çalıştırın ve API anahtarınızın gerekli izinlere sahip olduğundan emin olun.
* Sunucuya bağlanılamıyor: API URLsini ve Twenty sunucusunun erişilebilir olduğunu doğrulayın.
* Türler veya istemci eksik/eski: `yarn twenty app:generate` çalıştırın.
* Türler veya istemci eksik/eski: `yarn twenty app:dev` komutunu yeniden çalıştırın — tip tanımlı istemciyi otomatik olarak oluşturur.
* Geliştirme modu eşitlenmiyor: `yarn twenty app:dev`'in çalıştığından ve değişikliklerin ortamınız tarafından yok sayılmadığından emin olun.
Discord Yardım Kanalı: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -15,6 +15,7 @@ description: 以代码的形式构建并管理 Twenty 自定义项。
* 以代码定义自定义对象和字段(受管理的数据模型)
* 构建带有自定义触发器的逻辑函数
* 为 AI 智能体定义技能
* 将同一个应用部署到多个工作空间
## 先决条件
@@ -27,35 +28,48 @@ description: 以代码的形式构建并管理 Twenty 自定义项。
使用官方脚手架创建一个新应用,然后进行身份验证并开始开发:
```bash filename="Terminal"
# 搭建一个新应用
# Scaffold a new app (includes all examples by default)
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
# 如果你不使用 yarn@4
# If you don't use yarn@4
corepack enable
yarn install
# 使用你的 API 密钥进行身份验证(系统会提示你)
# Authenticate using your API key (you'll be prompted)
yarn twenty auth:login
# 启动开发模式:会将本地更改自动同步到你的工作区
# Start dev mode: automatically syncs local changes to your workspace
yarn twenty app:dev
```
The scaffolder supports three modes for controlling which example files are included:
```bash filename="Terminal"
# 默认(完整):所有示例(对象、字段、逻辑函数、前端组件、视图、导航菜单项、技能)
npx create-twenty-app@latest my-app
# 最小化:仅核心文件(application-config.ts 和 default-role.ts
npx create-twenty-app@latest my-app --minimal
# 交互式:选择要包含的示例
npx create-twenty-app@latest my-app --interactive
```
从这里您可以:
```bash filename="Terminal"
# 向你的应用添加一个新实体(引导式)
yarn twenty entity:add
# 生成类型化的 Twenty 客户端和工作区实体类型
yarn twenty app:generate
# 监听你的应用函数日志
yarn twenty function:logs
# 按名称执行一个函数
yarn twenty function:execute -n my-function -p '{"name": "test"}'
yarn twenty function:execute -n my-function -p '{\"name\": \"test\"}'
# 执行安装后函数
yarn twenty function:execute --postInstall
# 从当前工作区卸载该应用
yarn twenty app:uninstall
@@ -73,9 +87,9 @@ yarn twenty help
* 将一个最小的基础应用复制到 `my-twenty-app/` 中
* 添加本地 `twenty-sdk` 依赖和 Yarn 4 配置
* 创建与 `twenty` CLI 关联的配置文件和脚本
* 生成默认的应用配置和默认的函数角色
* Generates core files (application config, default function role, post-install function) plus example files based on the scaffolding mode
一个新生成的脚手架应用如下所示:
A freshly scaffolded app with the default `--exhaustive` mode looks like this:
```text filename="my-twenty-app/"
my-twenty-app/
@@ -89,17 +103,30 @@ my-twenty-app/
eslint.config.mjs
tsconfig.json
README.md
public/ # 公共资源文件夹(图像、字体等)
public/ # Public assets folder (images, fonts, etc.)
src/
├── application-config.ts # 必需 - 主应用程序配置
├── application-config.ts # Required - main application configuration
├── roles/
│ └── default-role.ts # 用于逻辑函数的默认角色
│ └── default-role.ts # Default role for logic functions
├── objects/
│ └── example-object.ts # Example custom object definition
├── fields/
│ └── example-field.ts # Example standalone field definition
├── logic-functions/
── hello-world.ts # 示例逻辑函数
└── front-components/
└── hello-world.tsx # 示例前端组件
── hello-world.ts # Example logic function
└── post-install.ts # Post-install logic function
├── front-components/
│ └── hello-world.tsx # Example front component
├── views/
│ └── example-view.ts # Example saved view definition
├── navigation-menu-items/
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
└── skills/
└── example-skill.ts # Example AI agent skill definition
```
With `--minimal`, only the core files are created (`application-config.ts`, `roles/default-role.ts`, and `logic-functions/post-install.ts`). With `--interactive`, you choose which example files to include.
总体来说:
* **package.json**:声明应用名称、版本、引擎(Node 24+、Yarn 4),并添加 `twenty-sdk` 以及一个 `twenty` 脚本,该脚本会委托给本地的 `twenty` CLI。 运行 `yarn twenty help` 以列出所有可用命令。
@@ -115,13 +142,16 @@ my-twenty-app/
该 SDK 通过在你的 TypeScript 文件中解析 **`export default define<Entity>({...})`** 调用来检测实体。 每种实体类型都有一个从 `twenty-sdk` 导出的对应辅助函数:
| 辅助函数 | 实体类型 |
| ------------------------ | --------- |
| `defineObject()` | 自定义对象定义 |
| `defineLogicFunction()` | 逻辑函数定义 |
| `defineFrontComponent()` | 前端组件定义 |
| `defineRole()` | 角色定义 |
| `defineField()` | 现有对象的字段扩展 |
| 辅助函数 | 实体类型 |
| ---------------------------- | -------------------------------- |
| `defineObject()` | 自定义对象定义 |
| `defineLogicFunction()` | 逻辑函数定义 |
| `defineFrontComponent()` | 前端组件定义 |
| `defineRole()` | 角色定义 |
| `defineField()` | 现有对象的字段扩展 |
| `defineView()` | Saved view definitions |
| `defineNavigationMenuItem()` | Navigation menu item definitions |
| `defineSkill()` | AI agent skill definitions |
<Note>
**文件命名是灵活的。** 实体检测基于 AST — SDK 会扫描你的源文件以查找 `export default define<Entity>({...})` 模式。 你可以按照自己的喜好组织文件和文件夹。 按实体类型分组(例如 `logic-functions/`、`roles/`)只是代码组织的一种约定,并非必需。
@@ -142,8 +172,8 @@ export default defineObject({
后续命令将添加更多文件和文件夹:
* `yarn twenty app:generate` 将创建一个 `generated/` 文件夹(类型化 Twenty 客户端 + 工作空间类型)。
* `yarn twenty entity:add` 会在 `src/` 下为你的自定义对象、函数、前端组件或角色添加实体定义文件。
* `yarn twenty app:dev` 将在 `node_modules/twenty-sdk/generated` 中自动生成一个类型化的 API 客户端(类型化 Twenty 客户端 + 工作类型)。
* `yarn twenty entity:add` will add entity definition files under `src/` for your custom objects, functions, front components, roles, skills, and more.
## 身份验证
@@ -186,14 +216,17 @@ twenty-sdk 提供你在应用中使用的类型化构件和辅助函数。 以
该 SDK 提供辅助函数用于定义你的应用实体。 如 [实体检测](#entity-detection) 中所述,你必须使用 `export default define<Entity>({...})` 才能让你的实体被检测到:
| 函数 | 目的 |
| ------------------------ | ------------------ |
| `defineApplication()` | 配置应用元数据(必需,每个应用一个) |
| `defineObject()` | 定义带字段的自定义对象 |
| `defineLogicFunction()` | 定义带处理程序的逻辑函数 |
| `defineFrontComponent()` | 为自定义 UI 定义前端组件 |
| `defineRole()` | 配置角色权限和对象访问 |
| `defineField()` | 为现有对象扩展额外字段 |
| 函数 | 目的 |
| ---------------------------- | ------------------------------- |
| `defineApplication()` | 配置应用元数据(必需,每个应用一个) |
| `defineObject()` | 定义带字段的自定义对象 |
| `defineLogicFunction()` | 定义带处理程序的逻辑函数 |
| `defineFrontComponent()` | 为自定义 UI 定义前端组件 |
| `defineRole()` | 配置角色权限和对象访问 |
| `defineField()` | 为现有对象扩展额外字段 |
| `defineView()` | Define saved views for objects |
| `defineNavigationMenuItem()` | Define sidebar navigation links |
| `defineSkill()` | Define AI agent skills |
这些函数会在构建时校验你的配置,并提供 IDE 自动补全和类型安全。
@@ -279,7 +312,11 @@ export default defineObject({
* 你可以使用 `yarn twenty entity:add` 脚手架创建新对象,它会引导你完成命名、字段和关系。
<Note>
**基础字段会自动创建。** 当你定义自定义对象时,Twenty 会自动添加 `name`、`createdAt`、`updatedAt`、`createdBy`、`position`、`deletedAt` 等标准字段。 你无需在 `fields` 数组中定义这些字段——只需添加你的自定义字段。
**基础字段会自动创建。** 当你定义自定义对象时,Twenty 会自动添加标准字段
例如 `id`、`name`、`createdAt`、`updatedAt`、`createdBy`、`updatedBy` 和 `deletedAt`。
你无需在 `fields` 数组中定义这些字段——只需添加你的自定义字段。
你可以通过在你的 `fields` 数组中定义一个同名字段来覆盖默认字段,
但不建议这样做。
</Note>
### 应用配置(application-config.ts
@@ -289,6 +326,7 @@ export default defineObject({
* **应用的身份**:标识符、显示名称和描述。
* **函数如何运行**:它们用于权限的角色。
* **(可选)变量**:以环境变量形式提供给函数的键值对。
* **(可选)安装后函数**:在应用安装后运行的逻辑函数。
使用 `defineApplication()` 定义你的应用配置:
@@ -296,6 +334,7 @@ export default defineObject({
// src/application-config.ts
import { defineApplication } from 'twenty-sdk';
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
@@ -311,6 +350,7 @@ export default defineApplication({
},
},
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
@@ -319,6 +359,7 @@ export default defineApplication({
* `universalIdentifier` 字段是你拥有的确定性 ID;生成一次并在多次同步中保持稳定。
* `applicationVariables` 会变成函数可用的环境变量(例如,`DEFAULT_RECIPIENT_NAME` 可作为 `process.env.DEFAULT_RECIPIENT_NAME` 使用)。
* `defaultRoleUniversalIdentifier` 必须与角色文件一致(见下文)。
* `postInstallLogicFunctionUniversalIdentifier`(可选)指向一个在应用安装后自动运行的逻辑函数。 参见 [安装后函数](#post-install-functions)。
#### 角色和权限
@@ -457,6 +498,55 @@ export default defineLogicFunction({
* `triggers` 数组是可选的。 没有触发器的函数可作为实用函数,被其他函数调用。
* 你可以在单个函数中混用多种触发器类型。
### 安装后函数
安装后函数是在你的应用安装到工作区后自动运行的逻辑函数。 这对于一次性设置任务很有用,例如填充默认数据、创建初始记录或配置工作区设置。
当你使用 `create-twenty-app` 脚手架创建一个新应用时,会在 `src/logic-functions/post-install.ts` 为你生成一个安装后函数:
```typescript
// src/logic-functions/post-install.ts
import { defineLogicFunction } from 'twenty-sdk';
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
const handler = async (): Promise<void> => {
console.log('Post install logic function executed successfully!');
};
export default defineLogicFunction({
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
name: 'post-install',
description: 'Runs after installation to set up the application.',
timeoutSeconds: 300,
handler,
});
```
通过在 `application-config.ts` 中引用其通用标识符,可将该函数接入你的应用:
```typescript
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
export default defineApplication({
// ...
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
});
```
You can also manually execute the post-install function at any time using the CLI:
```bash filename="Terminal"
yarn twenty function:execute --postInstall
```
关键点:
* Post-install functions are standard logic functions — they use `defineLogicFunction()` like any other function.
* The `postInstallLogicFunctionUniversalIdentifier` field in `defineApplication()` is optional. If omitted, no function runs after installation.
* The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `function:execute --postInstall`.
### 路由触发器负载
<Warning>
@@ -554,6 +644,71 @@ const handler = async (event: RoutePayload) => {
* **脚手架生成**:运行 `yarn twenty entity:add` 并选择添加新逻辑函数的选项。 这将生成一个包含处理程序和配置的入门文件。
* **手动**:创建一个新的 `*.logic-function.ts` 文件,并使用 `defineLogicFunction()`,遵循相同的模式。
### 将逻辑函数标记为工具
逻辑函数可以作为供 AI 智能体和工作流使用的**工具**对外提供。 当函数被标记为工具时,Twenty 的 AI 功能即可发现它,并可在工作流自动化中将其选作一个步骤。
要将逻辑函数标记为工具,请设置 `isTool: true`,并提供 `toolInputSchema`,使用 [JSON Schema](https://json-schema.org/) 描述预期的输入参数:
```typescript
// src/logic-functions/enrich-company.logic-function.ts
import { defineLogicFunction } from 'twenty-sdk';
import Twenty from '~/generated';
const handler = async (params: { companyName: string; domain?: string }) => {
const client = new Twenty();
const result = await client.mutation({
createTask: {
__args: {
data: {
title: `Enrich data for ${params.companyName}`,
body: `Domain: ${params.domain ?? 'unknown'}`,
},
},
id: true,
},
});
return { taskId: result.createTask.id };
};
export default defineLogicFunction({
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
name: 'enrich-company',
description: 'Enrich a company record with external data',
timeoutSeconds: 10,
handler,
isTool: true,
toolInputSchema: {
type: 'object',
properties: {
companyName: {
type: 'string',
description: 'The name of the company to enrich',
},
domain: {
type: 'string',
description: 'The company website domain (optional)',
},
},
required: ['companyName'],
},
});
```
关键点:
* **`isTool`** (`boolean`, 默认: `false`): 当设置为 `true` 时,该函数会被注册为工具,并可供 AI 代理和工作流自动化使用。
* **`toolInputSchema`** (`object`, 可选): 描述函数可接受参数的 JSON Schema 对象。 AI 代理使用此架构来理解该工具期望的输入并验证调用。 如果省略,架构将默认为 `{ type: 'object', properties: {} }`(无参数)。
* 设置为 `isTool: false`(或未设置)的函数**不会**被暴露为工具。 它们仍可直接执行或被其他函数调用,但不会出现在工具发现中。
* **工具命名**: 当作为工具对外暴露时,函数名会被自动规范化为 `logic_function_<name>`(转换为小写,非字母数字字符替换为下划线)。 例如,`enrich-company` 将变为 `logic_function_enrich_company`。
* 你可以将 `isTool` 与触发器结合使用——一个函数既可以作为工具(由 AI 代理调用),也可以同时由事件(cron、数据库事件、路由)触发。
<Note>
**写一个好的 `description`。** AI 代理会依赖该函数的 `description` 字段来决定何时使用该工具。 明确说明该工具的作用以及应在何时调用。
</Note>
### 前端组件
前端组件使你可以构建在 Twenty 的 UI 中渲染的自定义 React 组件。 使用 `defineFrontComponent()` 以内置校验定义组件:
@@ -591,9 +746,44 @@ export default defineFrontComponent({
* **脚手架生成**:运行 `yarn twenty entity:add` 并选择添加新前端组件的选项。
* **手动**:创建一个新的 `*.front-component.tsx` 文件,并使用 `defineFrontComponent()`。
### 技能
Skills define reusable instructions and capabilities that AI agents can use within your workspace. Use `defineSkill()` to define skills with built-in validation:
```typescript
// src/skills/example-skill.ts
import { defineSkill } from 'twenty-sdk';
export default defineSkill({
universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
name: 'sales-outreach',
label: 'Sales Outreach',
description: 'Guides the AI agent through a structured sales outreach process',
icon: 'IconBrain',
content: `You are a sales outreach assistant. When reaching out to a prospect:
1. Research the company and recent news
2. Identify the prospect's role and likely pain points
3. Draft a personalized message referencing specific details
4. Keep the tone professional but conversational`,
});
```
关键点:
* `name` is a unique identifier string for the skill (kebab-case recommended).
* `label` is the human-readable display name shown in the UI.
* `content` contains the skill instructions — this is the text the AI agent uses.
* `icon` (optional) sets the icon displayed in the UI.
* `description` (optional) provides additional context about the skill's purpose.
You can create new skills in two ways:
* **Scaffolded**: Run `yarn twenty entity:add` and choose the option to add a new skill.
* **Manual**: Create a new file and use `defineSkill()`, following the same pattern.
### 生成的类型化客户端
运行 `yarn twenty app:generate`,根据你的工作空间模式在 `generated/` 中创建本地类型化客户端。 在你的函数中使用它:
类型化客户端由 `yarn twenty app:dev` 自动生成,并基于你的工作区架构存放在 `node_modules/twenty-sdk/generated`。 在你的函数中使用它:
```typescript
import Twenty from '~/generated';
@@ -602,7 +792,7 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
客户端会通过 `yarn twenty app:generate` 重新生成。 在更改对象之后或接入新工作空间时,请重新运行
每当你的对象或字段发生变化时,`yarn twenty app:dev` 都会自动重新生成该客户端
#### 逻辑函数中的运行时凭据
@@ -617,6 +807,53 @@ const { me } = await client.query({ me: { id: true, displayName: true } });
* API 密钥的权限由 `application-config.ts` 中通过 `defaultRoleUniversalIdentifier` 引用的角色决定。 这是你的应用逻辑函数使用的默认角色。
* 应用可以定义角色以遵循最小权限原则。 仅授予函数所需的权限,然后将 `defaultRoleUniversalIdentifier` 指向该角色的通用标识符。
#### 上传文件
生成的 `Twenty` 客户端包含一个 `uploadFile` 方法,用于将文件附加到工作区对象的文件类型字段。 由于标准 GraphQL 客户端不原生支持多部分文件上传,该客户端提供了一个专用方法,在底层实现了 [GraphQL 多部分请求规范](https://github.com/jaydenseric/graphql-multipart-request-spec)。
```typescript
import Twenty from '~/generated';
import * as fs from 'fs';
const client = new Twenty();
const fileBuffer = fs.readFileSync('./invoice.pdf');
const uploadedFile = await client.uploadFile(
fileBuffer, // file contents as a Buffer
'invoice.pdf', // filename
'application/pdf', // MIME type (defaults to 'application/octet-stream')
'58a0a314-d7ea-4865-9850-7fb84e72f30b', // field universal identifier
);
console.log(uploadedFile);
// { id: '...', path: '...', size: 12345, createdAt: '...', url: 'https://...' }
```
方法签名:
```typescript
uploadFile(
fileBuffer: Buffer,
filename: string,
contentType: string,
fieldMetadataUniversalIdentifier: string,
): Promise<{ id: string; path: string; size: number; createdAt: string; url: string }>
```
| 参数 | 类型 | 描述 |
| ---------------------------------- | -------- | ------------------------------------------------ |
| `fileBuffer` | `Buffer` | 原始文件内容 |
| `filename` | `string` | 文件名称(用于存储和显示) |
| `contentType` | `string` | 文件的 MIME 类型(如果省略,默认为 `application/octet-stream` |
| `fieldMetadataUniversalIdentifier` | `string` | 你的对象上文件类型字段的 `universalIdentifier` |
关键点:
* 该方法将文件发送到**元数据端点**(而不是主 GraphQL 端点),在那里处理上传变更操作。
* 它使用该字段的 `universalIdentifier`(而不是其工作区特定的 ID),因此你的上传代码可以在安装了你的应用的任何工作区中使用——这与应用在其他地方引用字段的方式保持一致。
* 返回的 `url` 是一个签名 URL,你可以用它来访问已上传的文件。
### Hello World 示例
在[此处](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world)查看一个最小的端到端示例,展示对象、逻辑函数、前端组件和多种触发器:
@@ -639,13 +876,13 @@ yarn add -D twenty-sdk
}
```
现在你可以通过 `yarn twenty <command>` 运行所有命令,例如 `yarn twenty app:dev`、`yarn twenty app:generate`、`yarn twenty help` 等。
现在你可以通过 `yarn twenty <command>` 运行所有命令,例如 `yarn twenty app:dev`、`yarn twenty help` 等。
## 故障排除
* 身份验证错误:运行 `yarn twenty auth:login`,并确保你的 API 密钥具有所需权限。
* 无法连接到服务器:请验证 API URL,并确保 Twenty 服务器可达。
* 类型或客户端缺失/过期:运行 `yarn twenty app:generate`
* 类型或客户端缺失/过期:重启 `yarn twenty app:dev` — 它会自动生成类型化客户端
* 开发模式未同步:确保 `yarn twenty app:dev` 正在运行,并且你的环境不会忽略变更。
Discord 帮助频道:https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -111,8 +111,8 @@ test('Create and update record', async ({ page }) => {
await companyRelationWidget.hover();
await companyRelationWidget.locator('.tabler-icon-pencil').click();
await page.getByRole('textbox', { name: 'Search' }).fill('Goog');
await expect(page.getByRole('option', { name: 'Google' })).toBeVisible();
await page.getByRole('textbox', { name: 'Search' }).fill('VMw');
await expect(page.getByRole('option', { name: 'VMware' })).toBeVisible();
const [updatePersonResponse] = await Promise.all([
page.waitForResponse(async (response) => {
if (!response.url().endsWith('/graphql')) {
@@ -123,7 +123,7 @@ test('Create and update record', async ({ page }) => {
return requestBody.operationName === 'UpdateOnePerson';
}),
await page.getByRole('option', { name: 'Google' }).click({force: true})
await page.getByRole('option', { name: 'VMware' }).click({force: true})
]);
const body = await updatePersonResponse.json()
@@ -153,6 +153,6 @@ test('Create and update record', async ({ page }) => {
expect(findOnePersonReponseBody.data.person.linkedinLink.primaryLinkUrl).toBe('linkedin.com/johndoe');
expect(findOnePersonReponseBody.data.person.phones.primaryPhoneNumber).toBe('611223344');
expect(findOnePersonReponseBody.data.person.workPreference).toEqual(['HYBRID']);
expect(findOnePersonReponseBody.data.person.company.name).toBe('Google');
expect(findOnePersonReponseBody.data.person.company.name).toBe('VMware');
});
+1 -1
View File
@@ -19,7 +19,7 @@
},
"devDependencies": {
"@lingui/cli": "^5.1.2",
"@lingui/swc-plugin": "^5.6.0",
"@lingui/swc-plugin": "^5.11.0",
"@lingui/vite-plugin": "^5.1.2",
"@react-email/preview-server": "5.1.0",
"@tiptap/core": "^3.4.2",
@@ -52,11 +52,11 @@ export const rule = createRule<[], 'restApiMethodsShouldBeGuarded'>({
meta: {
docs: {
description:
'REST API endpoints should have authentication guards (UserAuthGuard, WorkspaceAuthGuard, FilePathGuard, or FilesFieldGuard) or be explicitly marked as public (PublicEndpointGuard) and permission guards (SettingsPermissionsGuard or CustomPermissionGuard) to maintain our security model.',
'REST API endpoints should have authentication guards (UserAuthGuard, WorkspaceAuthGuard, FilePathGuard, FileByIdGuard) or be explicitly marked as public (PublicEndpointGuard) and permission guards (SettingsPermissionsGuard or CustomPermissionGuard) to maintain our security model.',
},
messages: {
restApiMethodsShouldBeGuarded:
'All REST API controller endpoints must have authentication guards (@UseGuards(UserAuthGuard/WorkspaceAuthGuard/FilePathGuard/FileIdGuard/FilesFieldGuard/PublicEndpointGuard)) and permission guards (@UseGuards(..., SettingsPermissionsGuard(PermissionFlagType.XXX)), CustomPermissionGuard for custom logic, or NoPermissionGuard for special cases).',
'All REST API controller endpoints must have authentication guards (@UseGuards(UserAuthGuard/WorkspaceAuthGuard/FilePathGuard/FileByIdGuard/PublicEndpointGuard)) and permission guards (@UseGuards(..., SettingsPermissionsGuard(PermissionFlagType.XXX)), CustomPermissionGuard for custom logic, or NoPermissionGuard for special cases).',
},
schema: [],
hasSuggestions: false,
@@ -42,7 +42,7 @@ export const typedTokenHelpers = {
TSESTree.AST_NODE_TYPES.Identifier &&
decorator.expression.callee.name === 'UseGuards'
) {
// Check the arguments for UserAuthGuard, WorkspaceAuthGuard, PublicEndpoint, FilePathGuard, or FilesFieldGuard
// Check the arguments for UserAuthGuard, WorkspaceAuthGuard, PublicEndpoint, FilePathGuard or FileByIdGuard
return decorator.expression.arguments.some((arg) => {
if (arg.type === TSESTree.AST_NODE_TYPES.Identifier) {
return (
@@ -50,7 +50,7 @@ export const typedTokenHelpers = {
arg.name === 'WorkspaceAuthGuard' ||
arg.name === 'PublicEndpointGuard' ||
arg.name === 'FilePathGuard' ||
arg.name === 'FilesFieldGuard'
arg.name === 'FileByIdGuard'
);
}
return false;
@@ -9,6 +9,8 @@ import { SOURCE_LOCALE } from 'twenty-shared/translations';
// eslint-disable-next-line no-restricted-imports
import { RootDecorator } from '../src/testing/decorators/RootDecorator';
// eslint-disable-next-line no-restricted-imports
import { resetJotaiStore } from '../src/modules/ui/utilities/state/jotai/jotaiStore';
import 'react-loading-skeleton/dist/skeleton.css';
import 'twenty-ui/style.css';
@@ -84,6 +86,10 @@ const preview: Preview = {
RootDecorator,
],
beforeEach: () => {
resetJotaiStore();
},
loaders: [mswLoader],
parameters: {
+1 -2
View File
@@ -14,7 +14,6 @@ process.env.TZ = 'GMT';
// eslint-disable-next-line no-undef
process.env.LC_ALL = 'en_US.UTF-8';
const jestConfig = {
silent: true,
// For more information please have a look to official docs https://jestjs.io/docs/configuration/#prettierpath-string
// Prettier v3 will should be supported in jest v30 https://github.com/jestjs/jest/releases/tag/v30.0.0-alpha.1
prettierPath: null,
@@ -64,7 +63,7 @@ const jestConfig = {
global: {
statements: 49.5,
lines: 48,
functions: 40,
functions: 39.5,
},
},
collectCoverageFrom: ['<rootDir>/src/**/*.ts'],
+1 -1
View File
@@ -120,7 +120,7 @@
},
"devDependencies": {
"@lingui/cli": "^5.1.2",
"@lingui/swc-plugin": "^5.6.0",
"@lingui/swc-plugin": "^5.11.0",
"@lingui/vite-plugin": "^5.1.2",
"@playwright/test": "^1.56.1",
"@tiptap/suggestion": "3.4.2",
+26
View File
@@ -3,6 +3,11 @@
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';
import {
ReadableStream as NodeReadableStream,
TransformStream as NodeTransformStream,
WritableStream as NodeWritableStream,
} from 'node:stream/web';
import { i18n } from '@lingui/core';
import { SOURCE_LOCALE } from 'twenty-shared/translations';
@@ -12,6 +17,27 @@ import { messages as enMessages } from '~/locales/generated/en';
i18n.load({ [SOURCE_LOCALE]: enMessages });
i18n.activate(SOURCE_LOCALE);
const globalWithWebStreams = globalThis as Record<string, unknown>;
if (globalWithWebStreams.TransformStream === undefined) {
globalWithWebStreams.TransformStream = NodeTransformStream;
}
if (globalWithWebStreams.ReadableStream === undefined) {
globalWithWebStreams.ReadableStream = NodeReadableStream;
}
if (globalWithWebStreams.WritableStream === undefined) {
globalWithWebStreams.WritableStream = NodeWritableStream;
}
if (typeof window !== 'undefined') {
Object.defineProperty(window, 'scrollTo', {
value: () => {},
writable: true,
});
}
// Add Jest matchers for toThrowError and other missing methods
declare global {
namespace jest {
File diff suppressed because one or more lines are too long
@@ -3,7 +3,7 @@ import { useDefaultHomePagePath } from '@/navigation/hooks/useDefaultHomePagePat
import { useOnboardingStatus } from '@/onboarding/hooks/useOnboardingStatus';
import { useIsWorkspaceActivationStatusEqualsTo } from '@/workspace/hooks/useIsWorkspaceActivationStatusEqualsTo';
import { useParams } from 'react-router-dom';
import { useRecoilValue } from 'recoil';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { AppPath, SettingsPath } from 'twenty-shared/types';
import { getSettingsPath } from 'twenty-shared/utils';
@@ -63,14 +63,14 @@ const setupMockUseParams = (objectNamePlural?: string) => {
.mockReturnValueOnce({ objectNamePlural: objectNamePlural ?? '' });
};
jest.mock('recoil');
jest.mock('@/ui/utilities/state/jotai/hooks/useAtomStateValue');
const setupMockRecoil = (
objectNamePlural?: string,
verifyEmailRedirectPath?: string,
calendarBookingPageId?: string | null,
) => {
jest
.mocked(useRecoilValue)
.mocked(useAtomStateValue)
.mockReturnValueOnce(calendarBookingPageId ?? 'mock-calendar-id')
.mockReturnValueOnce([{ namePlural: objectNamePlural ?? '' }])
.mockReturnValueOnce(verifyEmailRedirectPath);
@@ -9,6 +9,18 @@ export const useCopyToClipboard = () => {
const { t } = useLingui();
const copyToClipboard = async (valueAsString: string, message?: string) => {
if (!window.isSecureContext) {
enqueueErrorSnackBar({
message: t`Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying.`,
options: {
icon: <IconExclamationCircle size={16} color="red" />,
duration: 6000,
},
});
return;
}
try {
await navigator.clipboard.writeText(valueAsString);
@@ -5,9 +5,9 @@ import { useIsCurrentLocationOnAWorkspace } from '@/domain-manager/hooks/useIsCu
import { useDefaultHomePagePath } from '@/navigation/hooks/useDefaultHomePagePath';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { useOnboardingStatus } from '@/onboarding/hooks/useOnboardingStatus';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useIsWorkspaceActivationStatusEqualsTo } from '@/workspace/hooks/useIsWorkspaceActivationStatusEqualsTo';
import { useLocation, useParams } from 'react-router-dom';
import { useRecoilValue } from 'recoil';
import { AppPath, SettingsPath } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
@@ -23,7 +23,7 @@ export const usePageChangeEffectNavigateLocation = () => {
);
const { defaultHomePagePath } = useDefaultHomePagePath();
const location = useLocation();
const calendarBookingPageId = useRecoilValue(calendarBookingPageIdState);
const calendarBookingPageId = useAtomStateValue(calendarBookingPageIdState);
const someMatchingLocationOf = (appPaths: AppPath[]): boolean =>
appPaths.some((appPath) => isMatchingLocation(location, appPath));
@@ -45,11 +45,13 @@ export const usePageChangeEffectNavigateLocation = () => {
];
const objectNamePlural = useParams().objectNamePlural ?? '';
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
const objectMetadataItems = useAtomStateValue(objectMetadataItemsState);
const objectMetadataItem = objectMetadataItems?.find(
(objectMetadataItem) => objectMetadataItem.namePlural === objectNamePlural,
);
const verifyEmailRedirectPath = useRecoilValue(verifyEmailRedirectPathState);
const verifyEmailRedirectPath = useAtomStateValue(
verifyEmailRedirectPathState,
);
if (
(!isLoggedIn || (isLoggedIn && !isOnAWorkspace)) &&
+284 -88
View File
@@ -106,6 +106,7 @@ msgstr "(gekies: {selectedIconKey})"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "[empty string]"
@@ -310,6 +311,11 @@ msgstr "{morphRelationCount} Objekte"
msgid "{num, selectordinal, one {{num}st} two {{num}nd} few {{num}rd} other {{num}th}}"
msgstr "{num, selectordinal, one {{num}ste} other {{num}de}}"
#. js-lingui-id: fTSz8d
#: src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownActorSelect.tsx
msgid "{numberOfSelectedItems} workspace members"
msgstr ""
#. js-lingui-id: 7kYa/u
#: src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts
msgid "{objectLabelPlural} ({totalCount})"
@@ -330,6 +336,16 @@ msgstr ""
msgid "{positionLabel} record holds priority"
msgstr "{positionLabel}-rekord het voorrang"
#. js-lingui-id: YG/wl5
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — API key not configured"
msgstr ""
#. js-lingui-id: s80lrU
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — Deprecated"
msgstr ""
#. js-lingui-id: Sxx5Hr
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "{recordCount} of {totalCount} records"
@@ -381,6 +397,11 @@ msgstr "{selectedCount} brontipes"
msgid "{serviceLabel} service is unreachable"
msgstr "{serviceLabel}-diens is onbereikbaar"
#. js-lingui-id: 8vJ+2V
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "{stepCount, plural, one {# step} other {# steps}}"
msgstr ""
#. js-lingui-id: Bzjg0/
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
msgid "{stepNumber}. Calendar"
@@ -764,6 +785,11 @@ msgstr "Voeg \"{trimmedName}\" by opsies"
msgid "Add a {objectLabelSingular}"
msgstr "Voeg 'n {objectLabelSingular} by"
#. js-lingui-id: 7W8nJr
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationGroupEditor.tsx
msgid "Add a Group"
msgstr ""
#. js-lingui-id: CZDwqQ
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
msgid "Add a new company we're in touch with (e.g. name, website, industry). Details: "
@@ -780,11 +806,6 @@ msgstr "Voeg 'n nodus by"
msgid "Add a record"
msgstr ""
#. js-lingui-id: r8W+9y
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
msgid "Add a Section"
msgstr ""
#. js-lingui-id: eMc2xs
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
msgid "Add a step"
@@ -1111,6 +1132,11 @@ msgstr "Stel die rolverwante instellings aan"
msgid "Admin"
msgstr ""
#. js-lingui-id: K2OX5h
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Admin Model Controls"
msgstr ""
#. js-lingui-id: g1in8j
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
@@ -1139,11 +1165,6 @@ msgstr "Gevorderde funksie om die werkverrigting van navrae te verbeter en uniek
msgid "Advanced filter"
msgstr "Gevorderde filter"
#. js-lingui-id: luNzWN
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Advanced model for complex planning"
msgstr ""
#. js-lingui-id: miuPUc
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
@@ -1246,6 +1267,7 @@ msgstr ""
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
#: src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectForm.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "AI"
msgstr "KI"
@@ -1257,11 +1279,6 @@ msgstr "KI"
msgid "AI Model"
msgstr "KI Model"
#. js-lingui-id: tGx4Zn
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "AI Models"
msgstr ""
#. js-lingui-id: Sfwld8
#: src/modules/ai/components/AIChatApiKeyNotConfiguredMessage.tsx
msgid "AI not configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or XAI_API_KEY in your environment."
@@ -1345,6 +1362,11 @@ msgstr ""
msgid "All Metadata"
msgstr ""
#. js-lingui-id: AJgjR+
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "All Models"
msgstr ""
#. js-lingui-id: aFE/OW
#: src/pages/settings/security/event-logs/components/EventLogFilters.tsx
#: src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableHeader.tsx
@@ -1506,6 +1528,9 @@ msgstr "'n Fout het voorgekom tydens die oplaai van die prent."
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
@@ -1602,6 +1627,11 @@ msgstr "API-sleutel"
msgid "API Key copied to clipboard"
msgstr "API-sleutel is na knipbord gekopieer"
#. js-lingui-id: jjaYji
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "API key not configured"
msgstr ""
#. js-lingui-id: Widx6n
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "API key roles"
@@ -1829,6 +1859,7 @@ msgstr "Oplopend"
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
@@ -1967,7 +1998,6 @@ msgstr "Aanhegsels"
#. js-lingui-id: EPEFrH
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "Audit Logs"
msgstr ""
@@ -2057,6 +2087,16 @@ msgstr "Outomaties skep kontakte vir mense."
msgid "Automatically create People records when receiving or sending emails"
msgstr "Outomaties skep van Persoonlike rekords by ontvang of stuur van e-posse"
#. js-lingui-id: erwsgX
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Automatically enable new models"
msgstr ""
#. js-lingui-id: fx8TeY
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Automatically mark new models as available"
msgstr ""
#. js-lingui-id: lXkUEV
#: src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerManual.tsx
msgid "Availability"
@@ -2064,10 +2104,16 @@ msgstr "Beskikbaarheid"
#. js-lingui-id: csDS2L
#: src/pages/settings/applications/SettingsApplications.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/data-model/new-object/components/SettingsAvailableStandardObjectsSection.tsx
msgid "Available"
msgstr "Beskikbaar"
#. js-lingui-id: 06gA3L
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Available as tool"
msgstr ""
#. js-lingui-id: oD38t2
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Available tools"
@@ -2239,9 +2285,9 @@ msgstr "Bruin"
msgid "Build a dashboard that shows: (1) total pipeline value by stage for the last 3 months, (2) count of deals won vs lost per month, (3) average deal size. Use our standard pipeline stages."
msgstr ""
#. js-lingui-id: 8SlslB
#. js-lingui-id: alSW5d
#: src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationJunctionForm.tsx
msgid "Build many-to-many relations. <0>Learn more</0>"
msgid "Build many-to-many relations"
msgstr ""
#. js-lingui-id: +7fBMP
@@ -2312,6 +2358,7 @@ msgstr "caldav.example.com"
#. js-lingui-id: AjVXBS
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
msgid "Calendar"
msgstr "Kalender"
@@ -2364,6 +2411,11 @@ msgstr "Kalender aansig"
msgid "Calendars"
msgstr "Kalenders"
#. js-lingui-id: qIlodj
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Calling Code"
msgstr ""
#. js-lingui-id: msssZq
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Can't change API names for standard objects"
@@ -2500,11 +2552,6 @@ msgstr "Verander nodustipe"
msgid "Change Password"
msgstr "Verander Wagwoord"
#. js-lingui-id: wRtBJP
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Change Plan"
msgstr "Verander Plan"
#. js-lingui-id: EYSFEW
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "Change subdomain?"
@@ -2602,7 +2649,7 @@ msgid "Choose the fields that will identify your records"
msgstr "Kies die velde wat jou rekords sal identifiseer"
#. js-lingui-id: hIJigY
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Choose the format used to display date value"
msgstr "Kies die formaat wat gebruik word om datumwaarde te vertoon"
@@ -2705,6 +2752,11 @@ msgstr "Kliënt geheime"
msgid "Client Settings"
msgstr "Kliëntinstellings"
#. js-lingui-id: mekEJ5
#: src/hooks/useCopyToClipboard.tsx
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
msgstr ""
#. js-lingui-id: yz7wBu
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
msgid "Close"
@@ -2747,6 +2799,7 @@ msgstr "Kodeer jou funksie"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Collapse"
@@ -2847,10 +2900,14 @@ msgstr "Voltooide werke behou vir {completedDuration}, mislukte werke behou vir
msgid "Conditions"
msgstr "Voorwaardes"
#. js-lingui-id: 14PdY0
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config"
msgstr ""
#. js-lingui-id: Vj43Y/
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config Variables"
msgstr "Konfig Veranderlikes"
@@ -2865,11 +2922,6 @@ msgstr "Konfigurasie"
msgid "Configure"
msgstr ""
#. js-lingui-id: 9px+al
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Configure AI models for routing and planning"
msgstr ""
#. js-lingui-id: +zUMwJ
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure an SSO connection"
@@ -2895,6 +2947,11 @@ msgstr "Stel CalDAV-instellings op om u kalendergebeurtenisse te sinchroniseer."
msgid "Configure date, time, number, timezone, and calendar start day"
msgstr "Konfigureer datum, tyd, nommer, tydsone, en kalender begin dag"
#. js-lingui-id: +SQwHr
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Configure default AI models and availability"
msgstr ""
#. js-lingui-id: utsXG8
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure fallback login methods for users with SSO bypass permissions"
@@ -3225,11 +3282,6 @@ msgstr "Kern"
msgid "Core Objects"
msgstr ""
#. js-lingui-id: cfa2VJ
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Core Schema"
msgstr "Kernskema"
#. js-lingui-id: I99Miw
#: src/modules/billing/components/SettingsBillingCreditsSection.tsx
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
@@ -3301,11 +3353,6 @@ msgstr "Tel unieke waardes"
msgid "Country"
msgstr "Land"
#. js-lingui-id: j2OqfX
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Country Code"
msgstr "Landkode"
#. js-lingui-id: gJdfqX
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "create"
@@ -4253,6 +4300,16 @@ msgstr "Verwyderde rekords"
msgid "Deleting this method will remove it permanently from your account."
msgstr "Deur hierdie metode te verwyder, sal dit permanent van u rekening verwyder word."
#. js-lingui-id: Ssdrw4
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated"
msgstr ""
#. js-lingui-id: 8OJZ/p
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated models"
msgstr ""
#. js-lingui-id: O3LJh6
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
@@ -4826,6 +4883,7 @@ msgstr "E-posdomeine"
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Emails"
msgstr "E-posse"
@@ -4877,6 +4935,7 @@ msgstr "Leeg"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Array"
@@ -4897,6 +4956,7 @@ msgstr "Leë Inboks"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Object"
@@ -5024,10 +5084,10 @@ msgstr ""
msgid "Enter filter"
msgstr "Voer filter in"
#. js-lingui-id: 9/30HU
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
msgid "Enter in <0>Unicode</0> format"
msgstr "Voer in <0>Unicode</0> formaat"
#. js-lingui-id: f09Lhk
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Enter in Unicode format"
msgstr ""
#. js-lingui-id: 9CjMQ7
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx
@@ -5092,6 +5152,11 @@ msgstr "Voer toetswaarde in"
msgid "Enter text"
msgstr "Voer teks in"
#. js-lingui-id: +rrO69
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
msgid "Enter text or type '/' for commands"
msgstr ""
#. js-lingui-id: yZMXC2
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
msgid "Enter text or Type '/' for commands"
@@ -5488,6 +5553,7 @@ msgstr "Verlaat Instellings"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Expand"
@@ -5787,9 +5853,9 @@ msgstr ""
msgid "Failed to save workspace instructions"
msgstr ""
#. js-lingui-id: YMSYb+
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update fast model"
#. js-lingui-id: YzURPo
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update auto-enable setting"
msgstr ""
#. js-lingui-id: P1NmNz
@@ -5797,6 +5863,27 @@ msgstr ""
msgid "Failed to update feature flag. {errorMessage}"
msgstr "Kon nie funksievlag opdateer nie. {errorMessage}"
#. js-lingui-id: 1R13Ov
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model"
msgstr ""
#. js-lingui-id: W7Ff/4
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update model availability"
msgstr ""
#. js-lingui-id: LgZlJ7
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model availability settings"
msgstr ""
#. js-lingui-id: rCUG3c
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model selection mode"
msgstr ""
#. js-lingui-id: HnBqPY
#: src/modules/billing/components/internal/MeteredPriceSelector.tsx
msgid "Failed to update price."
@@ -5812,11 +5899,6 @@ msgstr ""
msgid "Failed to update role"
msgstr "Kon nie rol opdateer nie"
#. js-lingui-id: h/0aT5
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update smart model"
msgstr ""
#. js-lingui-id: Dzh4a2
#: src/modules/settings/admin-panel/config-variables/hooks/useConfigVariableActions.ts
msgid "Failed to update variable"
@@ -5865,15 +5947,10 @@ msgid "False"
msgstr "Vals"
#. js-lingui-id: XVIZ7v
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Fast Model"
msgstr ""
#. js-lingui-id: UJHTjm
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Fast model updated successfully"
msgstr ""
#. js-lingui-id: X9kySA
#: src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx
#: src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx
@@ -6018,6 +6095,11 @@ msgstr ""
msgid "File URL is not defined"
msgstr ""
#. js-lingui-id: sER+bs
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Files"
msgstr ""
#. js-lingui-id: o7J4JM
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
@@ -6027,6 +6109,7 @@ msgstr ""
#: src/modules/views/components/ViewBarFilterButton.tsx
#: src/modules/settings/roles/components/SettingsRolesList.tsx
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
#: src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx
@@ -6121,6 +6204,7 @@ msgstr "Voornaam kan nie leeg wees nie"
#. js-lingui-id: ylQd2j
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "Flow"
msgstr "Vloei"
@@ -6255,7 +6339,9 @@ msgstr ""
#: src/pages/settings/SettingsWorkspace.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetEditorGroupsData.ts
#: src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenuOpenContent.tsx
msgid "General"
msgstr "Algemeen"
@@ -6497,11 +6583,15 @@ msgstr ""
msgid "Heading 3"
msgstr ""
#. js-lingui-id: UPqS9C
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health"
msgstr ""
#. js-lingui-id: I1IOmb
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
#: src/modules/settings/admin-panel/health-status/components/SettingsAdminHealthStatus.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health Status"
msgstr "Gesondheidstatus"
@@ -6586,6 +6676,11 @@ msgstr "Versteek groep {groupValue}"
msgid "Hide hidden groups"
msgstr "Versteek versteekte groepe"
#. js-lingui-id: i0qMbr
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Home"
msgstr ""
#. js-lingui-id: Xkd22/
#: src/modules/page-layout/utils/getWidgetTitle.ts
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
@@ -6897,6 +6992,7 @@ msgstr "Inligting"
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Input"
msgstr "Invoer"
@@ -6973,11 +7069,6 @@ msgstr "Instruksies vir KI"
msgid "Integrations - Settings"
msgstr "Integrasies - Instellings"
#. js-lingui-id: ntgzzG
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Interact with your workspace data"
msgstr "Interaksie met jou werkspasie-data"
#. js-lingui-id: jyjroS
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Interval switching has been cancelled."
@@ -7954,6 +8045,11 @@ msgstr "Maksimum reeks"
msgid "Maximum email addresses"
msgstr "Maksimum e-posadresse"
#. js-lingui-id: 9UHNQc
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Maximum execution time in seconds (1-900)"
msgstr ""
#. js-lingui-id: PAhTVY
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
msgid "Maximum files"
@@ -8086,11 +8182,6 @@ msgstr "Metadata"
msgid "Metadata file generation failed"
msgstr "Metadataleêr generasie het misluk"
#. js-lingui-id: 0BF9eC
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Metadata Schema"
msgstr "Metadataskema"
#. js-lingui-id: onCJJ6
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Metered tier switching has been cancelled."
@@ -8149,6 +8240,17 @@ msgstr ""
msgid "Mission accomplished!"
msgstr "Missie voltooi!"
#. js-lingui-id: //nm2/
#: src/pages/settings/ai/SettingsAI.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models"
msgstr ""
#. js-lingui-id: oHM560
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models available in the chat model picker"
msgstr ""
#. js-lingui-id: hty0d5
#: src/pages/settings/profile/appearance/components/DateTimeSettingsCalendarStartDaySelect.tsx
msgid "Monday"
@@ -8194,6 +8296,7 @@ msgid "months"
msgstr ""
#. js-lingui-id: 2FYpfJ
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/ui/layout/tab-list/components/TabMoreButton.tsx
msgid "More"
msgstr "Meer"
@@ -8483,6 +8586,11 @@ msgstr "Nuwe Veld"
msgid "New folder"
msgstr ""
#. js-lingui-id: 93KA8w
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationEditor.tsx
msgid "New Group"
msgstr ""
#. js-lingui-id: o8MyXb
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "New key"
@@ -8656,6 +8764,11 @@ msgstr "Geen beskikbare velde om te kies nie"
msgid "No body"
msgstr "Geen inhoud"
#. js-lingui-id: c3+z7H
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
msgid "No calling code"
msgstr ""
#. js-lingui-id: OTe3RI
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "No change detected"
@@ -8686,7 +8799,6 @@ msgstr "Geen konteks is vir hierdie versoek voorsien nie"
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
msgid "No country"
msgstr "Geen land nie"
@@ -8887,7 +8999,6 @@ msgstr "Geen maatstawedata beskikbaar"
#. js-lingui-id: UWZZdQ
#: src/pages/settings/ai/forms/components/SettingsAIAgentForm.tsx
#: src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "No models available. Please configure AI models in your workspace settings."
msgstr "Geen modelle beskikbaar nie. Stel asseblief KI-modelle in jou werkruimte-instellings op."
@@ -9124,7 +9235,13 @@ msgstr "Nie gedeel deur {notSharedByFullName} nie"
msgid "Not synced"
msgstr "Nie gesinkroniseer nie"
#. js-lingui-id: KiJn9B
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Note"
msgstr ""
#. js-lingui-id: 1DBGsz
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Notes"
msgstr "Notas"
@@ -9502,6 +9619,11 @@ msgstr ""
msgid "Organization"
msgstr "Organisasie"
#. js-lingui-id: zi/p7n
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Organization plan"
msgstr ""
#. js-lingui-id: nV6twc
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
msgid "Organize"
@@ -9514,7 +9636,7 @@ msgstr ""
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/pages/settings/admin-panel/SettingsAdmin.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemMainMenu.tsx
msgid "Other"
msgstr "Ander"
@@ -9560,6 +9682,7 @@ msgstr "Onderbreking"
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/TerminalOutput.tsx
#: src/modules/ai/components/CodeExecutionDisplay.tsx
msgid "Output"
@@ -10061,6 +10184,11 @@ msgstr "Privaatheidsbeleid"
msgid "Pro"
msgstr "Pro"
#. js-lingui-id: r5je1s
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Pro plan"
msgstr ""
#. js-lingui-id: k1ifdL
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
@@ -10196,11 +10324,6 @@ msgstr "Wagryprestasie"
msgid "Queue: {queueName}"
msgstr "Wagry: {queueName}"
#. js-lingui-id: GaAG2G
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Quick model for routing decisions"
msgstr ""
#. js-lingui-id: opSifa
#: src/modules/ai/utils/getToolDisplayMessage.ts
msgid "Ran {formattedName}"
@@ -10677,6 +10800,11 @@ msgstr "Herstel rekords"
msgid "Restore Records"
msgstr "Herstel rekords"
#. js-lingui-id: hO3AfV
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Restrict available models to a curated list"
msgstr ""
#. js-lingui-id: RD6AE9
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
msgid "Result"
@@ -10958,6 +11086,12 @@ msgstr "Soek 'n veld..."
msgid "Search a folder..."
msgstr ""
#. js-lingui-id: 8J0e5B
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Search a model..."
msgstr ""
#. js-lingui-id: WXvlVa
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "Search a role..."
@@ -11511,6 +11645,11 @@ msgstr "Gestuur en Ontvang"
msgid "Serbian (Cyrillic)"
msgstr "Serwies (Sirillies)"
#. js-lingui-id: 8ZSrlB
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Server-wide AI model availability settings"
msgstr ""
#. js-lingui-id: LUc0oL
#: src/modules/settings/security/components/SSO/SettingsSSOSAMLForm.tsx
msgid "Service Provider Details"
@@ -11593,7 +11732,6 @@ msgstr "Instelling van jou databasis..."
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
#: src/pages/settings/ai/SettingsAgentForm.tsx
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/sign-in-background-mock/components/SignInAppNavigationDrawerMock.tsx
#: src/modules/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsSection.tsx
#: src/modules/settings/roles/role/components/SettingsRole.tsx
@@ -11812,15 +11950,10 @@ msgid "Small section heading"
msgstr ""
#. js-lingui-id: 5J8ZFl
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Smart Model"
msgstr ""
#. js-lingui-id: qgvZ/2
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Smart model updated successfully"
msgstr ""
#. js-lingui-id: w+rJId
#: src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx
msgid "SMTP Configuration"
@@ -11920,6 +12053,14 @@ msgstr "Spasies en komma - {spacesAndCommaExample}"
msgid "Spanish"
msgstr "Spaans"
#. js-lingui-id: gsifzp
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Split multiple values"
msgstr ""
#. js-lingui-id: vnS6Rf
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "SSO"
@@ -12398,6 +12539,7 @@ msgid "Task Title"
msgstr "Taaktitel"
#. js-lingui-id: GtycJ/
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Tasks"
msgstr "Take"
@@ -12597,6 +12739,11 @@ msgstr "Daar is geen gekoppelde aktiwiteit by hierdie rekord nie."
msgid "There was an error while updating password."
msgstr "Daar was 'n fout terwyl die wagwoord opgedateer is."
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
msgstr ""
#. js-lingui-id: Ed99mE
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
msgid "Thinking..."
@@ -12784,6 +12931,11 @@ msgstr "Dit sal jou twee-faktor-verifikasiemetode permanent uitvee.<0/>Aangesien
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
msgstr "Dit sal die databasiswaarde na omgewing/verstekwaarde herstel. Die databasis oorskryding sal verwyder word en die stelsel sal die omgewingsinstellings gebruik."
#. js-lingui-id: f8HOUp
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thought"
msgstr ""
#. js-lingui-id: 5g/sE8
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
msgid "Tidy up"
@@ -12815,10 +12967,16 @@ msgid "Time zone"
msgstr "Tydsone"
#. js-lingui-id: cklVjM
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
msgid "Timeline"
msgstr "Tydlyn"
#. js-lingui-id: xY9s5E
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Timeout"
msgstr ""
#. js-lingui-id: 8TMaZI
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
@@ -12874,6 +13032,11 @@ msgstr "Skakel alle voorwerpregte"
msgid "Toggle all settings permissions"
msgstr "Skakel alle instellingregte"
#. js-lingui-id: 93pMSK
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Toggle model availability across all workspaces"
msgstr ""
#. js-lingui-id: WOr+hW
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
msgid "tokens"
@@ -13131,7 +13294,6 @@ msgid "Type"
msgstr "Tipe"
#. js-lingui-id: SKD2e4
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
#: src/modules/activities/components/ActivityRichTextEditor.tsx
msgid "Type '/' for commands, '@' for mentions"
msgstr ""
@@ -13172,6 +13334,11 @@ msgstr ""
msgid "Unable to Reach Back-end"
msgstr "Nie in staat om rugsteun te bereik nie"
#. js-lingui-id: EbnX+O
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Unconfigured models"
msgstr ""
#. js-lingui-id: EUHN7i
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableValueInput.tsx
msgid "Undefined"
@@ -13482,11 +13649,26 @@ msgstr "Gebruik as konsep"
msgid "Use authenticator apps and browser extensions like 1Password, Authy, Microsoft Authenticator to generate one-time passwords"
msgstr "Gebruik magtiging apps en blaaieruitbreidings soos 1Password, Authy, Microsoft Authenticator om eenmalige wagwoorde te genereer"
#. js-lingui-id: hCZsJ0
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Use best models only"
msgstr ""
#. js-lingui-id: c6uZUV
#: src/modules/object-record/record-table/empty-state/utils/getEmptyStateSubTitle.ts
msgid "Use our API or add your first {objectLabel} manually"
msgstr "Gebruik ons API of voeg jou eerste {objectLabel} handleiding by"
#. js-lingui-id: 664z2C
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for chats, agents, and complex reasoning"
msgstr ""
#. js-lingui-id: C41qgx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for lightweight tasks like title generation"
msgstr ""
#. js-lingui-id: AQVj2A
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Useful for pivot/junction tables"
@@ -13735,8 +13917,6 @@ msgid "View Logs"
msgstr ""
#. js-lingui-id: ecVcAx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
msgid "View Previous AI Chats"
@@ -13992,6 +14172,21 @@ msgstr ""
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
msgstr ""
#. js-lingui-id: 8jc/Xn
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "When enabled, AI agents and workflow automations can discover and call this function"
msgstr ""
#. js-lingui-id: i2V4DO
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "When enabled, new AI models will be available to users by default"
msgstr ""
#. js-lingui-id: 01e9rV
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "When enabled, newly added models are available to all workspaces by default"
msgstr ""
#. js-lingui-id: C51ilI
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "When the API key will expire."
@@ -14124,6 +14319,7 @@ msgid "Workspace Domain"
msgstr "Werkruimte Domein"
#. js-lingui-id: J2q6WC
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/components/EventLogTableSelector.tsx
msgid "Workspace Events"
msgstr ""
+284 -88
View File
@@ -106,6 +106,7 @@ msgstr "(المحدد: {selectedIconKey})"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "[empty string]"
@@ -310,6 +311,11 @@ msgstr "{morphRelationCount, plural, zero {لا كائنات} one {كائن وا
msgid "{num, selectordinal, one {{num}st} two {{num}nd} few {{num}rd} other {{num}th}}"
msgstr ""
#. js-lingui-id: fTSz8d
#: src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownActorSelect.tsx
msgid "{numberOfSelectedItems} workspace members"
msgstr ""
#. js-lingui-id: 7kYa/u
#: src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts
msgid "{objectLabelPlural} ({totalCount})"
@@ -330,6 +336,16 @@ msgstr ""
msgid "{positionLabel} record holds priority"
msgstr "سجل {positionLabel} له أولوية"
#. js-lingui-id: YG/wl5
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — API key not configured"
msgstr ""
#. js-lingui-id: s80lrU
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — Deprecated"
msgstr ""
#. js-lingui-id: Sxx5Hr
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "{recordCount} of {totalCount} records"
@@ -381,6 +397,11 @@ msgstr "{selectedCount, plural, zero {لا أنواع مصادر} one {نوع م
msgid "{serviceLabel} service is unreachable"
msgstr "خدمة {serviceLabel} غير قابلة للوصول"
#. js-lingui-id: 8vJ+2V
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "{stepCount, plural, one {# step} other {# steps}}"
msgstr ""
#. js-lingui-id: Bzjg0/
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
msgid "{stepNumber}. Calendar"
@@ -764,6 +785,11 @@ msgstr "أضف \"{trimmedName}\" إلى الخيارات"
msgid "Add a {objectLabelSingular}"
msgstr "أضف {objectLabelSingular}"
#. js-lingui-id: 7W8nJr
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationGroupEditor.tsx
msgid "Add a Group"
msgstr ""
#. js-lingui-id: CZDwqQ
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
msgid "Add a new company we're in touch with (e.g. name, website, industry). Details: "
@@ -780,11 +806,6 @@ msgstr "إضافة عقدة"
msgid "Add a record"
msgstr ""
#. js-lingui-id: r8W+9y
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
msgid "Add a Section"
msgstr ""
#. js-lingui-id: eMc2xs
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
msgid "Add a step"
@@ -1111,6 +1132,11 @@ msgstr "ضبط الإعدادات المتعلقة بالدور"
msgid "Admin"
msgstr ""
#. js-lingui-id: K2OX5h
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Admin Model Controls"
msgstr ""
#. js-lingui-id: g1in8j
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
@@ -1139,11 +1165,6 @@ msgstr "ميزة متقدمة لتحسين أداء الاستعلامات وف
msgid "Advanced filter"
msgstr "الفلتر المتقدم"
#. js-lingui-id: luNzWN
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Advanced model for complex planning"
msgstr ""
#. js-lingui-id: miuPUc
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
@@ -1246,6 +1267,7 @@ msgstr ""
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
#: src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectForm.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "AI"
msgstr "الذكاء الاصطناعي"
@@ -1257,11 +1279,6 @@ msgstr "الذكاء الاصطناعي"
msgid "AI Model"
msgstr "نموذج الذكاء الاصطناعي"
#. js-lingui-id: tGx4Zn
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "AI Models"
msgstr ""
#. js-lingui-id: Sfwld8
#: src/modules/ai/components/AIChatApiKeyNotConfiguredMessage.tsx
msgid "AI not configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or XAI_API_KEY in your environment."
@@ -1345,6 +1362,11 @@ msgstr ""
msgid "All Metadata"
msgstr ""
#. js-lingui-id: AJgjR+
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "All Models"
msgstr ""
#. js-lingui-id: aFE/OW
#: src/pages/settings/security/event-logs/components/EventLogFilters.tsx
#: src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableHeader.tsx
@@ -1506,6 +1528,9 @@ msgstr "حدث خطأ أثناء تحميل الصورة."
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
@@ -1602,6 +1627,11 @@ msgstr "مفتاح واجهة برمجة التطبيقات"
msgid "API Key copied to clipboard"
msgstr "تم نسخ مفتاح API إلى الحافظة"
#. js-lingui-id: jjaYji
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "API key not configured"
msgstr ""
#. js-lingui-id: Widx6n
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "API key roles"
@@ -1829,6 +1859,7 @@ msgstr "تصاعدي"
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
@@ -1967,7 +1998,6 @@ msgstr "المرفقات"
#. js-lingui-id: EPEFrH
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "Audit Logs"
msgstr ""
@@ -2057,6 +2087,16 @@ msgstr "إنشاء جهات اتصال تلقائيًا للأشخاص."
msgid "Automatically create People records when receiving or sending emails"
msgstr "إنشاء سجلات الأشخاص تلقائيًا عند استقبال أو إرسال رسائل البريد الإلكتروني"
#. js-lingui-id: erwsgX
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Automatically enable new models"
msgstr ""
#. js-lingui-id: fx8TeY
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Automatically mark new models as available"
msgstr ""
#. js-lingui-id: lXkUEV
#: src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerManual.tsx
msgid "Availability"
@@ -2064,10 +2104,16 @@ msgstr "التوفر"
#. js-lingui-id: csDS2L
#: src/pages/settings/applications/SettingsApplications.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/data-model/new-object/components/SettingsAvailableStandardObjectsSection.tsx
msgid "Available"
msgstr "متاح"
#. js-lingui-id: 06gA3L
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Available as tool"
msgstr ""
#. js-lingui-id: oD38t2
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Available tools"
@@ -2239,9 +2285,9 @@ msgstr "بني"
msgid "Build a dashboard that shows: (1) total pipeline value by stage for the last 3 months, (2) count of deals won vs lost per month, (3) average deal size. Use our standard pipeline stages."
msgstr ""
#. js-lingui-id: 8SlslB
#. js-lingui-id: alSW5d
#: src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationJunctionForm.tsx
msgid "Build many-to-many relations. <0>Learn more</0>"
msgid "Build many-to-many relations"
msgstr ""
#. js-lingui-id: +7fBMP
@@ -2312,6 +2358,7 @@ msgstr "caldav.example.com"
#. js-lingui-id: AjVXBS
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
msgid "Calendar"
msgstr "تقويم"
@@ -2364,6 +2411,11 @@ msgstr "عرض التقويم"
msgid "Calendars"
msgstr "التقاويم"
#. js-lingui-id: qIlodj
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Calling Code"
msgstr ""
#. js-lingui-id: msssZq
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Can't change API names for standard objects"
@@ -2500,11 +2552,6 @@ msgstr "تغيير نوع العقدة"
msgid "Change Password"
msgstr "تغيير كلمة السر"
#. js-lingui-id: wRtBJP
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Change Plan"
msgstr "تغيير الخطة"
#. js-lingui-id: EYSFEW
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "Change subdomain?"
@@ -2602,7 +2649,7 @@ msgid "Choose the fields that will identify your records"
msgstr "اختر الحقول التي ستحدد سجلاتك"
#. js-lingui-id: hIJigY
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Choose the format used to display date value"
msgstr "اختر التنسيق المستخدم لعرض قيمة التاريخ"
@@ -2705,6 +2752,11 @@ msgstr "سر العميل"
msgid "Client Settings"
msgstr "إعدادات العميل"
#. js-lingui-id: mekEJ5
#: src/hooks/useCopyToClipboard.tsx
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
msgstr ""
#. js-lingui-id: yz7wBu
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
msgid "Close"
@@ -2747,6 +2799,7 @@ msgstr "برمج الوظيفة الخاصة بك"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Collapse"
@@ -2847,10 +2900,14 @@ msgstr "تم الاحتفاظ بالوظائف المكتملة لمدة {comple
msgid "Conditions"
msgstr "الشروط"
#. js-lingui-id: 14PdY0
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config"
msgstr ""
#. js-lingui-id: Vj43Y/
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config Variables"
msgstr "متغيرات التكوين"
@@ -2865,11 +2922,6 @@ msgstr "التكوين"
msgid "Configure"
msgstr ""
#. js-lingui-id: 9px+al
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Configure AI models for routing and planning"
msgstr ""
#. js-lingui-id: +zUMwJ
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure an SSO connection"
@@ -2895,6 +2947,11 @@ msgstr "قم بتكوين إعدادات CalDAV لمزامنة أحداث الت
msgid "Configure date, time, number, timezone, and calendar start day"
msgstr "إعداد التاريخ والوقت والرقم والمنطقة الزمنية ويوم بدء التقويم"
#. js-lingui-id: +SQwHr
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Configure default AI models and availability"
msgstr ""
#. js-lingui-id: utsXG8
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure fallback login methods for users with SSO bypass permissions"
@@ -3225,11 +3282,6 @@ msgstr "النواة"
msgid "Core Objects"
msgstr ""
#. js-lingui-id: cfa2VJ
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Core Schema"
msgstr "المخطط الأساسي"
#. js-lingui-id: I99Miw
#: src/modules/billing/components/SettingsBillingCreditsSection.tsx
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
@@ -3301,11 +3353,6 @@ msgstr "عدّ القيم الفريدة"
msgid "Country"
msgstr "البلد"
#. js-lingui-id: j2OqfX
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Country Code"
msgstr "رمز البلد"
#. js-lingui-id: gJdfqX
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "create"
@@ -4253,6 +4300,16 @@ msgstr "السجلات المحذوفة"
msgid "Deleting this method will remove it permanently from your account."
msgstr "سيؤدي حذف هذه الطريقة إلى إزالتها نهائيًا من حسابك."
#. js-lingui-id: Ssdrw4
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated"
msgstr ""
#. js-lingui-id: 8OJZ/p
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated models"
msgstr ""
#. js-lingui-id: O3LJh6
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
@@ -4826,6 +4883,7 @@ msgstr "نطاقات البريد الإلكتروني"
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Emails"
msgstr "رسائل البريد الإلكتروني"
@@ -4877,6 +4935,7 @@ msgstr "فارغ"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Array"
@@ -4897,6 +4956,7 @@ msgstr "صندوق الوارد فارغ"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Object"
@@ -5024,10 +5084,10 @@ msgstr ""
msgid "Enter filter"
msgstr "أدخل عامل تصفية"
#. js-lingui-id: 9/30HU
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
msgid "Enter in <0>Unicode</0> format"
msgstr "إدخل بصيغة <0>Unicode</0>"
#. js-lingui-id: f09Lhk
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Enter in Unicode format"
msgstr ""
#. js-lingui-id: 9CjMQ7
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx
@@ -5092,6 +5152,11 @@ msgstr "أدخل قيمة الاختبار"
msgid "Enter text"
msgstr "أدخل نصًا"
#. js-lingui-id: +rrO69
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
msgid "Enter text or type '/' for commands"
msgstr ""
#. js-lingui-id: yZMXC2
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
msgid "Enter text or Type '/' for commands"
@@ -5488,6 +5553,7 @@ msgstr "خروج من الإعدادات"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Expand"
@@ -5787,9 +5853,9 @@ msgstr ""
msgid "Failed to save workspace instructions"
msgstr ""
#. js-lingui-id: YMSYb+
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update fast model"
#. js-lingui-id: YzURPo
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update auto-enable setting"
msgstr ""
#. js-lingui-id: P1NmNz
@@ -5797,6 +5863,27 @@ msgstr ""
msgid "Failed to update feature flag. {errorMessage}"
msgstr "فشل في تحديث علم الميزة. {errorMessage}"
#. js-lingui-id: 1R13Ov
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model"
msgstr ""
#. js-lingui-id: W7Ff/4
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update model availability"
msgstr ""
#. js-lingui-id: LgZlJ7
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model availability settings"
msgstr ""
#. js-lingui-id: rCUG3c
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model selection mode"
msgstr ""
#. js-lingui-id: HnBqPY
#: src/modules/billing/components/internal/MeteredPriceSelector.tsx
msgid "Failed to update price."
@@ -5812,11 +5899,6 @@ msgstr ""
msgid "Failed to update role"
msgstr "فشل في تحديث الدور"
#. js-lingui-id: h/0aT5
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update smart model"
msgstr ""
#. js-lingui-id: Dzh4a2
#: src/modules/settings/admin-panel/config-variables/hooks/useConfigVariableActions.ts
msgid "Failed to update variable"
@@ -5865,15 +5947,10 @@ msgid "False"
msgstr "خاطئ"
#. js-lingui-id: XVIZ7v
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Fast Model"
msgstr ""
#. js-lingui-id: UJHTjm
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Fast model updated successfully"
msgstr ""
#. js-lingui-id: X9kySA
#: src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx
#: src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx
@@ -6018,6 +6095,11 @@ msgstr ""
msgid "File URL is not defined"
msgstr ""
#. js-lingui-id: sER+bs
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Files"
msgstr ""
#. js-lingui-id: o7J4JM
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
@@ -6027,6 +6109,7 @@ msgstr ""
#: src/modules/views/components/ViewBarFilterButton.tsx
#: src/modules/settings/roles/components/SettingsRolesList.tsx
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
#: src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx
@@ -6121,6 +6204,7 @@ msgstr "لا يمكن أن يكون الاسم الأول فارغًا"
#. js-lingui-id: ylQd2j
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "Flow"
msgstr "تدفق"
@@ -6255,7 +6339,9 @@ msgstr "الرسم البياني القياسي"
#: src/pages/settings/SettingsWorkspace.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetEditorGroupsData.ts
#: src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenuOpenContent.tsx
msgid "General"
msgstr "عام"
@@ -6497,11 +6583,15 @@ msgstr ""
msgid "Heading 3"
msgstr ""
#. js-lingui-id: UPqS9C
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health"
msgstr ""
#. js-lingui-id: I1IOmb
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
#: src/modules/settings/admin-panel/health-status/components/SettingsAdminHealthStatus.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health Status"
msgstr "الحالة الصحية"
@@ -6586,6 +6676,11 @@ msgstr "إخفاء المجموعة {groupValue}"
msgid "Hide hidden groups"
msgstr "إخفاء المجموعات المخفية"
#. js-lingui-id: i0qMbr
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Home"
msgstr ""
#. js-lingui-id: Xkd22/
#: src/modules/page-layout/utils/getWidgetTitle.ts
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
@@ -6897,6 +6992,7 @@ msgstr "معلومات"
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Input"
msgstr "إدخال"
@@ -6973,11 +7069,6 @@ msgstr "تعليمات إلى الذكاء الاصطناعي"
msgid "Integrations - Settings"
msgstr "التكاملات - إعدادات"
#. js-lingui-id: ntgzzG
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Interact with your workspace data"
msgstr "تفاعل مع بيانات مساحة العمل الخاصة بك"
#. js-lingui-id: jyjroS
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Interval switching has been cancelled."
@@ -7954,6 +8045,11 @@ msgstr "المدى الأقصى"
msgid "Maximum email addresses"
msgstr "الحد الأقصى لعناوين البريد الإلكتروني"
#. js-lingui-id: 9UHNQc
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Maximum execution time in seconds (1-900)"
msgstr ""
#. js-lingui-id: PAhTVY
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
msgid "Maximum files"
@@ -8086,11 +8182,6 @@ msgstr "البيانات الوصفية"
msgid "Metadata file generation failed"
msgstr "فشل في توليد ملف البيانات الوصفية"
#. js-lingui-id: 0BF9eC
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Metadata Schema"
msgstr "مخطط البيانات الوصفية"
#. js-lingui-id: onCJJ6
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Metered tier switching has been cancelled."
@@ -8149,6 +8240,17 @@ msgstr ""
msgid "Mission accomplished!"
msgstr "تم إنجاز المهمة!"
#. js-lingui-id: //nm2/
#: src/pages/settings/ai/SettingsAI.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models"
msgstr ""
#. js-lingui-id: oHM560
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models available in the chat model picker"
msgstr ""
#. js-lingui-id: hty0d5
#: src/pages/settings/profile/appearance/components/DateTimeSettingsCalendarStartDaySelect.tsx
msgid "Monday"
@@ -8194,6 +8296,7 @@ msgid "months"
msgstr ""
#. js-lingui-id: 2FYpfJ
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/ui/layout/tab-list/components/TabMoreButton.tsx
msgid "More"
msgstr "المزيد"
@@ -8483,6 +8586,11 @@ msgstr "حقل جديد"
msgid "New folder"
msgstr ""
#. js-lingui-id: 93KA8w
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationEditor.tsx
msgid "New Group"
msgstr ""
#. js-lingui-id: o8MyXb
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "New key"
@@ -8656,6 +8764,11 @@ msgstr "لا توجد حقول متاحة للاختيار"
msgid "No body"
msgstr "لا يوجد متن"
#. js-lingui-id: c3+z7H
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
msgid "No calling code"
msgstr ""
#. js-lingui-id: OTe3RI
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "No change detected"
@@ -8686,7 +8799,6 @@ msgstr "لم يتم توفير سياق لهذا الطلب"
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
msgid "No country"
msgstr "لا دولة"
@@ -8887,7 +8999,6 @@ msgstr "لا توجد بيانات قياسات متاحة"
#. js-lingui-id: UWZZdQ
#: src/pages/settings/ai/forms/components/SettingsAIAgentForm.tsx
#: src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "No models available. Please configure AI models in your workspace settings."
msgstr "لا توجد نماذج متاحة. يرجى تهيئة نماذج الذكاء الاصطناعي في إعدادات مكان العمل الخاص بك."
@@ -9124,7 +9235,13 @@ msgstr "لم تتم المشاركة من قِبَل {notSharedByFullName}"
msgid "Not synced"
msgstr "غير متزامن"
#. js-lingui-id: KiJn9B
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Note"
msgstr ""
#. js-lingui-id: 1DBGsz
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Notes"
msgstr "الملاحظات"
@@ -9502,6 +9619,11 @@ msgstr ""
msgid "Organization"
msgstr "المؤسسة"
#. js-lingui-id: zi/p7n
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Organization plan"
msgstr ""
#. js-lingui-id: nV6twc
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
msgid "Organize"
@@ -9514,7 +9636,7 @@ msgstr ""
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/pages/settings/admin-panel/SettingsAdmin.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemMainMenu.tsx
msgid "Other"
msgstr "أخرى"
@@ -9560,6 +9682,7 @@ msgstr "انقطاع"
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/TerminalOutput.tsx
#: src/modules/ai/components/CodeExecutionDisplay.tsx
msgid "Output"
@@ -10061,6 +10184,11 @@ msgstr "\\\\"
msgid "Pro"
msgstr "محترف"
#. js-lingui-id: r5je1s
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Pro plan"
msgstr ""
#. js-lingui-id: k1ifdL
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
@@ -10196,11 +10324,6 @@ msgstr "أداء الطابور"
msgid "Queue: {queueName}"
msgstr "الطابور: {queueName}"
#. js-lingui-id: GaAG2G
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Quick model for routing decisions"
msgstr ""
#. js-lingui-id: opSifa
#: src/modules/ai/utils/getToolDisplayMessage.ts
msgid "Ran {formattedName}"
@@ -10677,6 +10800,11 @@ msgstr "استعادة السجلات"
msgid "Restore Records"
msgstr "استعادة السجلات"
#. js-lingui-id: hO3AfV
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Restrict available models to a curated list"
msgstr ""
#. js-lingui-id: RD6AE9
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
msgid "Result"
@@ -10958,6 +11086,12 @@ msgstr "ابحث عن حقل..."
msgid "Search a folder..."
msgstr ""
#. js-lingui-id: 8J0e5B
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Search a model..."
msgstr ""
#. js-lingui-id: WXvlVa
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "Search a role..."
@@ -11511,6 +11645,11 @@ msgstr "مرسل ومستلم"
msgid "Serbian (Cyrillic)"
msgstr "الصربية (السيريلية)"
#. js-lingui-id: 8ZSrlB
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Server-wide AI model availability settings"
msgstr ""
#. js-lingui-id: LUc0oL
#: src/modules/settings/security/components/SSO/SettingsSSOSAMLForm.tsx
msgid "Service Provider Details"
@@ -11593,7 +11732,6 @@ msgstr "إعداد قاعدة البيانات الخاصة بك..."
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
#: src/pages/settings/ai/SettingsAgentForm.tsx
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/sign-in-background-mock/components/SignInAppNavigationDrawerMock.tsx
#: src/modules/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsSection.tsx
#: src/modules/settings/roles/role/components/SettingsRole.tsx
@@ -11812,15 +11950,10 @@ msgid "Small section heading"
msgstr ""
#. js-lingui-id: 5J8ZFl
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Smart Model"
msgstr ""
#. js-lingui-id: qgvZ/2
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Smart model updated successfully"
msgstr ""
#. js-lingui-id: w+rJId
#: src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx
msgid "SMTP Configuration"
@@ -11920,6 +12053,14 @@ msgstr "المسافات والفاصلة - {spacesAndCommaExample}"
msgid "Spanish"
msgstr "الإسبانية"
#. js-lingui-id: gsifzp
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Split multiple values"
msgstr ""
#. js-lingui-id: vnS6Rf
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "SSO"
@@ -12398,6 +12539,7 @@ msgid "Task Title"
msgstr "عنوان المهمة"
#. js-lingui-id: GtycJ/
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Tasks"
msgstr "المهام"
@@ -12597,6 +12739,11 @@ msgstr "لا توجد أنشطة مرتبطة بهذا السجل."
msgid "There was an error while updating password."
msgstr "حدث خطأ أثناء تحديث كلمة المرور."
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
msgstr ""
#. js-lingui-id: Ed99mE
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
msgid "Thinking..."
@@ -12784,6 +12931,11 @@ msgstr "سيؤدي ذلك إلى حذف طريقة المصادقة الثنائ
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
msgstr "سيؤدي هذا إلى إعادة قيمة قاعدة البيانات إلى البيئة/القيمة الافتراضية. سيتم إزالة تجاوز قاعدة البيانات وسيستخدم النظام إعدادات البيئة."
#. js-lingui-id: f8HOUp
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thought"
msgstr ""
#. js-lingui-id: 5g/sE8
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
msgid "Tidy up"
@@ -12815,10 +12967,16 @@ msgid "Time zone"
msgstr "المنطقة الزمنية"
#. js-lingui-id: cklVjM
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
msgid "Timeline"
msgstr "الجدول الزمني"
#. js-lingui-id: xY9s5E
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Timeout"
msgstr ""
#. js-lingui-id: 8TMaZI
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
@@ -12874,6 +13032,11 @@ msgstr "التبديل بين جميع أذونات الكائنات"
msgid "Toggle all settings permissions"
msgstr "تبديل جميع أذونات الإعدادات"
#. js-lingui-id: 93pMSK
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Toggle model availability across all workspaces"
msgstr ""
#. js-lingui-id: WOr+hW
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
msgid "tokens"
@@ -13131,7 +13294,6 @@ msgid "Type"
msgstr "النوع"
#. js-lingui-id: SKD2e4
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
#: src/modules/activities/components/ActivityRichTextEditor.tsx
msgid "Type '/' for commands, '@' for mentions"
msgstr ""
@@ -13172,6 +13334,11 @@ msgstr ""
msgid "Unable to Reach Back-end"
msgstr "غير قادر على الوصول إلى الخلفية"
#. js-lingui-id: EbnX+O
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Unconfigured models"
msgstr ""
#. js-lingui-id: EUHN7i
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableValueInput.tsx
msgid "Undefined"
@@ -13482,11 +13649,26 @@ msgstr "استخدم كمسودة"
msgid "Use authenticator apps and browser extensions like 1Password, Authy, Microsoft Authenticator to generate one-time passwords"
msgstr "استخدم تطبيقات المصادقة وملحقات المتصفح مثل 1Password، Authy، Microsoft Authenticator لإنشاء كلمات مرور لمرة واحدة"
#. js-lingui-id: hCZsJ0
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Use best models only"
msgstr ""
#. js-lingui-id: c6uZUV
#: src/modules/object-record/record-table/empty-state/utils/getEmptyStateSubTitle.ts
msgid "Use our API or add your first {objectLabel} manually"
msgstr "استخدم واجهة برمجة التطبيقات لدينا أو أضف {objectLabel} الأولى يدوياً"
#. js-lingui-id: 664z2C
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for chats, agents, and complex reasoning"
msgstr ""
#. js-lingui-id: C41qgx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for lightweight tasks like title generation"
msgstr ""
#. js-lingui-id: AQVj2A
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Useful for pivot/junction tables"
@@ -13735,8 +13917,6 @@ msgid "View Logs"
msgstr ""
#. js-lingui-id: ecVcAx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
msgid "View Previous AI Chats"
@@ -13990,6 +14170,21 @@ msgstr ""
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
msgstr ""
#. js-lingui-id: 8jc/Xn
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "When enabled, AI agents and workflow automations can discover and call this function"
msgstr ""
#. js-lingui-id: i2V4DO
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "When enabled, new AI models will be available to users by default"
msgstr ""
#. js-lingui-id: 01e9rV
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "When enabled, newly added models are available to all workspaces by default"
msgstr ""
#. js-lingui-id: C51ilI
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "When the API key will expire."
@@ -14122,6 +14317,7 @@ msgid "Workspace Domain"
msgstr "نطاق مساحة العمل"
#. js-lingui-id: J2q6WC
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/components/EventLogTableSelector.tsx
msgid "Workspace Events"
msgstr ""
+284 -88
View File
@@ -106,6 +106,7 @@ msgstr "(seleccionada: {selectedIconKey})"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "[empty string]"
@@ -310,6 +311,11 @@ msgstr "{morphRelationCount} objectes"
msgid "{num, selectordinal, one {{num}st} two {{num}nd} few {{num}rd} other {{num}th}}"
msgstr "{num, selectordinal, one {{num}r} other {{num}è}}"
#. js-lingui-id: fTSz8d
#: src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownActorSelect.tsx
msgid "{numberOfSelectedItems} workspace members"
msgstr ""
#. js-lingui-id: 7kYa/u
#: src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts
msgid "{objectLabelPlural} ({totalCount})"
@@ -330,6 +336,16 @@ msgstr ""
msgid "{positionLabel} record holds priority"
msgstr "El registre {positionLabel} té prioritat"
#. js-lingui-id: YG/wl5
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — API key not configured"
msgstr ""
#. js-lingui-id: s80lrU
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — Deprecated"
msgstr ""
#. js-lingui-id: Sxx5Hr
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "{recordCount} of {totalCount} records"
@@ -381,6 +397,11 @@ msgstr "{selectedCount} tipus d'origen"
msgid "{serviceLabel} service is unreachable"
msgstr "El servei {serviceLabel} és inaccessible"
#. js-lingui-id: 8vJ+2V
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "{stepCount, plural, one {# step} other {# steps}}"
msgstr ""
#. js-lingui-id: Bzjg0/
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
msgid "{stepNumber}. Calendar"
@@ -764,6 +785,11 @@ msgstr "Afegeix \"{trimmedName}\" a les opcions"
msgid "Add a {objectLabelSingular}"
msgstr "Afegeix un {objectLabelSingular}"
#. js-lingui-id: 7W8nJr
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationGroupEditor.tsx
msgid "Add a Group"
msgstr ""
#. js-lingui-id: CZDwqQ
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
msgid "Add a new company we're in touch with (e.g. name, website, industry). Details: "
@@ -780,11 +806,6 @@ msgstr "Afegeix un node"
msgid "Add a record"
msgstr ""
#. js-lingui-id: r8W+9y
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
msgid "Add a Section"
msgstr ""
#. js-lingui-id: eMc2xs
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
msgid "Add a step"
@@ -1111,6 +1132,11 @@ msgstr "Ajusta els paràmetres relacionats amb el rol"
msgid "Admin"
msgstr ""
#. js-lingui-id: K2OX5h
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Admin Model Controls"
msgstr ""
#. js-lingui-id: g1in8j
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
@@ -1139,11 +1165,6 @@ msgstr "Funció avançada per millorar el rendiment de les consultes i fer compl
msgid "Advanced filter"
msgstr "Filtre avançat"
#. js-lingui-id: luNzWN
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Advanced model for complex planning"
msgstr ""
#. js-lingui-id: miuPUc
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
@@ -1246,6 +1267,7 @@ msgstr ""
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
#: src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectForm.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "AI"
msgstr "IA"
@@ -1257,11 +1279,6 @@ msgstr "IA"
msgid "AI Model"
msgstr "Model IA"
#. js-lingui-id: tGx4Zn
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "AI Models"
msgstr ""
#. js-lingui-id: Sfwld8
#: src/modules/ai/components/AIChatApiKeyNotConfiguredMessage.tsx
msgid "AI not configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or XAI_API_KEY in your environment."
@@ -1345,6 +1362,11 @@ msgstr ""
msgid "All Metadata"
msgstr ""
#. js-lingui-id: AJgjR+
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "All Models"
msgstr ""
#. js-lingui-id: aFE/OW
#: src/pages/settings/security/event-logs/components/EventLogFilters.tsx
#: src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableHeader.tsx
@@ -1506,6 +1528,9 @@ msgstr "S'ha produït un error en carregar la imatge."
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
@@ -1602,6 +1627,11 @@ msgstr "Clau d'API"
msgid "API Key copied to clipboard"
msgstr "La clau API s'ha copiat al porta-retalls"
#. js-lingui-id: jjaYji
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "API key not configured"
msgstr ""
#. js-lingui-id: Widx6n
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "API key roles"
@@ -1829,6 +1859,7 @@ msgstr "Ascendent"
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
@@ -1967,7 +1998,6 @@ msgstr "Adjunts"
#. js-lingui-id: EPEFrH
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "Audit Logs"
msgstr ""
@@ -2057,6 +2087,16 @@ msgstr "Crea automàticament contactes per a persones."
msgid "Automatically create People records when receiving or sending emails"
msgstr "Crear automàticament registres de Persones quan es reben o s'envien correus electrònics"
#. js-lingui-id: erwsgX
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Automatically enable new models"
msgstr ""
#. js-lingui-id: fx8TeY
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Automatically mark new models as available"
msgstr ""
#. js-lingui-id: lXkUEV
#: src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerManual.tsx
msgid "Availability"
@@ -2064,10 +2104,16 @@ msgstr "Disponibilitat"
#. js-lingui-id: csDS2L
#: src/pages/settings/applications/SettingsApplications.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/data-model/new-object/components/SettingsAvailableStandardObjectsSection.tsx
msgid "Available"
msgstr "Disponible"
#. js-lingui-id: 06gA3L
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Available as tool"
msgstr ""
#. js-lingui-id: oD38t2
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Available tools"
@@ -2239,9 +2285,9 @@ msgstr "Marró"
msgid "Build a dashboard that shows: (1) total pipeline value by stage for the last 3 months, (2) count of deals won vs lost per month, (3) average deal size. Use our standard pipeline stages."
msgstr ""
#. js-lingui-id: 8SlslB
#. js-lingui-id: alSW5d
#: src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationJunctionForm.tsx
msgid "Build many-to-many relations. <0>Learn more</0>"
msgid "Build many-to-many relations"
msgstr ""
#. js-lingui-id: +7fBMP
@@ -2312,6 +2358,7 @@ msgstr "caldav.example.com"
#. js-lingui-id: AjVXBS
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
msgid "Calendar"
msgstr "Calendari"
@@ -2364,6 +2411,11 @@ msgstr "Vista de calendari"
msgid "Calendars"
msgstr "Calendaris"
#. js-lingui-id: qIlodj
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Calling Code"
msgstr ""
#. js-lingui-id: msssZq
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Can't change API names for standard objects"
@@ -2500,11 +2552,6 @@ msgstr "Canvia el tipus de node"
msgid "Change Password"
msgstr "Canvia la contrasenya"
#. js-lingui-id: wRtBJP
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Change Plan"
msgstr "Canviar Pla"
#. js-lingui-id: EYSFEW
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "Change subdomain?"
@@ -2602,7 +2649,7 @@ msgid "Choose the fields that will identify your records"
msgstr "Trieu els camps que identificaran els vostres registres"
#. js-lingui-id: hIJigY
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Choose the format used to display date value"
msgstr "Tria el format utilitzat per mostrar el valor de la data"
@@ -2705,6 +2752,11 @@ msgstr "Secret del client"
msgid "Client Settings"
msgstr "Configuració del client"
#. js-lingui-id: mekEJ5
#: src/hooks/useCopyToClipboard.tsx
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
msgstr ""
#. js-lingui-id: yz7wBu
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
msgid "Close"
@@ -2747,6 +2799,7 @@ msgstr "Programar la teva funció"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Collapse"
@@ -2847,10 +2900,14 @@ msgstr "Feines completades guardades per {completedDuration}, feines fallades gu
msgid "Conditions"
msgstr "Condicions"
#. js-lingui-id: 14PdY0
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config"
msgstr ""
#. js-lingui-id: Vj43Y/
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config Variables"
msgstr "Variables de Configuració"
@@ -2865,11 +2922,6 @@ msgstr "Configuració"
msgid "Configure"
msgstr ""
#. js-lingui-id: 9px+al
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Configure AI models for routing and planning"
msgstr ""
#. js-lingui-id: +zUMwJ
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure an SSO connection"
@@ -2895,6 +2947,11 @@ msgstr "Configureu la configuració de CalDAV per sincronitzar els vostres esdev
msgid "Configure date, time, number, timezone, and calendar start day"
msgstr "Configura la data, hora, número, fus horari i dia d'inici del calendari"
#. js-lingui-id: +SQwHr
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Configure default AI models and availability"
msgstr ""
#. js-lingui-id: utsXG8
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure fallback login methods for users with SSO bypass permissions"
@@ -3225,11 +3282,6 @@ msgstr "Nucli"
msgid "Core Objects"
msgstr ""
#. js-lingui-id: cfa2VJ
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Core Schema"
msgstr "Esquema del nucli"
#. js-lingui-id: I99Miw
#: src/modules/billing/components/SettingsBillingCreditsSection.tsx
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
@@ -3301,11 +3353,6 @@ msgstr "Compta valors únics"
msgid "Country"
msgstr "País"
#. js-lingui-id: j2OqfX
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Country Code"
msgstr "Codi de país"
#. js-lingui-id: gJdfqX
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "create"
@@ -4253,6 +4300,16 @@ msgstr "Registres suprimits"
msgid "Deleting this method will remove it permanently from your account."
msgstr "Eliminar aquest mètode el eliminarà permanentment del teu compte."
#. js-lingui-id: Ssdrw4
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated"
msgstr ""
#. js-lingui-id: 8OJZ/p
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated models"
msgstr ""
#. js-lingui-id: O3LJh6
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
@@ -4826,6 +4883,7 @@ msgstr "Dominis de correu"
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Emails"
msgstr "Correus electrònics"
@@ -4877,6 +4935,7 @@ msgstr "Buit"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Array"
@@ -4897,6 +4956,7 @@ msgstr "Bústia buida"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Object"
@@ -5024,10 +5084,10 @@ msgstr ""
msgid "Enter filter"
msgstr "Introdueix el filtre"
#. js-lingui-id: 9/30HU
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
msgid "Enter in <0>Unicode</0> format"
msgstr "Introdueix en format <0>Unicode</0>"
#. js-lingui-id: f09Lhk
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Enter in Unicode format"
msgstr ""
#. js-lingui-id: 9CjMQ7
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx
@@ -5092,6 +5152,11 @@ msgstr "Introdueix el valor de prova"
msgid "Enter text"
msgstr "Introdueix el text"
#. js-lingui-id: +rrO69
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
msgid "Enter text or type '/' for commands"
msgstr ""
#. js-lingui-id: yZMXC2
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
msgid "Enter text or Type '/' for commands"
@@ -5488,6 +5553,7 @@ msgstr "Sortir de la configuració"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Expand"
@@ -5787,9 +5853,9 @@ msgstr ""
msgid "Failed to save workspace instructions"
msgstr ""
#. js-lingui-id: YMSYb+
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update fast model"
#. js-lingui-id: YzURPo
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update auto-enable setting"
msgstr ""
#. js-lingui-id: P1NmNz
@@ -5797,6 +5863,27 @@ msgstr ""
msgid "Failed to update feature flag. {errorMessage}"
msgstr "No s'ha pogut actualitzar el feature flag. {errorMessage}"
#. js-lingui-id: 1R13Ov
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model"
msgstr ""
#. js-lingui-id: W7Ff/4
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update model availability"
msgstr ""
#. js-lingui-id: LgZlJ7
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model availability settings"
msgstr ""
#. js-lingui-id: rCUG3c
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model selection mode"
msgstr ""
#. js-lingui-id: HnBqPY
#: src/modules/billing/components/internal/MeteredPriceSelector.tsx
msgid "Failed to update price."
@@ -5812,11 +5899,6 @@ msgstr ""
msgid "Failed to update role"
msgstr "Ha fallat l'actualització del rol"
#. js-lingui-id: h/0aT5
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update smart model"
msgstr ""
#. js-lingui-id: Dzh4a2
#: src/modules/settings/admin-panel/config-variables/hooks/useConfigVariableActions.ts
msgid "Failed to update variable"
@@ -5865,15 +5947,10 @@ msgid "False"
msgstr "Fals"
#. js-lingui-id: XVIZ7v
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Fast Model"
msgstr ""
#. js-lingui-id: UJHTjm
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Fast model updated successfully"
msgstr ""
#. js-lingui-id: X9kySA
#: src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx
#: src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx
@@ -6018,6 +6095,11 @@ msgstr ""
msgid "File URL is not defined"
msgstr ""
#. js-lingui-id: sER+bs
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Files"
msgstr ""
#. js-lingui-id: o7J4JM
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
@@ -6027,6 +6109,7 @@ msgstr ""
#: src/modules/views/components/ViewBarFilterButton.tsx
#: src/modules/settings/roles/components/SettingsRolesList.tsx
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
#: src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx
@@ -6121,6 +6204,7 @@ msgstr "El nom no pot estar buit"
#. js-lingui-id: ylQd2j
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "Flow"
msgstr "Flux"
@@ -6255,7 +6339,9 @@ msgstr "Gràfic de mesurador"
#: src/pages/settings/SettingsWorkspace.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetEditorGroupsData.ts
#: src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenuOpenContent.tsx
msgid "General"
msgstr "General"
@@ -6497,11 +6583,15 @@ msgstr ""
msgid "Heading 3"
msgstr ""
#. js-lingui-id: UPqS9C
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health"
msgstr ""
#. js-lingui-id: I1IOmb
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
#: src/modules/settings/admin-panel/health-status/components/SettingsAdminHealthStatus.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health Status"
msgstr "Estat de salut"
@@ -6586,6 +6676,11 @@ msgstr "Amaga el grup {groupValue}"
msgid "Hide hidden groups"
msgstr "Amaga grups ocults"
#. js-lingui-id: i0qMbr
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Home"
msgstr ""
#. js-lingui-id: Xkd22/
#: src/modules/page-layout/utils/getWidgetTitle.ts
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
@@ -6897,6 +6992,7 @@ msgstr "Informació"
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Input"
msgstr "Entrada"
@@ -6973,11 +7069,6 @@ msgstr "Instruccions per a la IA"
msgid "Integrations - Settings"
msgstr "Integracions - Configuració"
#. js-lingui-id: ntgzzG
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Interact with your workspace data"
msgstr "Interactua amb les dades del teu espai de treball"
#. js-lingui-id: jyjroS
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Interval switching has been cancelled."
@@ -7954,6 +8045,11 @@ msgstr "Rang màxim"
msgid "Maximum email addresses"
msgstr "Quantitat màxima de correus electrònics"
#. js-lingui-id: 9UHNQc
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Maximum execution time in seconds (1-900)"
msgstr ""
#. js-lingui-id: PAhTVY
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
msgid "Maximum files"
@@ -8086,11 +8182,6 @@ msgstr "Metadades"
msgid "Metadata file generation failed"
msgstr "Error en la generació del fitxer de metadades"
#. js-lingui-id: 0BF9eC
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Metadata Schema"
msgstr "Esquema de metadades"
#. js-lingui-id: onCJJ6
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Metered tier switching has been cancelled."
@@ -8149,6 +8240,17 @@ msgstr ""
msgid "Mission accomplished!"
msgstr "Missió acomplerta!"
#. js-lingui-id: //nm2/
#: src/pages/settings/ai/SettingsAI.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models"
msgstr ""
#. js-lingui-id: oHM560
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models available in the chat model picker"
msgstr ""
#. js-lingui-id: hty0d5
#: src/pages/settings/profile/appearance/components/DateTimeSettingsCalendarStartDaySelect.tsx
msgid "Monday"
@@ -8194,6 +8296,7 @@ msgid "months"
msgstr ""
#. js-lingui-id: 2FYpfJ
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/ui/layout/tab-list/components/TabMoreButton.tsx
msgid "More"
msgstr "Més"
@@ -8483,6 +8586,11 @@ msgstr "Nou camp"
msgid "New folder"
msgstr ""
#. js-lingui-id: 93KA8w
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationEditor.tsx
msgid "New Group"
msgstr ""
#. js-lingui-id: o8MyXb
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "New key"
@@ -8656,6 +8764,11 @@ msgstr "No hi ha camps disponibles per seleccionar"
msgid "No body"
msgstr "Sense cos"
#. js-lingui-id: c3+z7H
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
msgid "No calling code"
msgstr ""
#. js-lingui-id: OTe3RI
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "No change detected"
@@ -8686,7 +8799,6 @@ msgstr "No s'ha proporcionat cap context per a aquesta sol·licitud"
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
msgid "No country"
msgstr "Sense país"
@@ -8887,7 +8999,6 @@ msgstr "No hi ha dades de mètriques disponibles"
#. js-lingui-id: UWZZdQ
#: src/pages/settings/ai/forms/components/SettingsAIAgentForm.tsx
#: src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "No models available. Please configure AI models in your workspace settings."
msgstr "No hi ha models disponibles. Si us plau, configureu models d'IA a la configuració del vostre espai de treball."
@@ -9124,7 +9235,13 @@ msgstr "No compartit per {notSharedByFullName}"
msgid "Not synced"
msgstr "No sincronitzat"
#. js-lingui-id: KiJn9B
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Note"
msgstr ""
#. js-lingui-id: 1DBGsz
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Notes"
msgstr "Notes"
@@ -9502,6 +9619,11 @@ msgstr ""
msgid "Organization"
msgstr "Organització"
#. js-lingui-id: zi/p7n
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Organization plan"
msgstr ""
#. js-lingui-id: nV6twc
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
msgid "Organize"
@@ -9514,7 +9636,7 @@ msgstr ""
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/pages/settings/admin-panel/SettingsAdmin.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemMainMenu.tsx
msgid "Other"
msgstr "Altres"
@@ -9560,6 +9682,7 @@ msgstr "Interrupció"
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/TerminalOutput.tsx
#: src/modules/ai/components/CodeExecutionDisplay.tsx
msgid "Output"
@@ -10061,6 +10184,11 @@ msgstr "Política de Privacitat"
msgid "Pro"
msgstr "Pro"
#. js-lingui-id: r5je1s
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Pro plan"
msgstr ""
#. js-lingui-id: k1ifdL
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
@@ -10196,11 +10324,6 @@ msgstr "Rendiment de la cua"
msgid "Queue: {queueName}"
msgstr "Cua: {queueName}"
#. js-lingui-id: GaAG2G
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Quick model for routing decisions"
msgstr ""
#. js-lingui-id: opSifa
#: src/modules/ai/utils/getToolDisplayMessage.ts
msgid "Ran {formattedName}"
@@ -10677,6 +10800,11 @@ msgstr "Restaurar registres"
msgid "Restore Records"
msgstr "Restaura Registres"
#. js-lingui-id: hO3AfV
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Restrict available models to a curated list"
msgstr ""
#. js-lingui-id: RD6AE9
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
msgid "Result"
@@ -10958,6 +11086,12 @@ msgstr "Cerca un camp..."
msgid "Search a folder..."
msgstr ""
#. js-lingui-id: 8J0e5B
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Search a model..."
msgstr ""
#. js-lingui-id: WXvlVa
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "Search a role..."
@@ -11511,6 +11645,11 @@ msgstr "Enviat i rebut"
msgid "Serbian (Cyrillic)"
msgstr "Serbi (ciríl·lic)"
#. js-lingui-id: 8ZSrlB
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Server-wide AI model availability settings"
msgstr ""
#. js-lingui-id: LUc0oL
#: src/modules/settings/security/components/SSO/SettingsSSOSAMLForm.tsx
msgid "Service Provider Details"
@@ -11593,7 +11732,6 @@ msgstr "Configurant la teva base de dades..."
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
#: src/pages/settings/ai/SettingsAgentForm.tsx
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/sign-in-background-mock/components/SignInAppNavigationDrawerMock.tsx
#: src/modules/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsSection.tsx
#: src/modules/settings/roles/role/components/SettingsRole.tsx
@@ -11812,15 +11950,10 @@ msgid "Small section heading"
msgstr ""
#. js-lingui-id: 5J8ZFl
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Smart Model"
msgstr ""
#. js-lingui-id: qgvZ/2
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Smart model updated successfully"
msgstr ""
#. js-lingui-id: w+rJId
#: src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx
msgid "SMTP Configuration"
@@ -11920,6 +12053,14 @@ msgstr "Espais i coma - {spacesAndCommaExample}"
msgid "Spanish"
msgstr "Espanyol"
#. js-lingui-id: gsifzp
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Split multiple values"
msgstr ""
#. js-lingui-id: vnS6Rf
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "SSO"
@@ -12398,6 +12539,7 @@ msgid "Task Title"
msgstr "Títol de la tasca"
#. js-lingui-id: GtycJ/
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Tasks"
msgstr "Tasques"
@@ -12597,6 +12739,11 @@ msgstr "No hi ha cap activitat associada amb aquest registre."
msgid "There was an error while updating password."
msgstr "S'ha produït un error en actualitzar la contrasenya."
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
msgstr ""
#. js-lingui-id: Ed99mE
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
msgid "Thinking..."
@@ -12784,6 +12931,11 @@ msgstr "Això suprimirà permanentment el teu mètode d'autenticació de dos fac
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
msgstr "Això revertirà el valor de la base de dades al valor d'entorn/predeterminat. L'anul·lació de la base de dades serà eliminada i el sistema utilitzarà la configuració de l'entorn."
#. js-lingui-id: f8HOUp
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thought"
msgstr ""
#. js-lingui-id: 5g/sE8
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
msgid "Tidy up"
@@ -12815,10 +12967,16 @@ msgid "Time zone"
msgstr "Zona horària"
#. js-lingui-id: cklVjM
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
msgid "Timeline"
msgstr "Cronologia"
#. js-lingui-id: xY9s5E
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Timeout"
msgstr ""
#. js-lingui-id: 8TMaZI
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
@@ -12874,6 +13032,11 @@ msgstr "Alternar els permisos de tots els objectes"
msgid "Toggle all settings permissions"
msgstr "Alternar tots els permisos de configuració"
#. js-lingui-id: 93pMSK
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Toggle model availability across all workspaces"
msgstr ""
#. js-lingui-id: WOr+hW
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
msgid "tokens"
@@ -13131,7 +13294,6 @@ msgid "Type"
msgstr "Tipus"
#. js-lingui-id: SKD2e4
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
#: src/modules/activities/components/ActivityRichTextEditor.tsx
msgid "Type '/' for commands, '@' for mentions"
msgstr ""
@@ -13172,6 +13334,11 @@ msgstr ""
msgid "Unable to Reach Back-end"
msgstr "No es pot contactar amb el backend"
#. js-lingui-id: EbnX+O
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Unconfigured models"
msgstr ""
#. js-lingui-id: EUHN7i
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableValueInput.tsx
msgid "Undefined"
@@ -13482,11 +13649,26 @@ msgstr "Utilitzar com a esborrany"
msgid "Use authenticator apps and browser extensions like 1Password, Authy, Microsoft Authenticator to generate one-time passwords"
msgstr "Utilitza aplicacions d'autenticació i extensions de navegador com 1Password, Authy, Microsoft Authenticator per generar contrasenyes d'un sol ús"
#. js-lingui-id: hCZsJ0
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Use best models only"
msgstr ""
#. js-lingui-id: c6uZUV
#: src/modules/object-record/record-table/empty-state/utils/getEmptyStateSubTitle.ts
msgid "Use our API or add your first {objectLabel} manually"
msgstr "Utilitzeu la nostra API o afegiu el vostre primer {objectLabel} manualment"
#. js-lingui-id: 664z2C
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for chats, agents, and complex reasoning"
msgstr ""
#. js-lingui-id: C41qgx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for lightweight tasks like title generation"
msgstr ""
#. js-lingui-id: AQVj2A
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Useful for pivot/junction tables"
@@ -13735,8 +13917,6 @@ msgid "View Logs"
msgstr ""
#. js-lingui-id: ecVcAx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
msgid "View Previous AI Chats"
@@ -13992,6 +14172,21 @@ msgstr ""
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
msgstr ""
#. js-lingui-id: 8jc/Xn
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "When enabled, AI agents and workflow automations can discover and call this function"
msgstr ""
#. js-lingui-id: i2V4DO
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "When enabled, new AI models will be available to users by default"
msgstr ""
#. js-lingui-id: 01e9rV
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "When enabled, newly added models are available to all workspaces by default"
msgstr ""
#. js-lingui-id: C51ilI
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "When the API key will expire."
@@ -14124,6 +14319,7 @@ msgid "Workspace Domain"
msgstr "Domini de l'espai de treball"
#. js-lingui-id: J2q6WC
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/components/EventLogTableSelector.tsx
msgid "Workspace Events"
msgstr ""
+284 -88
View File
@@ -106,6 +106,7 @@ msgstr "(vybráno: {selectedIconKey})"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "[empty string]"
@@ -310,6 +311,11 @@ msgstr "{morphRelationCount} objektů"
msgid "{num, selectordinal, one {{num}st} two {{num}nd} few {{num}rd} other {{num}th}}"
msgstr "{num, selectordinal, one {{num}.} few {{num}.} many {{num}.} other {{num}.}}"
#. js-lingui-id: fTSz8d
#: src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownActorSelect.tsx
msgid "{numberOfSelectedItems} workspace members"
msgstr ""
#. js-lingui-id: 7kYa/u
#: src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts
msgid "{objectLabelPlural} ({totalCount})"
@@ -330,6 +336,16 @@ msgstr ""
msgid "{positionLabel} record holds priority"
msgstr "Záznam {positionLabel} má prioritu"
#. js-lingui-id: YG/wl5
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — API key not configured"
msgstr ""
#. js-lingui-id: s80lrU
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — Deprecated"
msgstr ""
#. js-lingui-id: Sxx5Hr
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "{recordCount} of {totalCount} records"
@@ -381,6 +397,11 @@ msgstr "{selectedCount} typů zdrojů"
msgid "{serviceLabel} service is unreachable"
msgstr "Služba {serviceLabel} je nedostupná"
#. js-lingui-id: 8vJ+2V
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "{stepCount, plural, one {# step} other {# steps}}"
msgstr ""
#. js-lingui-id: Bzjg0/
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
msgid "{stepNumber}. Calendar"
@@ -764,6 +785,11 @@ msgstr "Přidat \"{trimmedName}\" do možností"
msgid "Add a {objectLabelSingular}"
msgstr "Přidat {objectLabelSingular}"
#. js-lingui-id: 7W8nJr
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationGroupEditor.tsx
msgid "Add a Group"
msgstr ""
#. js-lingui-id: CZDwqQ
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
msgid "Add a new company we're in touch with (e.g. name, website, industry). Details: "
@@ -780,11 +806,6 @@ msgstr "Přidat uzel"
msgid "Add a record"
msgstr ""
#. js-lingui-id: r8W+9y
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
msgid "Add a Section"
msgstr ""
#. js-lingui-id: eMc2xs
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
msgid "Add a step"
@@ -1111,6 +1132,11 @@ msgstr "Upravit nastavení související s rolí"
msgid "Admin"
msgstr ""
#. js-lingui-id: K2OX5h
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Admin Model Controls"
msgstr ""
#. js-lingui-id: g1in8j
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
@@ -1139,11 +1165,6 @@ msgstr "Pokročilá funkce pro zlepšení výkonu dotazů a prosazení jedinečn
msgid "Advanced filter"
msgstr "Pokročilý filtr"
#. js-lingui-id: luNzWN
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Advanced model for complex planning"
msgstr ""
#. js-lingui-id: miuPUc
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
@@ -1246,6 +1267,7 @@ msgstr ""
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
#: src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectForm.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "AI"
msgstr "AI"
@@ -1257,11 +1279,6 @@ msgstr "AI"
msgid "AI Model"
msgstr "AI Model"
#. js-lingui-id: tGx4Zn
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "AI Models"
msgstr ""
#. js-lingui-id: Sfwld8
#: src/modules/ai/components/AIChatApiKeyNotConfiguredMessage.tsx
msgid "AI not configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or XAI_API_KEY in your environment."
@@ -1345,6 +1362,11 @@ msgstr ""
msgid "All Metadata"
msgstr ""
#. js-lingui-id: AJgjR+
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "All Models"
msgstr ""
#. js-lingui-id: aFE/OW
#: src/pages/settings/security/event-logs/components/EventLogFilters.tsx
#: src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableHeader.tsx
@@ -1506,6 +1528,9 @@ msgstr "Při nahrávání obrázku došlo k chybě."
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
@@ -1602,6 +1627,11 @@ msgstr "API klíč"
msgid "API Key copied to clipboard"
msgstr "Klíč API zkopírován do schránky"
#. js-lingui-id: jjaYji
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "API key not configured"
msgstr ""
#. js-lingui-id: Widx6n
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "API key roles"
@@ -1829,6 +1859,7 @@ msgstr "Vzestupně"
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
@@ -1967,7 +1998,6 @@ msgstr "Přílohy"
#. js-lingui-id: EPEFrH
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "Audit Logs"
msgstr ""
@@ -2057,6 +2087,16 @@ msgstr "Automaticky vytvářet kontakty pro lidi."
msgid "Automatically create People records when receiving or sending emails"
msgstr "Automaticky vytvářet záznamy lidí při přijímání nebo odesílání emailů"
#. js-lingui-id: erwsgX
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Automatically enable new models"
msgstr ""
#. js-lingui-id: fx8TeY
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Automatically mark new models as available"
msgstr ""
#. js-lingui-id: lXkUEV
#: src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerManual.tsx
msgid "Availability"
@@ -2064,10 +2104,16 @@ msgstr "Dostupnost"
#. js-lingui-id: csDS2L
#: src/pages/settings/applications/SettingsApplications.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/data-model/new-object/components/SettingsAvailableStandardObjectsSection.tsx
msgid "Available"
msgstr "Dostupný"
#. js-lingui-id: 06gA3L
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Available as tool"
msgstr ""
#. js-lingui-id: oD38t2
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Available tools"
@@ -2239,9 +2285,9 @@ msgstr "Hnědá"
msgid "Build a dashboard that shows: (1) total pipeline value by stage for the last 3 months, (2) count of deals won vs lost per month, (3) average deal size. Use our standard pipeline stages."
msgstr ""
#. js-lingui-id: 8SlslB
#. js-lingui-id: alSW5d
#: src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationJunctionForm.tsx
msgid "Build many-to-many relations. <0>Learn more</0>"
msgid "Build many-to-many relations"
msgstr ""
#. js-lingui-id: +7fBMP
@@ -2312,6 +2358,7 @@ msgstr "caldav.example.com"
#. js-lingui-id: AjVXBS
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
msgid "Calendar"
msgstr "Kalendář"
@@ -2364,6 +2411,11 @@ msgstr "Kalendářní zobrazení"
msgid "Calendars"
msgstr "Kalendáře"
#. js-lingui-id: qIlodj
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Calling Code"
msgstr ""
#. js-lingui-id: msssZq
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Can't change API names for standard objects"
@@ -2500,11 +2552,6 @@ msgstr "Změnit typ uzlu"
msgid "Change Password"
msgstr "Změnit heslo"
#. js-lingui-id: wRtBJP
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Change Plan"
msgstr "Změnit plán"
#. js-lingui-id: EYSFEW
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "Change subdomain?"
@@ -2602,7 +2649,7 @@ msgid "Choose the fields that will identify your records"
msgstr "Vyberte pole, která budou identifikovat vaše záznamy"
#. js-lingui-id: hIJigY
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Choose the format used to display date value"
msgstr "Vyberte formát použitý k zobrazení datumové hodnoty"
@@ -2705,6 +2752,11 @@ msgstr "Klientský tajný klíč"
msgid "Client Settings"
msgstr "Nastavení klienta"
#. js-lingui-id: mekEJ5
#: src/hooks/useCopyToClipboard.tsx
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
msgstr ""
#. js-lingui-id: yz7wBu
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
msgid "Close"
@@ -2747,6 +2799,7 @@ msgstr "Naprogramujte svou funkci"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Collapse"
@@ -2847,10 +2900,14 @@ msgstr "Dokončené úlohy uchovány po dobu {completedDuration}, neúspěšné
msgid "Conditions"
msgstr "Podmínky"
#. js-lingui-id: 14PdY0
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config"
msgstr ""
#. js-lingui-id: Vj43Y/
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config Variables"
msgstr "Konfigurační proměnné"
@@ -2865,11 +2922,6 @@ msgstr "Konfigurace"
msgid "Configure"
msgstr ""
#. js-lingui-id: 9px+al
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Configure AI models for routing and planning"
msgstr ""
#. js-lingui-id: +zUMwJ
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure an SSO connection"
@@ -2895,6 +2947,11 @@ msgstr "Konfigurujte nastavení CalDAV pro synchronizaci událostí kalendáře.
msgid "Configure date, time, number, timezone, and calendar start day"
msgstr "Nastavit datum, čas, číslo, časovou zónu a počáteční den kalendáře"
#. js-lingui-id: +SQwHr
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Configure default AI models and availability"
msgstr ""
#. js-lingui-id: utsXG8
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure fallback login methods for users with SSO bypass permissions"
@@ -3225,11 +3282,6 @@ msgstr "Jádro"
msgid "Core Objects"
msgstr ""
#. js-lingui-id: cfa2VJ
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Core Schema"
msgstr "Základní schéma"
#. js-lingui-id: I99Miw
#: src/modules/billing/components/SettingsBillingCreditsSection.tsx
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
@@ -3301,11 +3353,6 @@ msgstr "Počet unikátních hodnot"
msgid "Country"
msgstr "Země"
#. js-lingui-id: j2OqfX
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Country Code"
msgstr "Kód země"
#. js-lingui-id: gJdfqX
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "create"
@@ -4253,6 +4300,16 @@ msgstr "Smazané záznamy"
msgid "Deleting this method will remove it permanently from your account."
msgstr "Smazáním této metody ji trvale odeberete ze svého účtu."
#. js-lingui-id: Ssdrw4
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated"
msgstr ""
#. js-lingui-id: 8OJZ/p
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated models"
msgstr ""
#. js-lingui-id: O3LJh6
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
@@ -4826,6 +4883,7 @@ msgstr "E-mailové domény"
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Emails"
msgstr "E-maily"
@@ -4877,6 +4935,7 @@ msgstr "Prázdné"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Array"
@@ -4897,6 +4956,7 @@ msgstr "Prázdná schránka"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Object"
@@ -5024,10 +5084,10 @@ msgstr ""
msgid "Enter filter"
msgstr "Zadejte filtr"
#. js-lingui-id: 9/30HU
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
msgid "Enter in <0>Unicode</0> format"
msgstr "Zadejte v <0>Unicode</0> formátu"
#. js-lingui-id: f09Lhk
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Enter in Unicode format"
msgstr ""
#. js-lingui-id: 9CjMQ7
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx
@@ -5092,6 +5152,11 @@ msgstr "Zadejte testovací hodnotu"
msgid "Enter text"
msgstr "Zadejte text"
#. js-lingui-id: +rrO69
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
msgid "Enter text or type '/' for commands"
msgstr ""
#. js-lingui-id: yZMXC2
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
msgid "Enter text or Type '/' for commands"
@@ -5488,6 +5553,7 @@ msgstr "Opustit nastavení"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Expand"
@@ -5787,9 +5853,9 @@ msgstr ""
msgid "Failed to save workspace instructions"
msgstr ""
#. js-lingui-id: YMSYb+
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update fast model"
#. js-lingui-id: YzURPo
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update auto-enable setting"
msgstr ""
#. js-lingui-id: P1NmNz
@@ -5797,6 +5863,27 @@ msgstr ""
msgid "Failed to update feature flag. {errorMessage}"
msgstr "Nepodařilo se aktualizovat příznak funkce. {errorMessage}"
#. js-lingui-id: 1R13Ov
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model"
msgstr ""
#. js-lingui-id: W7Ff/4
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update model availability"
msgstr ""
#. js-lingui-id: LgZlJ7
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model availability settings"
msgstr ""
#. js-lingui-id: rCUG3c
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model selection mode"
msgstr ""
#. js-lingui-id: HnBqPY
#: src/modules/billing/components/internal/MeteredPriceSelector.tsx
msgid "Failed to update price."
@@ -5812,11 +5899,6 @@ msgstr ""
msgid "Failed to update role"
msgstr "Nepodařilo se aktualizovat roli"
#. js-lingui-id: h/0aT5
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update smart model"
msgstr ""
#. js-lingui-id: Dzh4a2
#: src/modules/settings/admin-panel/config-variables/hooks/useConfigVariableActions.ts
msgid "Failed to update variable"
@@ -5865,15 +5947,10 @@ msgid "False"
msgstr "Nepravdivé"
#. js-lingui-id: XVIZ7v
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Fast Model"
msgstr ""
#. js-lingui-id: UJHTjm
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Fast model updated successfully"
msgstr ""
#. js-lingui-id: X9kySA
#: src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx
#: src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx
@@ -6018,6 +6095,11 @@ msgstr ""
msgid "File URL is not defined"
msgstr ""
#. js-lingui-id: sER+bs
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Files"
msgstr ""
#. js-lingui-id: o7J4JM
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
@@ -6027,6 +6109,7 @@ msgstr ""
#: src/modules/views/components/ViewBarFilterButton.tsx
#: src/modules/settings/roles/components/SettingsRolesList.tsx
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
#: src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx
@@ -6121,6 +6204,7 @@ msgstr "Křestní jméno nesmí být prázdné"
#. js-lingui-id: ylQd2j
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "Flow"
msgstr "Tok"
@@ -6255,7 +6339,9 @@ msgstr "Ukazatelový graf"
#: src/pages/settings/SettingsWorkspace.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetEditorGroupsData.ts
#: src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenuOpenContent.tsx
msgid "General"
msgstr "Obecné"
@@ -6497,11 +6583,15 @@ msgstr ""
msgid "Heading 3"
msgstr ""
#. js-lingui-id: UPqS9C
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health"
msgstr ""
#. js-lingui-id: I1IOmb
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
#: src/modules/settings/admin-panel/health-status/components/SettingsAdminHealthStatus.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health Status"
msgstr "Zdravotní stav"
@@ -6586,6 +6676,11 @@ msgstr "Skrýt skupinu {groupValue}"
msgid "Hide hidden groups"
msgstr "Skrýt skryté skupiny"
#. js-lingui-id: i0qMbr
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Home"
msgstr ""
#. js-lingui-id: Xkd22/
#: src/modules/page-layout/utils/getWidgetTitle.ts
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
@@ -6897,6 +6992,7 @@ msgstr "Informace"
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Input"
msgstr "Vstup"
@@ -6973,11 +7069,6 @@ msgstr "Pokyny pro AI"
msgid "Integrations - Settings"
msgstr "Integrace - Nastavení"
#. js-lingui-id: ntgzzG
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Interact with your workspace data"
msgstr "Interakce s daty vašeho pracovního prostoru"
#. js-lingui-id: jyjroS
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Interval switching has been cancelled."
@@ -7954,6 +8045,11 @@ msgstr "Maximální rozsah"
msgid "Maximum email addresses"
msgstr "Maximální počet emailových adres"
#. js-lingui-id: 9UHNQc
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Maximum execution time in seconds (1-900)"
msgstr ""
#. js-lingui-id: PAhTVY
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
msgid "Maximum files"
@@ -8086,11 +8182,6 @@ msgstr "Metadata"
msgid "Metadata file generation failed"
msgstr "Generování souboru metadat selhalo"
#. js-lingui-id: 0BF9eC
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Metadata Schema"
msgstr "Schéma metadat"
#. js-lingui-id: onCJJ6
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Metered tier switching has been cancelled."
@@ -8149,6 +8240,17 @@ msgstr ""
msgid "Mission accomplished!"
msgstr "Mise splněna!"
#. js-lingui-id: //nm2/
#: src/pages/settings/ai/SettingsAI.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models"
msgstr ""
#. js-lingui-id: oHM560
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models available in the chat model picker"
msgstr ""
#. js-lingui-id: hty0d5
#: src/pages/settings/profile/appearance/components/DateTimeSettingsCalendarStartDaySelect.tsx
msgid "Monday"
@@ -8194,6 +8296,7 @@ msgid "months"
msgstr ""
#. js-lingui-id: 2FYpfJ
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/ui/layout/tab-list/components/TabMoreButton.tsx
msgid "More"
msgstr "Více"
@@ -8483,6 +8586,11 @@ msgstr "Nové pole"
msgid "New folder"
msgstr ""
#. js-lingui-id: 93KA8w
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationEditor.tsx
msgid "New Group"
msgstr ""
#. js-lingui-id: o8MyXb
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "New key"
@@ -8656,6 +8764,11 @@ msgstr "Žádná dostupná pole k výběru"
msgid "No body"
msgstr "Žádné tělo"
#. js-lingui-id: c3+z7H
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
msgid "No calling code"
msgstr ""
#. js-lingui-id: OTe3RI
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "No change detected"
@@ -8686,7 +8799,6 @@ msgstr "Pro tento požadavek nebyl poskytnut žádný kontext"
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
msgid "No country"
msgstr "Žádná země"
@@ -8887,7 +8999,6 @@ msgstr "Žádná data metrik nejsou k dispozici"
#. js-lingui-id: UWZZdQ
#: src/pages/settings/ai/forms/components/SettingsAIAgentForm.tsx
#: src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "No models available. Please configure AI models in your workspace settings."
msgstr "Nejsou dostupné žádné modely. Prosím, nakonfigurujte AI modely v nastavení vašeho pracovního prostoru."
@@ -9124,7 +9235,13 @@ msgstr "Nesdíleno uživatelem {notSharedByFullName}"
msgid "Not synced"
msgstr "Nesynchronizováno"
#. js-lingui-id: KiJn9B
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Note"
msgstr ""
#. js-lingui-id: 1DBGsz
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Notes"
msgstr "Poznámky"
@@ -9502,6 +9619,11 @@ msgstr ""
msgid "Organization"
msgstr "Organizace"
#. js-lingui-id: zi/p7n
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Organization plan"
msgstr ""
#. js-lingui-id: nV6twc
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
msgid "Organize"
@@ -9514,7 +9636,7 @@ msgstr ""
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/pages/settings/admin-panel/SettingsAdmin.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemMainMenu.tsx
msgid "Other"
msgstr "Ostatní"
@@ -9560,6 +9682,7 @@ msgstr "Výpadek"
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/TerminalOutput.tsx
#: src/modules/ai/components/CodeExecutionDisplay.tsx
msgid "Output"
@@ -10061,6 +10184,11 @@ msgstr "Zásady ochrany osobních údajů"
msgid "Pro"
msgstr "Pro"
#. js-lingui-id: r5je1s
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Pro plan"
msgstr ""
#. js-lingui-id: k1ifdL
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
@@ -10196,11 +10324,6 @@ msgstr "Výkon fronty"
msgid "Queue: {queueName}"
msgstr "Fronta: {queueName}"
#. js-lingui-id: GaAG2G
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Quick model for routing decisions"
msgstr ""
#. js-lingui-id: opSifa
#: src/modules/ai/utils/getToolDisplayMessage.ts
msgid "Ran {formattedName}"
@@ -10677,6 +10800,11 @@ msgstr "Obnovit záznamy"
msgid "Restore Records"
msgstr "Obnovit záznamy"
#. js-lingui-id: hO3AfV
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Restrict available models to a curated list"
msgstr ""
#. js-lingui-id: RD6AE9
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
msgid "Result"
@@ -10958,6 +11086,12 @@ msgstr "Hledat ve sloupci..."
msgid "Search a folder..."
msgstr ""
#. js-lingui-id: 8J0e5B
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Search a model..."
msgstr ""
#. js-lingui-id: WXvlVa
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "Search a role..."
@@ -11511,6 +11645,11 @@ msgstr "Odesláno a přijato"
msgid "Serbian (Cyrillic)"
msgstr "Srbština (cyrilice)"
#. js-lingui-id: 8ZSrlB
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Server-wide AI model availability settings"
msgstr ""
#. js-lingui-id: LUc0oL
#: src/modules/settings/security/components/SSO/SettingsSSOSAMLForm.tsx
msgid "Service Provider Details"
@@ -11593,7 +11732,6 @@ msgstr "Nastavení vaší databáze..."
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
#: src/pages/settings/ai/SettingsAgentForm.tsx
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/sign-in-background-mock/components/SignInAppNavigationDrawerMock.tsx
#: src/modules/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsSection.tsx
#: src/modules/settings/roles/role/components/SettingsRole.tsx
@@ -11812,15 +11950,10 @@ msgid "Small section heading"
msgstr ""
#. js-lingui-id: 5J8ZFl
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Smart Model"
msgstr ""
#. js-lingui-id: qgvZ/2
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Smart model updated successfully"
msgstr ""
#. js-lingui-id: w+rJId
#: src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx
msgid "SMTP Configuration"
@@ -11920,6 +12053,14 @@ msgstr "Mezery a čárka - {spacesAndCommaExample}"
msgid "Spanish"
msgstr "Španělština"
#. js-lingui-id: gsifzp
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Split multiple values"
msgstr ""
#. js-lingui-id: vnS6Rf
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "SSO"
@@ -12398,6 +12539,7 @@ msgid "Task Title"
msgstr "Název úkolu"
#. js-lingui-id: GtycJ/
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Tasks"
msgstr "Úkoly"
@@ -12597,6 +12739,11 @@ msgstr "S tímto záznamem není spojena žádná aktivita."
msgid "There was an error while updating password."
msgstr "Během aktualizace hesla došlo k chybě."
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
msgstr ""
#. js-lingui-id: Ed99mE
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
msgid "Thinking..."
@@ -12784,6 +12931,11 @@ msgstr "Tímto bude vaše metoda dvoufaktorového ověřování trvale odstraně
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
msgstr "Toto obnoví hodnotu databáze na hodnotu prostředí/výchozí hodnotu. Přepis databáze bude odstraněn a systém použije nastavení prostředí."
#. js-lingui-id: f8HOUp
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thought"
msgstr ""
#. js-lingui-id: 5g/sE8
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
msgid "Tidy up"
@@ -12815,10 +12967,16 @@ msgid "Time zone"
msgstr "Časové pásmo"
#. js-lingui-id: cklVjM
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
msgid "Timeline"
msgstr "Časová osa"
#. js-lingui-id: xY9s5E
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Timeout"
msgstr ""
#. js-lingui-id: 8TMaZI
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
@@ -12874,6 +13032,11 @@ msgstr "Přepnout oprávnění všech objektů"
msgid "Toggle all settings permissions"
msgstr "Přepnout všechna oprávnění nastavení"
#. js-lingui-id: 93pMSK
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Toggle model availability across all workspaces"
msgstr ""
#. js-lingui-id: WOr+hW
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
msgid "tokens"
@@ -13131,7 +13294,6 @@ msgid "Type"
msgstr "Typ"
#. js-lingui-id: SKD2e4
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
#: src/modules/activities/components/ActivityRichTextEditor.tsx
msgid "Type '/' for commands, '@' for mentions"
msgstr ""
@@ -13172,6 +13334,11 @@ msgstr ""
msgid "Unable to Reach Back-end"
msgstr "Nepodařilo se dosáhnout zadního konce"
#. js-lingui-id: EbnX+O
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Unconfigured models"
msgstr ""
#. js-lingui-id: EUHN7i
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableValueInput.tsx
msgid "Undefined"
@@ -13482,11 +13649,26 @@ msgstr "Použít jako koncept"
msgid "Use authenticator apps and browser extensions like 1Password, Authy, Microsoft Authenticator to generate one-time passwords"
msgstr "Používejte autentizační aplikace a rozšíření prohlížeče jako 1Password, Authy, Microsoft Authenticator pro generování jednorázových hesel"
#. js-lingui-id: hCZsJ0
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Use best models only"
msgstr ""
#. js-lingui-id: c6uZUV
#: src/modules/object-record/record-table/empty-state/utils/getEmptyStateSubTitle.ts
msgid "Use our API or add your first {objectLabel} manually"
msgstr "Použijte naše API nebo ručně přidejte první {objectLabel}"
#. js-lingui-id: 664z2C
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for chats, agents, and complex reasoning"
msgstr ""
#. js-lingui-id: C41qgx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for lightweight tasks like title generation"
msgstr ""
#. js-lingui-id: AQVj2A
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Useful for pivot/junction tables"
@@ -13735,8 +13917,6 @@ msgid "View Logs"
msgstr ""
#. js-lingui-id: ecVcAx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
msgid "View Previous AI Chats"
@@ -13992,6 +14172,21 @@ msgstr ""
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
msgstr ""
#. js-lingui-id: 8jc/Xn
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "When enabled, AI agents and workflow automations can discover and call this function"
msgstr ""
#. js-lingui-id: i2V4DO
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "When enabled, new AI models will be available to users by default"
msgstr ""
#. js-lingui-id: 01e9rV
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "When enabled, newly added models are available to all workspaces by default"
msgstr ""
#. js-lingui-id: C51ilI
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "When the API key will expire."
@@ -14124,6 +14319,7 @@ msgid "Workspace Domain"
msgstr "Doména pracovního prostoru"
#. js-lingui-id: J2q6WC
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/components/EventLogTableSelector.tsx
msgid "Workspace Events"
msgstr ""
+284 -88
View File
@@ -106,6 +106,7 @@ msgstr "(valgt: {selectedIconKey})"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "[empty string]"
@@ -310,6 +311,11 @@ msgstr "{morphRelationCount} objekter"
msgid "{num, selectordinal, one {{num}st} two {{num}nd} few {{num}rd} other {{num}th}}"
msgstr "{num, selectordinal, one {{num}ste} other {{num}te}}"
#. js-lingui-id: fTSz8d
#: src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownActorSelect.tsx
msgid "{numberOfSelectedItems} workspace members"
msgstr ""
#. js-lingui-id: 7kYa/u
#: src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts
msgid "{objectLabelPlural} ({totalCount})"
@@ -330,6 +336,16 @@ msgstr ""
msgid "{positionLabel} record holds priority"
msgstr "Posten {positionLabel} har prioritet"
#. js-lingui-id: YG/wl5
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — API key not configured"
msgstr ""
#. js-lingui-id: s80lrU
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — Deprecated"
msgstr ""
#. js-lingui-id: Sxx5Hr
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "{recordCount} of {totalCount} records"
@@ -381,6 +397,11 @@ msgstr "{selectedCount} kildetyper"
msgid "{serviceLabel} service is unreachable"
msgstr "Tjenesten {serviceLabel} kan ikke nås"
#. js-lingui-id: 8vJ+2V
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "{stepCount, plural, one {# step} other {# steps}}"
msgstr ""
#. js-lingui-id: Bzjg0/
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
msgid "{stepNumber}. Calendar"
@@ -764,6 +785,11 @@ msgstr "Tilføj \"{trimmedName}\" til muligheder"
msgid "Add a {objectLabelSingular}"
msgstr "Tilføj {objectLabelSingular}"
#. js-lingui-id: 7W8nJr
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationGroupEditor.tsx
msgid "Add a Group"
msgstr ""
#. js-lingui-id: CZDwqQ
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
msgid "Add a new company we're in touch with (e.g. name, website, industry). Details: "
@@ -780,11 +806,6 @@ msgstr "Tilføj en node"
msgid "Add a record"
msgstr ""
#. js-lingui-id: r8W+9y
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
msgid "Add a Section"
msgstr ""
#. js-lingui-id: eMc2xs
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
msgid "Add a step"
@@ -1111,6 +1132,11 @@ msgstr "Juster de rolle-relaterede indstillinger"
msgid "Admin"
msgstr ""
#. js-lingui-id: K2OX5h
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Admin Model Controls"
msgstr ""
#. js-lingui-id: g1in8j
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
@@ -1139,11 +1165,6 @@ msgstr "Avanceret funktion til at forbedre ydeevnen af forespørgsler og håndh
msgid "Advanced filter"
msgstr "Avanceret filter"
#. js-lingui-id: luNzWN
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Advanced model for complex planning"
msgstr ""
#. js-lingui-id: miuPUc
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
@@ -1246,6 +1267,7 @@ msgstr ""
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
#: src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectForm.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "AI"
msgstr "AI"
@@ -1257,11 +1279,6 @@ msgstr "AI"
msgid "AI Model"
msgstr "AI Model"
#. js-lingui-id: tGx4Zn
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "AI Models"
msgstr ""
#. js-lingui-id: Sfwld8
#: src/modules/ai/components/AIChatApiKeyNotConfiguredMessage.tsx
msgid "AI not configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or XAI_API_KEY in your environment."
@@ -1345,6 +1362,11 @@ msgstr ""
msgid "All Metadata"
msgstr ""
#. js-lingui-id: AJgjR+
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "All Models"
msgstr ""
#. js-lingui-id: aFE/OW
#: src/pages/settings/security/event-logs/components/EventLogFilters.tsx
#: src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableHeader.tsx
@@ -1506,6 +1528,9 @@ msgstr "Der opstod en fejl under upload af billedet."
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
@@ -1602,6 +1627,11 @@ msgstr "API-nøgle"
msgid "API Key copied to clipboard"
msgstr "API-nøgle kopieret til udklipsholder"
#. js-lingui-id: jjaYji
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "API key not configured"
msgstr ""
#. js-lingui-id: Widx6n
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "API key roles"
@@ -1829,6 +1859,7 @@ msgstr "Stigende"
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
@@ -1967,7 +1998,6 @@ msgstr "Vedhæftninger"
#. js-lingui-id: EPEFrH
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "Audit Logs"
msgstr ""
@@ -2057,6 +2087,16 @@ msgstr "Opret automatisk kontakter for personer."
msgid "Automatically create People records when receiving or sending emails"
msgstr "Opret automatisk personposter, når du modtager eller sender e-mails"
#. js-lingui-id: erwsgX
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Automatically enable new models"
msgstr ""
#. js-lingui-id: fx8TeY
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Automatically mark new models as available"
msgstr ""
#. js-lingui-id: lXkUEV
#: src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerManual.tsx
msgid "Availability"
@@ -2064,10 +2104,16 @@ msgstr "Tilgængelighed"
#. js-lingui-id: csDS2L
#: src/pages/settings/applications/SettingsApplications.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/data-model/new-object/components/SettingsAvailableStandardObjectsSection.tsx
msgid "Available"
msgstr "Tilgængelig"
#. js-lingui-id: 06gA3L
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Available as tool"
msgstr ""
#. js-lingui-id: oD38t2
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Available tools"
@@ -2239,9 +2285,9 @@ msgstr "Brun"
msgid "Build a dashboard that shows: (1) total pipeline value by stage for the last 3 months, (2) count of deals won vs lost per month, (3) average deal size. Use our standard pipeline stages."
msgstr ""
#. js-lingui-id: 8SlslB
#. js-lingui-id: alSW5d
#: src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationJunctionForm.tsx
msgid "Build many-to-many relations. <0>Learn more</0>"
msgid "Build many-to-many relations"
msgstr ""
#. js-lingui-id: +7fBMP
@@ -2312,6 +2358,7 @@ msgstr "caldav.example.com"
#. js-lingui-id: AjVXBS
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
msgid "Calendar"
msgstr "Kalender"
@@ -2364,6 +2411,11 @@ msgstr "Kalendervisning"
msgid "Calendars"
msgstr "Kalendere"
#. js-lingui-id: qIlodj
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Calling Code"
msgstr ""
#. js-lingui-id: msssZq
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Can't change API names for standard objects"
@@ -2500,11 +2552,6 @@ msgstr "Skift nodetype"
msgid "Change Password"
msgstr "Skift kodeord"
#. js-lingui-id: wRtBJP
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Change Plan"
msgstr "Ændre Pakke"
#. js-lingui-id: EYSFEW
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "Change subdomain?"
@@ -2602,7 +2649,7 @@ msgid "Choose the fields that will identify your records"
msgstr "Vælg de felter, der vil identificere dine poster"
#. js-lingui-id: hIJigY
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Choose the format used to display date value"
msgstr "Vælg det format, der bruges til at vise datoværdien"
@@ -2705,6 +2752,11 @@ msgstr "Klienthemmelighed"
msgid "Client Settings"
msgstr "Klientindstillinger"
#. js-lingui-id: mekEJ5
#: src/hooks/useCopyToClipboard.tsx
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
msgstr ""
#. js-lingui-id: yz7wBu
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
msgid "Close"
@@ -2747,6 +2799,7 @@ msgstr "Kodedin funktion"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Collapse"
@@ -2847,10 +2900,14 @@ msgstr "Fuldførte jobs opbevares i {completedDuration}, mislykkede jobs opbevar
msgid "Conditions"
msgstr "Betingelser"
#. js-lingui-id: 14PdY0
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config"
msgstr ""
#. js-lingui-id: Vj43Y/
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config Variables"
msgstr "Konfigurationsvariabler"
@@ -2865,11 +2922,6 @@ msgstr "Konfiguration"
msgid "Configure"
msgstr ""
#. js-lingui-id: 9px+al
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Configure AI models for routing and planning"
msgstr ""
#. js-lingui-id: +zUMwJ
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure an SSO connection"
@@ -2895,6 +2947,11 @@ msgstr "Konfigurer CalDAV-indstillingerne for at synkronisere dine kalenderevent
msgid "Configure date, time, number, timezone, and calendar start day"
msgstr "Konfigurer dato, tid, tal, tidszone og kalenderstartdag"
#. js-lingui-id: +SQwHr
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Configure default AI models and availability"
msgstr ""
#. js-lingui-id: utsXG8
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure fallback login methods for users with SSO bypass permissions"
@@ -3225,11 +3282,6 @@ msgstr "Kerne"
msgid "Core Objects"
msgstr ""
#. js-lingui-id: cfa2VJ
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Core Schema"
msgstr "Kerneskema"
#. js-lingui-id: I99Miw
#: src/modules/billing/components/SettingsBillingCreditsSection.tsx
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
@@ -3301,11 +3353,6 @@ msgstr "Tæl unikke værdier"
msgid "Country"
msgstr "Land"
#. js-lingui-id: j2OqfX
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Country Code"
msgstr "Landekode"
#. js-lingui-id: gJdfqX
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "create"
@@ -4253,6 +4300,16 @@ msgstr "Slettede poster"
msgid "Deleting this method will remove it permanently from your account."
msgstr "Ved at slette denne metode fjernes den permanent fra din konto."
#. js-lingui-id: Ssdrw4
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated"
msgstr ""
#. js-lingui-id: 8OJZ/p
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated models"
msgstr ""
#. js-lingui-id: O3LJh6
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
@@ -4826,6 +4883,7 @@ msgstr "E-mail-domæner"
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Emails"
msgstr "E-mails"
@@ -4877,6 +4935,7 @@ msgstr "Tom"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Array"
@@ -4897,6 +4956,7 @@ msgstr "Tom Indbakke"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Object"
@@ -5024,10 +5084,10 @@ msgstr ""
msgid "Enter filter"
msgstr "Indtast filter"
#. js-lingui-id: 9/30HU
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
msgid "Enter in <0>Unicode</0> format"
msgstr "Indtast i <0>Unicode</0> format"
#. js-lingui-id: f09Lhk
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Enter in Unicode format"
msgstr ""
#. js-lingui-id: 9CjMQ7
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx
@@ -5092,6 +5152,11 @@ msgstr "Indtast testværdi"
msgid "Enter text"
msgstr "Indtast tekst"
#. js-lingui-id: +rrO69
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
msgid "Enter text or type '/' for commands"
msgstr ""
#. js-lingui-id: yZMXC2
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
msgid "Enter text or Type '/' for commands"
@@ -5488,6 +5553,7 @@ msgstr "Forlad indstillinger"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Expand"
@@ -5787,9 +5853,9 @@ msgstr ""
msgid "Failed to save workspace instructions"
msgstr ""
#. js-lingui-id: YMSYb+
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update fast model"
#. js-lingui-id: YzURPo
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update auto-enable setting"
msgstr ""
#. js-lingui-id: P1NmNz
@@ -5797,6 +5863,27 @@ msgstr ""
msgid "Failed to update feature flag. {errorMessage}"
msgstr "Kunne ikke opdatere funktionsflag. {errorMessage}"
#. js-lingui-id: 1R13Ov
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model"
msgstr ""
#. js-lingui-id: W7Ff/4
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update model availability"
msgstr ""
#. js-lingui-id: LgZlJ7
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model availability settings"
msgstr ""
#. js-lingui-id: rCUG3c
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model selection mode"
msgstr ""
#. js-lingui-id: HnBqPY
#: src/modules/billing/components/internal/MeteredPriceSelector.tsx
msgid "Failed to update price."
@@ -5812,11 +5899,6 @@ msgstr ""
msgid "Failed to update role"
msgstr "Kunne ikke ændre rollen"
#. js-lingui-id: h/0aT5
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update smart model"
msgstr ""
#. js-lingui-id: Dzh4a2
#: src/modules/settings/admin-panel/config-variables/hooks/useConfigVariableActions.ts
msgid "Failed to update variable"
@@ -5865,15 +5947,10 @@ msgid "False"
msgstr "Falsk"
#. js-lingui-id: XVIZ7v
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Fast Model"
msgstr ""
#. js-lingui-id: UJHTjm
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Fast model updated successfully"
msgstr ""
#. js-lingui-id: X9kySA
#: src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx
#: src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx
@@ -6018,6 +6095,11 @@ msgstr ""
msgid "File URL is not defined"
msgstr ""
#. js-lingui-id: sER+bs
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Files"
msgstr ""
#. js-lingui-id: o7J4JM
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
@@ -6027,6 +6109,7 @@ msgstr ""
#: src/modules/views/components/ViewBarFilterButton.tsx
#: src/modules/settings/roles/components/SettingsRolesList.tsx
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
#: src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx
@@ -6121,6 +6204,7 @@ msgstr "Fornavn må ikke være tomt"
#. js-lingui-id: ylQd2j
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "Flow"
msgstr "Strøm"
@@ -6255,7 +6339,9 @@ msgstr "Målediagram"
#: src/pages/settings/SettingsWorkspace.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetEditorGroupsData.ts
#: src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenuOpenContent.tsx
msgid "General"
msgstr "Generelt"
@@ -6497,11 +6583,15 @@ msgstr ""
msgid "Heading 3"
msgstr ""
#. js-lingui-id: UPqS9C
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health"
msgstr ""
#. js-lingui-id: I1IOmb
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
#: src/modules/settings/admin-panel/health-status/components/SettingsAdminHealthStatus.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health Status"
msgstr "Sundhedsstatus"
@@ -6586,6 +6676,11 @@ msgstr "Skjul gruppe {groupValue}"
msgid "Hide hidden groups"
msgstr "Skjul skjulte grupper"
#. js-lingui-id: i0qMbr
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Home"
msgstr ""
#. js-lingui-id: Xkd22/
#: src/modules/page-layout/utils/getWidgetTitle.ts
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
@@ -6897,6 +6992,7 @@ msgstr "Info"
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Input"
msgstr "Input"
@@ -6973,11 +7069,6 @@ msgstr "Instruktioner til AI"
msgid "Integrations - Settings"
msgstr "Integrationer - Indstillinger"
#. js-lingui-id: ntgzzG
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Interact with your workspace data"
msgstr "Interagér med dine arbejdspladsdata"
#. js-lingui-id: jyjroS
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Interval switching has been cancelled."
@@ -7954,6 +8045,11 @@ msgstr "Maksimumsgrænse"
msgid "Maximum email addresses"
msgstr "Maksimalt antal e-mailadresser"
#. js-lingui-id: 9UHNQc
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Maximum execution time in seconds (1-900)"
msgstr ""
#. js-lingui-id: PAhTVY
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
msgid "Maximum files"
@@ -8086,11 +8182,6 @@ msgstr "Metadata"
msgid "Metadata file generation failed"
msgstr "Generering af metadatafil mislykkedes"
#. js-lingui-id: 0BF9eC
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Metadata Schema"
msgstr "Metadata-skema"
#. js-lingui-id: onCJJ6
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Metered tier switching has been cancelled."
@@ -8149,6 +8240,17 @@ msgstr ""
msgid "Mission accomplished!"
msgstr "Mission fuldført!"
#. js-lingui-id: //nm2/
#: src/pages/settings/ai/SettingsAI.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models"
msgstr ""
#. js-lingui-id: oHM560
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models available in the chat model picker"
msgstr ""
#. js-lingui-id: hty0d5
#: src/pages/settings/profile/appearance/components/DateTimeSettingsCalendarStartDaySelect.tsx
msgid "Monday"
@@ -8194,6 +8296,7 @@ msgid "months"
msgstr ""
#. js-lingui-id: 2FYpfJ
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/ui/layout/tab-list/components/TabMoreButton.tsx
msgid "More"
msgstr "Mere"
@@ -8483,6 +8586,11 @@ msgstr "Nyt felt"
msgid "New folder"
msgstr ""
#. js-lingui-id: 93KA8w
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationEditor.tsx
msgid "New Group"
msgstr ""
#. js-lingui-id: o8MyXb
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "New key"
@@ -8656,6 +8764,11 @@ msgstr "Ingen tilgængelige felter for at vælge"
msgid "No body"
msgstr "Ingen body"
#. js-lingui-id: c3+z7H
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
msgid "No calling code"
msgstr ""
#. js-lingui-id: OTe3RI
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "No change detected"
@@ -8686,7 +8799,6 @@ msgstr "Der blev ikke angivet nogen kontekst for denne anmodning"
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
msgid "No country"
msgstr "Intet land"
@@ -8887,7 +8999,6 @@ msgstr "Ingen metrikdata tilgængelige"
#. js-lingui-id: UWZZdQ
#: src/pages/settings/ai/forms/components/SettingsAIAgentForm.tsx
#: src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "No models available. Please configure AI models in your workspace settings."
msgstr "Ingen modeller tilgængelige. Konfigurer venligst AI-modeller i dine arbejdsområdeindstillinger."
@@ -9124,7 +9235,13 @@ msgstr "Ikke delt af {notSharedByFullName}"
msgid "Not synced"
msgstr "Ikke synkroniseret"
#. js-lingui-id: KiJn9B
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Note"
msgstr ""
#. js-lingui-id: 1DBGsz
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Notes"
msgstr "Noter"
@@ -9502,6 +9619,11 @@ msgstr ""
msgid "Organization"
msgstr "Organisation"
#. js-lingui-id: zi/p7n
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Organization plan"
msgstr ""
#. js-lingui-id: nV6twc
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
msgid "Organize"
@@ -9514,7 +9636,7 @@ msgstr ""
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/pages/settings/admin-panel/SettingsAdmin.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemMainMenu.tsx
msgid "Other"
msgstr "Andet"
@@ -9560,6 +9682,7 @@ msgstr "Nedetid"
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/TerminalOutput.tsx
#: src/modules/ai/components/CodeExecutionDisplay.tsx
msgid "Output"
@@ -10061,6 +10184,11 @@ msgstr "Privatlivspolitik"
msgid "Pro"
msgstr "Pro"
#. js-lingui-id: r5je1s
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Pro plan"
msgstr ""
#. js-lingui-id: k1ifdL
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
@@ -10196,11 +10324,6 @@ msgstr "Køydelse"
msgid "Queue: {queueName}"
msgstr "Kø: {queueName}"
#. js-lingui-id: GaAG2G
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Quick model for routing decisions"
msgstr ""
#. js-lingui-id: opSifa
#: src/modules/ai/utils/getToolDisplayMessage.ts
msgid "Ran {formattedName}"
@@ -10677,6 +10800,11 @@ msgstr "Gendan poster"
msgid "Restore Records"
msgstr "Gendan poster"
#. js-lingui-id: hO3AfV
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Restrict available models to a curated list"
msgstr ""
#. js-lingui-id: RD6AE9
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
msgid "Result"
@@ -10958,6 +11086,12 @@ msgstr "Søg i et felt..."
msgid "Search a folder..."
msgstr ""
#. js-lingui-id: 8J0e5B
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Search a model..."
msgstr ""
#. js-lingui-id: WXvlVa
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "Search a role..."
@@ -11511,6 +11645,11 @@ msgstr "Sendt og modtaget"
msgid "Serbian (Cyrillic)"
msgstr "Serbisk (Cyrillisk)"
#. js-lingui-id: 8ZSrlB
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Server-wide AI model availability settings"
msgstr ""
#. js-lingui-id: LUc0oL
#: src/modules/settings/security/components/SSO/SettingsSSOSAMLForm.tsx
msgid "Service Provider Details"
@@ -11593,7 +11732,6 @@ msgstr "Opsætning af din database..."
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
#: src/pages/settings/ai/SettingsAgentForm.tsx
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/sign-in-background-mock/components/SignInAppNavigationDrawerMock.tsx
#: src/modules/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsSection.tsx
#: src/modules/settings/roles/role/components/SettingsRole.tsx
@@ -11812,15 +11950,10 @@ msgid "Small section heading"
msgstr ""
#. js-lingui-id: 5J8ZFl
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Smart Model"
msgstr ""
#. js-lingui-id: qgvZ/2
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Smart model updated successfully"
msgstr ""
#. js-lingui-id: w+rJId
#: src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx
msgid "SMTP Configuration"
@@ -11920,6 +12053,14 @@ msgstr "Mellemrum og komma - {spacesAndCommaExample}"
msgid "Spanish"
msgstr "Spansk"
#. js-lingui-id: gsifzp
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Split multiple values"
msgstr ""
#. js-lingui-id: vnS6Rf
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "SSO"
@@ -12398,6 +12539,7 @@ msgid "Task Title"
msgstr "Opgavetitel"
#. js-lingui-id: GtycJ/
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Tasks"
msgstr "Opgaver"
@@ -12597,6 +12739,11 @@ msgstr "Der er ingen aktivitet tilknyttet denne post."
msgid "There was an error while updating password."
msgstr "Der opstod en fejl under opdatering af adgangskoden."
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
msgstr ""
#. js-lingui-id: Ed99mE
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
msgid "Thinking..."
@@ -12786,6 +12933,11 @@ msgstr "Dette vil permanent slette din tofaktorgodkendelsesmetode.<0/>Da 2FA er
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
msgstr "Dette vil gendanne databaseværdien til miljø/standardværdi. Databasetilsidesættelsen vil blive fjernet, og systemet vil bruge miljøindstillingerne."
#. js-lingui-id: f8HOUp
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thought"
msgstr ""
#. js-lingui-id: 5g/sE8
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
msgid "Tidy up"
@@ -12817,10 +12969,16 @@ msgid "Time zone"
msgstr "Tidszone"
#. js-lingui-id: cklVjM
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
msgid "Timeline"
msgstr "Tidslinje"
#. js-lingui-id: xY9s5E
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Timeout"
msgstr ""
#. js-lingui-id: 8TMaZI
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
@@ -12876,6 +13034,11 @@ msgstr "Skift alle objekt tilladelser"
msgid "Toggle all settings permissions"
msgstr "Skift alle indstillingers tilladelser"
#. js-lingui-id: 93pMSK
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Toggle model availability across all workspaces"
msgstr ""
#. js-lingui-id: WOr+hW
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
msgid "tokens"
@@ -13133,7 +13296,6 @@ msgid "Type"
msgstr "Type"
#. js-lingui-id: SKD2e4
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
#: src/modules/activities/components/ActivityRichTextEditor.tsx
msgid "Type '/' for commands, '@' for mentions"
msgstr ""
@@ -13174,6 +13336,11 @@ msgstr ""
msgid "Unable to Reach Back-end"
msgstr "Kan ikke nå bagenden"
#. js-lingui-id: EbnX+O
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Unconfigured models"
msgstr ""
#. js-lingui-id: EUHN7i
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableValueInput.tsx
msgid "Undefined"
@@ -13484,11 +13651,26 @@ msgstr "Brug som kladde"
msgid "Use authenticator apps and browser extensions like 1Password, Authy, Microsoft Authenticator to generate one-time passwords"
msgstr "Brug autentifikationsapps og browserudvidelser som 1Password, Authy, Microsoft Authenticator til at generere engangsadgangskoder"
#. js-lingui-id: hCZsJ0
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Use best models only"
msgstr ""
#. js-lingui-id: c6uZUV
#: src/modules/object-record/record-table/empty-state/utils/getEmptyStateSubTitle.ts
msgid "Use our API or add your first {objectLabel} manually"
msgstr "Brug vores API eller tilføj din første {objectLabel} manuelt"
#. js-lingui-id: 664z2C
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for chats, agents, and complex reasoning"
msgstr ""
#. js-lingui-id: C41qgx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for lightweight tasks like title generation"
msgstr ""
#. js-lingui-id: AQVj2A
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Useful for pivot/junction tables"
@@ -13737,8 +13919,6 @@ msgid "View Logs"
msgstr ""
#. js-lingui-id: ecVcAx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
msgid "View Previous AI Chats"
@@ -13994,6 +14174,21 @@ msgstr ""
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
msgstr ""
#. js-lingui-id: 8jc/Xn
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "When enabled, AI agents and workflow automations can discover and call this function"
msgstr ""
#. js-lingui-id: i2V4DO
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "When enabled, new AI models will be available to users by default"
msgstr ""
#. js-lingui-id: 01e9rV
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "When enabled, newly added models are available to all workspaces by default"
msgstr ""
#. js-lingui-id: C51ilI
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "When the API key will expire."
@@ -14126,6 +14321,7 @@ msgid "Workspace Domain"
msgstr "Arbejdsområdedomæne"
#. js-lingui-id: J2q6WC
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/components/EventLogTableSelector.tsx
msgid "Workspace Events"
msgstr ""
+284 -88
View File
@@ -106,6 +106,7 @@ msgstr "(ausgewählt: {selectedIconKey})"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "[empty string]"
@@ -310,6 +311,11 @@ msgstr "{morphRelationCount} Objekte"
msgid "{num, selectordinal, one {{num}st} two {{num}nd} few {{num}rd} other {{num}th}}"
msgstr "{num, selectordinal, one {{num}.} other {{num}.}}"
#. js-lingui-id: fTSz8d
#: src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownActorSelect.tsx
msgid "{numberOfSelectedItems} workspace members"
msgstr ""
#. js-lingui-id: 7kYa/u
#: src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts
msgid "{objectLabelPlural} ({totalCount})"
@@ -330,6 +336,16 @@ msgstr ""
msgid "{positionLabel} record holds priority"
msgstr "{positionLabel}-Datensatz hat Priorität"
#. js-lingui-id: YG/wl5
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — API key not configured"
msgstr ""
#. js-lingui-id: s80lrU
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — Deprecated"
msgstr ""
#. js-lingui-id: Sxx5Hr
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "{recordCount} of {totalCount} records"
@@ -381,6 +397,11 @@ msgstr "{selectedCount} Quelltypen"
msgid "{serviceLabel} service is unreachable"
msgstr "{serviceLabel}-Dienst ist nicht erreichbar"
#. js-lingui-id: 8vJ+2V
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "{stepCount, plural, one {# step} other {# steps}}"
msgstr ""
#. js-lingui-id: Bzjg0/
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
msgid "{stepNumber}. Calendar"
@@ -764,6 +785,11 @@ msgstr "\"{trimmedName}\" zu den Optionen hinzufügen"
msgid "Add a {objectLabelSingular}"
msgstr "Ein {objectLabelSingular} hinzufügen"
#. js-lingui-id: 7W8nJr
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationGroupEditor.tsx
msgid "Add a Group"
msgstr ""
#. js-lingui-id: CZDwqQ
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
msgid "Add a new company we're in touch with (e.g. name, website, industry). Details: "
@@ -780,11 +806,6 @@ msgstr "Knoten hinzufügen"
msgid "Add a record"
msgstr ""
#. js-lingui-id: r8W+9y
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
msgid "Add a Section"
msgstr ""
#. js-lingui-id: eMc2xs
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
msgid "Add a step"
@@ -1111,6 +1132,11 @@ msgstr "Passen Sie die rollenspezifischen Einstellungen an"
msgid "Admin"
msgstr ""
#. js-lingui-id: K2OX5h
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Admin Model Controls"
msgstr ""
#. js-lingui-id: g1in8j
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
@@ -1139,11 +1165,6 @@ msgstr "Erweiterte Funktion zur Verbesserung der Abfrageleistung und zur Durchse
msgid "Advanced filter"
msgstr "Erweiterter Filter"
#. js-lingui-id: luNzWN
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Advanced model for complex planning"
msgstr ""
#. js-lingui-id: miuPUc
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
@@ -1246,6 +1267,7 @@ msgstr ""
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
#: src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectForm.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "AI"
msgstr "KI"
@@ -1257,11 +1279,6 @@ msgstr "KI"
msgid "AI Model"
msgstr "KI-Modell"
#. js-lingui-id: tGx4Zn
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "AI Models"
msgstr ""
#. js-lingui-id: Sfwld8
#: src/modules/ai/components/AIChatApiKeyNotConfiguredMessage.tsx
msgid "AI not configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or XAI_API_KEY in your environment."
@@ -1345,6 +1362,11 @@ msgstr ""
msgid "All Metadata"
msgstr ""
#. js-lingui-id: AJgjR+
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "All Models"
msgstr ""
#. js-lingui-id: aFE/OW
#: src/pages/settings/security/event-logs/components/EventLogFilters.tsx
#: src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableHeader.tsx
@@ -1506,6 +1528,9 @@ msgstr "Beim Hochladen des Bildes ist ein Fehler aufgetreten."
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
@@ -1602,6 +1627,11 @@ msgstr "API-Schlüssel"
msgid "API Key copied to clipboard"
msgstr "API-Schlüssel in die Zwischenablage kopiert"
#. js-lingui-id: jjaYji
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "API key not configured"
msgstr ""
#. js-lingui-id: Widx6n
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "API key roles"
@@ -1829,6 +1859,7 @@ msgstr "Aufsteigend"
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
@@ -1967,7 +1998,6 @@ msgstr "Anhänge"
#. js-lingui-id: EPEFrH
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "Audit Logs"
msgstr ""
@@ -2057,6 +2087,16 @@ msgstr "Automatisch Kontakte für Personen erstellen."
msgid "Automatically create People records when receiving or sending emails"
msgstr "Automatisch Personendatensätze erstellen beim Empfangen oder Senden von E-Mails"
#. js-lingui-id: erwsgX
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Automatically enable new models"
msgstr ""
#. js-lingui-id: fx8TeY
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Automatically mark new models as available"
msgstr ""
#. js-lingui-id: lXkUEV
#: src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerManual.tsx
msgid "Availability"
@@ -2064,10 +2104,16 @@ msgstr "Verfügbarkeit"
#. js-lingui-id: csDS2L
#: src/pages/settings/applications/SettingsApplications.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/data-model/new-object/components/SettingsAvailableStandardObjectsSection.tsx
msgid "Available"
msgstr "Verfügbar"
#. js-lingui-id: 06gA3L
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Available as tool"
msgstr ""
#. js-lingui-id: oD38t2
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Available tools"
@@ -2239,9 +2285,9 @@ msgstr "Braun"
msgid "Build a dashboard that shows: (1) total pipeline value by stage for the last 3 months, (2) count of deals won vs lost per month, (3) average deal size. Use our standard pipeline stages."
msgstr ""
#. js-lingui-id: 8SlslB
#. js-lingui-id: alSW5d
#: src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationJunctionForm.tsx
msgid "Build many-to-many relations. <0>Learn more</0>"
msgid "Build many-to-many relations"
msgstr ""
#. js-lingui-id: +7fBMP
@@ -2312,6 +2358,7 @@ msgstr "caldav.example.com"
#. js-lingui-id: AjVXBS
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
msgid "Calendar"
msgstr "Kalender"
@@ -2364,6 +2411,11 @@ msgstr "Kalenderansicht"
msgid "Calendars"
msgstr "Kalender"
#. js-lingui-id: qIlodj
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Calling Code"
msgstr ""
#. js-lingui-id: msssZq
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Can't change API names for standard objects"
@@ -2500,11 +2552,6 @@ msgstr "Knotentyp ändern"
msgid "Change Password"
msgstr "Passwort ändern"
#. js-lingui-id: wRtBJP
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Change Plan"
msgstr "Plan ändern"
#. js-lingui-id: EYSFEW
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "Change subdomain?"
@@ -2602,7 +2649,7 @@ msgid "Choose the fields that will identify your records"
msgstr "Wählen Sie die Felder aus, die Ihre Datensätze identifizieren werden"
#. js-lingui-id: hIJigY
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Choose the format used to display date value"
msgstr "Wählen Sie das Format zur Anzeige des Datumswertes"
@@ -2705,6 +2752,11 @@ msgstr "Client-Geheimnis"
msgid "Client Settings"
msgstr "Client-Einstellungen"
#. js-lingui-id: mekEJ5
#: src/hooks/useCopyToClipboard.tsx
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
msgstr ""
#. js-lingui-id: yz7wBu
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
msgid "Close"
@@ -2747,6 +2799,7 @@ msgstr "Funktion programmieren"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Collapse"
@@ -2847,10 +2900,14 @@ msgstr "Abgeschlossene Aufgaben werden für {completedDuration} aufbewahrt, fehl
msgid "Conditions"
msgstr "Bedingungen"
#. js-lingui-id: 14PdY0
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config"
msgstr ""
#. js-lingui-id: Vj43Y/
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config Variables"
msgstr "Konfigurationsvariablen"
@@ -2865,11 +2922,6 @@ msgstr "Konfiguration"
msgid "Configure"
msgstr ""
#. js-lingui-id: 9px+al
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Configure AI models for routing and planning"
msgstr ""
#. js-lingui-id: +zUMwJ
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure an SSO connection"
@@ -2895,6 +2947,11 @@ msgstr "Konfigurieren Sie die CalDAV-Einstellungen, um Ihre Kalenderereignisse z
msgid "Configure date, time, number, timezone, and calendar start day"
msgstr "Datum, Uhrzeit, Zahl, Zeitzone und Kalendertagesstart konfigurieren"
#. js-lingui-id: +SQwHr
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Configure default AI models and availability"
msgstr ""
#. js-lingui-id: utsXG8
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure fallback login methods for users with SSO bypass permissions"
@@ -3225,11 +3282,6 @@ msgstr "Kern"
msgid "Core Objects"
msgstr ""
#. js-lingui-id: cfa2VJ
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Core Schema"
msgstr "Kernschema"
#. js-lingui-id: I99Miw
#: src/modules/billing/components/SettingsBillingCreditsSection.tsx
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
@@ -3301,11 +3353,6 @@ msgstr "Eindeutige Werte zählen"
msgid "Country"
msgstr "Land"
#. js-lingui-id: j2OqfX
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Country Code"
msgstr "Ländercode"
#. js-lingui-id: gJdfqX
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "create"
@@ -4253,6 +4300,16 @@ msgstr "Gelöschte Datensätze"
msgid "Deleting this method will remove it permanently from your account."
msgstr "Durch das Löschen dieser Methode wird sie dauerhaft von Ihrem Konto entfernt."
#. js-lingui-id: Ssdrw4
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated"
msgstr ""
#. js-lingui-id: 8OJZ/p
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated models"
msgstr ""
#. js-lingui-id: O3LJh6
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
@@ -4826,6 +4883,7 @@ msgstr "E-Mail-Domänen"
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Emails"
msgstr "E-Mails"
@@ -4877,6 +4935,7 @@ msgstr "Leer"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Array"
@@ -4897,6 +4956,7 @@ msgstr "Leerer Posteingang"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Object"
@@ -5024,10 +5084,10 @@ msgstr ""
msgid "Enter filter"
msgstr "Filter eingeben"
#. js-lingui-id: 9/30HU
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
msgid "Enter in <0>Unicode</0> format"
msgstr "Im <0>Unicode</0>-Format eingeben"
#. js-lingui-id: f09Lhk
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Enter in Unicode format"
msgstr ""
#. js-lingui-id: 9CjMQ7
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx
@@ -5092,6 +5152,11 @@ msgstr "Testwert eingeben"
msgid "Enter text"
msgstr "Text eingeben"
#. js-lingui-id: +rrO69
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
msgid "Enter text or type '/' for commands"
msgstr ""
#. js-lingui-id: yZMXC2
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
msgid "Enter text or Type '/' for commands"
@@ -5488,6 +5553,7 @@ msgstr "Einstellungen verlassen"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Expand"
@@ -5787,9 +5853,9 @@ msgstr ""
msgid "Failed to save workspace instructions"
msgstr ""
#. js-lingui-id: YMSYb+
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update fast model"
#. js-lingui-id: YzURPo
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update auto-enable setting"
msgstr ""
#. js-lingui-id: P1NmNz
@@ -5797,6 +5863,27 @@ msgstr ""
msgid "Failed to update feature flag. {errorMessage}"
msgstr "Feature-Flag konnte nicht aktualisiert werden. {errorMessage}"
#. js-lingui-id: 1R13Ov
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model"
msgstr ""
#. js-lingui-id: W7Ff/4
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update model availability"
msgstr ""
#. js-lingui-id: LgZlJ7
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model availability settings"
msgstr ""
#. js-lingui-id: rCUG3c
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model selection mode"
msgstr ""
#. js-lingui-id: HnBqPY
#: src/modules/billing/components/internal/MeteredPriceSelector.tsx
msgid "Failed to update price."
@@ -5812,11 +5899,6 @@ msgstr ""
msgid "Failed to update role"
msgstr "Fehler beim Aktualisieren der Rolle"
#. js-lingui-id: h/0aT5
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update smart model"
msgstr ""
#. js-lingui-id: Dzh4a2
#: src/modules/settings/admin-panel/config-variables/hooks/useConfigVariableActions.ts
msgid "Failed to update variable"
@@ -5865,15 +5947,10 @@ msgid "False"
msgstr "Falsch"
#. js-lingui-id: XVIZ7v
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Fast Model"
msgstr ""
#. js-lingui-id: UJHTjm
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Fast model updated successfully"
msgstr ""
#. js-lingui-id: X9kySA
#: src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx
#: src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx
@@ -6018,6 +6095,11 @@ msgstr ""
msgid "File URL is not defined"
msgstr ""
#. js-lingui-id: sER+bs
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Files"
msgstr ""
#. js-lingui-id: o7J4JM
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
@@ -6027,6 +6109,7 @@ msgstr ""
#: src/modules/views/components/ViewBarFilterButton.tsx
#: src/modules/settings/roles/components/SettingsRolesList.tsx
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
#: src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx
@@ -6121,6 +6204,7 @@ msgstr "Vorname darf nicht leer sein"
#. js-lingui-id: ylQd2j
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "Flow"
msgstr "Fluss"
@@ -6255,7 +6339,9 @@ msgstr ""
#: src/pages/settings/SettingsWorkspace.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetEditorGroupsData.ts
#: src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenuOpenContent.tsx
msgid "General"
msgstr "Allgemein"
@@ -6497,11 +6583,15 @@ msgstr ""
msgid "Heading 3"
msgstr ""
#. js-lingui-id: UPqS9C
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health"
msgstr ""
#. js-lingui-id: I1IOmb
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
#: src/modules/settings/admin-panel/health-status/components/SettingsAdminHealthStatus.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health Status"
msgstr "Gesundheitsstatus"
@@ -6586,6 +6676,11 @@ msgstr "Gruppe {groupValue} ausblenden"
msgid "Hide hidden groups"
msgstr "Verborgene Gruppen ausblenden"
#. js-lingui-id: i0qMbr
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Home"
msgstr ""
#. js-lingui-id: Xkd22/
#: src/modules/page-layout/utils/getWidgetTitle.ts
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
@@ -6897,6 +6992,7 @@ msgstr "Informationen"
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Input"
msgstr "Eingabe"
@@ -6973,11 +7069,6 @@ msgstr "Anweisungen für die KI"
msgid "Integrations - Settings"
msgstr "Integrationen - Einstellungen"
#. js-lingui-id: ntgzzG
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Interact with your workspace data"
msgstr "Interagieren Sie mit Ihren Arbeitsbereichsdaten"
#. js-lingui-id: jyjroS
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Interval switching has been cancelled."
@@ -7954,6 +8045,11 @@ msgstr "Maximaler Bereich"
msgid "Maximum email addresses"
msgstr "Maximale E-Mail-Adressen"
#. js-lingui-id: 9UHNQc
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Maximum execution time in seconds (1-900)"
msgstr ""
#. js-lingui-id: PAhTVY
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
msgid "Maximum files"
@@ -8086,11 +8182,6 @@ msgstr "Metadaten"
msgid "Metadata file generation failed"
msgstr "Generierung der Metadatendatei fehlgeschlagen"
#. js-lingui-id: 0BF9eC
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Metadata Schema"
msgstr "Metadaten-Schema"
#. js-lingui-id: onCJJ6
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Metered tier switching has been cancelled."
@@ -8149,6 +8240,17 @@ msgstr ""
msgid "Mission accomplished!"
msgstr "Mission erfüllt!"
#. js-lingui-id: //nm2/
#: src/pages/settings/ai/SettingsAI.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models"
msgstr ""
#. js-lingui-id: oHM560
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models available in the chat model picker"
msgstr ""
#. js-lingui-id: hty0d5
#: src/pages/settings/profile/appearance/components/DateTimeSettingsCalendarStartDaySelect.tsx
msgid "Monday"
@@ -8194,6 +8296,7 @@ msgid "months"
msgstr ""
#. js-lingui-id: 2FYpfJ
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/ui/layout/tab-list/components/TabMoreButton.tsx
msgid "More"
msgstr "Mehr"
@@ -8483,6 +8586,11 @@ msgstr "Neues Feld"
msgid "New folder"
msgstr ""
#. js-lingui-id: 93KA8w
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationEditor.tsx
msgid "New Group"
msgstr ""
#. js-lingui-id: o8MyXb
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "New key"
@@ -8656,6 +8764,11 @@ msgstr "Keine verfügbaren Felder zur Auswahl"
msgid "No body"
msgstr "Kein Body"
#. js-lingui-id: c3+z7H
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
msgid "No calling code"
msgstr ""
#. js-lingui-id: OTe3RI
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "No change detected"
@@ -8686,7 +8799,6 @@ msgstr "Für diese Anfrage wurde kein Kontext bereitgestellt"
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
msgid "No country"
msgstr "Kein Land"
@@ -8887,7 +8999,6 @@ msgstr "Keine Metrik-Daten verfügbar"
#. js-lingui-id: UWZZdQ
#: src/pages/settings/ai/forms/components/SettingsAIAgentForm.tsx
#: src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "No models available. Please configure AI models in your workspace settings."
msgstr "Keine Modelle verfügbar. Bitte konfigurieren Sie KI-Modelle in Ihren Arbeitsbereichseinstellungen."
@@ -9124,7 +9235,13 @@ msgstr "Nicht geteilt von {notSharedByFullName}"
msgid "Not synced"
msgstr "Nicht synchronisiert"
#. js-lingui-id: KiJn9B
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Note"
msgstr ""
#. js-lingui-id: 1DBGsz
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Notes"
msgstr "Notizen"
@@ -9502,6 +9619,11 @@ msgstr ""
msgid "Organization"
msgstr "Organisation"
#. js-lingui-id: zi/p7n
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Organization plan"
msgstr ""
#. js-lingui-id: nV6twc
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
msgid "Organize"
@@ -9514,7 +9636,7 @@ msgstr ""
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/pages/settings/admin-panel/SettingsAdmin.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemMainMenu.tsx
msgid "Other"
msgstr "Andere"
@@ -9560,6 +9682,7 @@ msgstr "Ausfall"
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/TerminalOutput.tsx
#: src/modules/ai/components/CodeExecutionDisplay.tsx
msgid "Output"
@@ -10061,6 +10184,11 @@ msgstr "Datenschutzrichtlinie"
msgid "Pro"
msgstr "Pro"
#. js-lingui-id: r5je1s
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Pro plan"
msgstr ""
#. js-lingui-id: k1ifdL
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
@@ -10196,11 +10324,6 @@ msgstr "Queue-Leistung"
msgid "Queue: {queueName}"
msgstr "Warteschlange: {queueName}"
#. js-lingui-id: GaAG2G
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Quick model for routing decisions"
msgstr ""
#. js-lingui-id: opSifa
#: src/modules/ai/utils/getToolDisplayMessage.ts
msgid "Ran {formattedName}"
@@ -10677,6 +10800,11 @@ msgstr "Datensätze wiederherstellen"
msgid "Restore Records"
msgstr "Datensätze wiederherstellen"
#. js-lingui-id: hO3AfV
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Restrict available models to a curated list"
msgstr ""
#. js-lingui-id: RD6AE9
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
msgid "Result"
@@ -10958,6 +11086,12 @@ msgstr "Feld suchen..."
msgid "Search a folder..."
msgstr ""
#. js-lingui-id: 8J0e5B
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Search a model..."
msgstr ""
#. js-lingui-id: WXvlVa
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "Search a role..."
@@ -11511,6 +11645,11 @@ msgstr "Gesendet und Empfangen"
msgid "Serbian (Cyrillic)"
msgstr "Serbisch (Kyrillisch)"
#. js-lingui-id: 8ZSrlB
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Server-wide AI model availability settings"
msgstr ""
#. js-lingui-id: LUc0oL
#: src/modules/settings/security/components/SSO/SettingsSSOSAMLForm.tsx
msgid "Service Provider Details"
@@ -11593,7 +11732,6 @@ msgstr "Einrichten Ihrer Datenbank..."
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
#: src/pages/settings/ai/SettingsAgentForm.tsx
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/sign-in-background-mock/components/SignInAppNavigationDrawerMock.tsx
#: src/modules/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsSection.tsx
#: src/modules/settings/roles/role/components/SettingsRole.tsx
@@ -11812,15 +11950,10 @@ msgid "Small section heading"
msgstr ""
#. js-lingui-id: 5J8ZFl
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Smart Model"
msgstr ""
#. js-lingui-id: qgvZ/2
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Smart model updated successfully"
msgstr ""
#. js-lingui-id: w+rJId
#: src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx
msgid "SMTP Configuration"
@@ -11920,6 +12053,14 @@ msgstr "Leerzeichen und Komma - {spacesAndCommaExample}"
msgid "Spanish"
msgstr "Spanisch"
#. js-lingui-id: gsifzp
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Split multiple values"
msgstr ""
#. js-lingui-id: vnS6Rf
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "SSO"
@@ -12398,6 +12539,7 @@ msgid "Task Title"
msgstr "Aufgabentitel"
#. js-lingui-id: GtycJ/
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Tasks"
msgstr "Aufgaben"
@@ -12597,6 +12739,11 @@ msgstr "Mit diesem Datensatz ist keine Aktivität verknüpft."
msgid "There was an error while updating password."
msgstr "Beim Aktualisieren des Passworts ist ein Fehler aufgetreten."
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
msgstr ""
#. js-lingui-id: Ed99mE
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
msgid "Thinking..."
@@ -12784,6 +12931,11 @@ msgstr "Dies wird Ihre Zwei-Faktor-Authentifizierung dauerhaft löschen.<0/>Da 2
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
msgstr "Dies wird den Datenbankwert auf den Umwelt-/Standardwert zurücksetzen. Der Datenbanküberschreibung wird entfernt und das System wird die Umgebungsanstellungen verwenden."
#. js-lingui-id: f8HOUp
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thought"
msgstr ""
#. js-lingui-id: 5g/sE8
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
msgid "Tidy up"
@@ -12815,10 +12967,16 @@ msgid "Time zone"
msgstr "Zeitzone"
#. js-lingui-id: cklVjM
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
msgid "Timeline"
msgstr "Zeitleiste"
#. js-lingui-id: xY9s5E
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Timeout"
msgstr ""
#. js-lingui-id: 8TMaZI
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
@@ -12874,6 +13032,11 @@ msgstr "Alle Objektberechtigungen umschalten"
msgid "Toggle all settings permissions"
msgstr "Alle Einstellungsberechtigungen umschalten"
#. js-lingui-id: 93pMSK
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Toggle model availability across all workspaces"
msgstr ""
#. js-lingui-id: WOr+hW
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
msgid "tokens"
@@ -13131,7 +13294,6 @@ msgid "Type"
msgstr "Typ"
#. js-lingui-id: SKD2e4
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
#: src/modules/activities/components/ActivityRichTextEditor.tsx
msgid "Type '/' for commands, '@' for mentions"
msgstr ""
@@ -13172,6 +13334,11 @@ msgstr ""
msgid "Unable to Reach Back-end"
msgstr "Backend nicht erreichbar"
#. js-lingui-id: EbnX+O
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Unconfigured models"
msgstr ""
#. js-lingui-id: EUHN7i
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableValueInput.tsx
msgid "Undefined"
@@ -13482,11 +13649,26 @@ msgstr "Als Entwurf verwenden"
msgid "Use authenticator apps and browser extensions like 1Password, Authy, Microsoft Authenticator to generate one-time passwords"
msgstr "Verwenden Sie Authenticator-Apps und Browser-Erweiterungen wie 1Password, Authy, Microsoft Authenticator, um Einmal-Passwörter zu generieren"
#. js-lingui-id: hCZsJ0
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Use best models only"
msgstr ""
#. js-lingui-id: c6uZUV
#: src/modules/object-record/record-table/empty-state/utils/getEmptyStateSubTitle.ts
msgid "Use our API or add your first {objectLabel} manually"
msgstr "Verwenden Sie unsere API oder fügen Sie Ihr erstes {objectLabel} manuell hinzu"
#. js-lingui-id: 664z2C
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for chats, agents, and complex reasoning"
msgstr ""
#. js-lingui-id: C41qgx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for lightweight tasks like title generation"
msgstr ""
#. js-lingui-id: AQVj2A
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Useful for pivot/junction tables"
@@ -13735,8 +13917,6 @@ msgid "View Logs"
msgstr ""
#. js-lingui-id: ecVcAx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
msgid "View Previous AI Chats"
@@ -13992,6 +14172,21 @@ msgstr ""
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
msgstr ""
#. js-lingui-id: 8jc/Xn
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "When enabled, AI agents and workflow automations can discover and call this function"
msgstr ""
#. js-lingui-id: i2V4DO
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "When enabled, new AI models will be available to users by default"
msgstr ""
#. js-lingui-id: 01e9rV
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "When enabled, newly added models are available to all workspaces by default"
msgstr ""
#. js-lingui-id: C51ilI
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "When the API key will expire."
@@ -14124,6 +14319,7 @@ msgid "Workspace Domain"
msgstr "Arbeitsbereichsdomäne"
#. js-lingui-id: J2q6WC
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/components/EventLogTableSelector.tsx
msgid "Workspace Events"
msgstr ""
+284 -88
View File
@@ -106,6 +106,7 @@ msgstr "(επιλεγμένο: {selectedIconKey})"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "[empty string]"
@@ -310,6 +311,11 @@ msgstr "{morphRelationCount} Αντικείμενα"
msgid "{num, selectordinal, one {{num}st} two {{num}nd} few {{num}rd} other {{num}th}}"
msgstr "{num, selectordinal, one {{num}η} other {{num}η}}"
#. js-lingui-id: fTSz8d
#: src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownActorSelect.tsx
msgid "{numberOfSelectedItems} workspace members"
msgstr ""
#. js-lingui-id: 7kYa/u
#: src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts
msgid "{objectLabelPlural} ({totalCount})"
@@ -330,6 +336,16 @@ msgstr ""
msgid "{positionLabel} record holds priority"
msgstr "Η εγγραφή {positionLabel} έχει προτεραιότητα"
#. js-lingui-id: YG/wl5
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — API key not configured"
msgstr ""
#. js-lingui-id: s80lrU
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — Deprecated"
msgstr ""
#. js-lingui-id: Sxx5Hr
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "{recordCount} of {totalCount} records"
@@ -381,6 +397,11 @@ msgstr "{selectedCount} τύποι πηγής"
msgid "{serviceLabel} service is unreachable"
msgstr "Η υπηρεσία {serviceLabel} είναι απρόσιτη"
#. js-lingui-id: 8vJ+2V
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "{stepCount, plural, one {# step} other {# steps}}"
msgstr ""
#. js-lingui-id: Bzjg0/
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
msgid "{stepNumber}. Calendar"
@@ -764,6 +785,11 @@ msgstr "Προσθήκη \"{trimmedName}\" στις επιλογές"
msgid "Add a {objectLabelSingular}"
msgstr "Προσθήκη {objectLabelSingular}"
#. js-lingui-id: 7W8nJr
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationGroupEditor.tsx
msgid "Add a Group"
msgstr ""
#. js-lingui-id: CZDwqQ
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
msgid "Add a new company we're in touch with (e.g. name, website, industry). Details: "
@@ -780,11 +806,6 @@ msgstr "Προσθήκη κόμβου"
msgid "Add a record"
msgstr ""
#. js-lingui-id: r8W+9y
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
msgid "Add a Section"
msgstr ""
#. js-lingui-id: eMc2xs
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
msgid "Add a step"
@@ -1111,6 +1132,11 @@ msgstr "Ρυθμίστε τις ρυθμίσεις που σχετίζονται
msgid "Admin"
msgstr ""
#. js-lingui-id: K2OX5h
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Admin Model Controls"
msgstr ""
#. js-lingui-id: g1in8j
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
@@ -1139,11 +1165,6 @@ msgstr "Σύνθετη λειτουργία για τη βελτίωση της
msgid "Advanced filter"
msgstr "Προηγμένο φίλτρο"
#. js-lingui-id: luNzWN
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Advanced model for complex planning"
msgstr ""
#. js-lingui-id: miuPUc
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
@@ -1246,6 +1267,7 @@ msgstr ""
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
#: src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectForm.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "AI"
msgstr "AI"
@@ -1257,11 +1279,6 @@ msgstr "AI"
msgid "AI Model"
msgstr "Μοντέλο AI"
#. js-lingui-id: tGx4Zn
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "AI Models"
msgstr ""
#. js-lingui-id: Sfwld8
#: src/modules/ai/components/AIChatApiKeyNotConfiguredMessage.tsx
msgid "AI not configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or XAI_API_KEY in your environment."
@@ -1345,6 +1362,11 @@ msgstr ""
msgid "All Metadata"
msgstr ""
#. js-lingui-id: AJgjR+
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "All Models"
msgstr ""
#. js-lingui-id: aFE/OW
#: src/pages/settings/security/event-logs/components/EventLogFilters.tsx
#: src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableHeader.tsx
@@ -1506,6 +1528,9 @@ msgstr "Παρουσιάστηκε σφάλμα κατά τη μεταφόρτω
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
@@ -1602,6 +1627,11 @@ msgstr "API Key"
msgid "API Key copied to clipboard"
msgstr "Το κλειδί API αντιγράφηκε στο πρόχειρο"
#. js-lingui-id: jjaYji
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "API key not configured"
msgstr ""
#. js-lingui-id: Widx6n
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "API key roles"
@@ -1829,6 +1859,7 @@ msgstr "Αύξουσα"
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
@@ -1967,7 +1998,6 @@ msgstr "Συνημμένα"
#. js-lingui-id: EPEFrH
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "Audit Logs"
msgstr ""
@@ -2057,6 +2087,16 @@ msgstr "Αυτόματη δημιουργία επαφών για άτομα."
msgid "Automatically create People records when receiving or sending emails"
msgstr "Δημιουργία αυτόματων εγγραφών Ατόμων κατά την αποστολή ή λήψη email"
#. js-lingui-id: erwsgX
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Automatically enable new models"
msgstr ""
#. js-lingui-id: fx8TeY
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Automatically mark new models as available"
msgstr ""
#. js-lingui-id: lXkUEV
#: src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerManual.tsx
msgid "Availability"
@@ -2064,10 +2104,16 @@ msgstr "Διαθεσιμότητα"
#. js-lingui-id: csDS2L
#: src/pages/settings/applications/SettingsApplications.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/data-model/new-object/components/SettingsAvailableStandardObjectsSection.tsx
msgid "Available"
msgstr "Διαθέσιμο"
#. js-lingui-id: 06gA3L
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Available as tool"
msgstr ""
#. js-lingui-id: oD38t2
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Available tools"
@@ -2239,9 +2285,9 @@ msgstr "Καφέ"
msgid "Build a dashboard that shows: (1) total pipeline value by stage for the last 3 months, (2) count of deals won vs lost per month, (3) average deal size. Use our standard pipeline stages."
msgstr ""
#. js-lingui-id: 8SlslB
#. js-lingui-id: alSW5d
#: src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationJunctionForm.tsx
msgid "Build many-to-many relations. <0>Learn more</0>"
msgid "Build many-to-many relations"
msgstr ""
#. js-lingui-id: +7fBMP
@@ -2312,6 +2358,7 @@ msgstr "caldav.example.com"
#. js-lingui-id: AjVXBS
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
msgid "Calendar"
msgstr "Ημερολόγιο"
@@ -2364,6 +2411,11 @@ msgstr "Προβολή Ημερολογίου"
msgid "Calendars"
msgstr "Ημερολόγια"
#. js-lingui-id: qIlodj
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Calling Code"
msgstr ""
#. js-lingui-id: msssZq
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Can't change API names for standard objects"
@@ -2500,11 +2552,6 @@ msgstr "Αλλαγή τύπου κόμβου"
msgid "Change Password"
msgstr "Αλλαγή Κωδικού"
#. js-lingui-id: wRtBJP
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Change Plan"
msgstr "Αλλαγή σχεδίου"
#. js-lingui-id: EYSFEW
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "Change subdomain?"
@@ -2602,7 +2649,7 @@ msgid "Choose the fields that will identify your records"
msgstr "Επιλέξτε τα πεδία που θα ταυτοποιήσουν τις εγγραφές σας"
#. js-lingui-id: hIJigY
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Choose the format used to display date value"
msgstr "Επιλέξτε τη μορφή που χρησιμοποιείται για την εμφάνιση της τιμής ημερομηνίας"
@@ -2705,6 +2752,11 @@ msgstr "Μυστικό Πελάτη"
msgid "Client Settings"
msgstr "Ρυθμίσεις Πελάτη"
#. js-lingui-id: mekEJ5
#: src/hooks/useCopyToClipboard.tsx
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
msgstr ""
#. js-lingui-id: yz7wBu
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
msgid "Close"
@@ -2747,6 +2799,7 @@ msgstr "Κωδικοποιήστε τη λειτουργία σας"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Collapse"
@@ -2847,10 +2900,14 @@ msgstr "Οι ολοκληρωμένες εργασίες διατηρούντα
msgid "Conditions"
msgstr "Προϋποθέσεις"
#. js-lingui-id: 14PdY0
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config"
msgstr ""
#. js-lingui-id: Vj43Y/
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config Variables"
msgstr "Μεταβλητές Διαμόρφωσης"
@@ -2865,11 +2922,6 @@ msgstr "Διαμόρφωση"
msgid "Configure"
msgstr ""
#. js-lingui-id: 9px+al
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Configure AI models for routing and planning"
msgstr ""
#. js-lingui-id: +zUMwJ
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure an SSO connection"
@@ -2895,6 +2947,11 @@ msgstr "Ρυθμίστε τις παραμέτρους του CalDAV για συ
msgid "Configure date, time, number, timezone, and calendar start day"
msgstr "Διαμόρφωση ημερομηνίας, ώρας, αριθμού, ζώνης ώρας και έναρξης ημερολογίου"
#. js-lingui-id: +SQwHr
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Configure default AI models and availability"
msgstr ""
#. js-lingui-id: utsXG8
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure fallback login methods for users with SSO bypass permissions"
@@ -3225,11 +3282,6 @@ msgstr "Πυρήνας"
msgid "Core Objects"
msgstr ""
#. js-lingui-id: cfa2VJ
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Core Schema"
msgstr "Βασικό σχήμα"
#. js-lingui-id: I99Miw
#: src/modules/billing/components/SettingsBillingCreditsSection.tsx
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
@@ -3301,11 +3353,6 @@ msgstr "Καταμέτρηση μοναδικών τιμών"
msgid "Country"
msgstr "Χώρα"
#. js-lingui-id: j2OqfX
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Country Code"
msgstr "Κωδικός χώρας"
#. js-lingui-id: gJdfqX
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "create"
@@ -4253,6 +4300,16 @@ msgstr "Διαγραμμένες εγγραφές"
msgid "Deleting this method will remove it permanently from your account."
msgstr "Η διαγραφή αυτής της μεθόδου θα την αφαιρέσει μόνιμα από τον λογαριασμό σας."
#. js-lingui-id: Ssdrw4
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated"
msgstr ""
#. js-lingui-id: 8OJZ/p
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated models"
msgstr ""
#. js-lingui-id: O3LJh6
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
@@ -4826,6 +4883,7 @@ msgstr "Περιοχές Email"
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Emails"
msgstr "Ηλεκτρονικά ταχυδρομεία"
@@ -4877,6 +4935,7 @@ msgstr "Κενό"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Array"
@@ -4897,6 +4956,7 @@ msgstr "Άδειο Γραμματοκιβώτιο"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Object"
@@ -5024,10 +5084,10 @@ msgstr ""
msgid "Enter filter"
msgstr "Εισάγετε φίλτρο"
#. js-lingui-id: 9/30HU
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
msgid "Enter in <0>Unicode</0> format"
msgstr "Εισάγετε σε μορφή <0>Unicode</0>"
#. js-lingui-id: f09Lhk
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Enter in Unicode format"
msgstr ""
#. js-lingui-id: 9CjMQ7
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx
@@ -5092,6 +5152,11 @@ msgstr "Εισάγετε δοκιμαστική τιμή"
msgid "Enter text"
msgstr "Εισάγετε κείμενο"
#. js-lingui-id: +rrO69
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
msgid "Enter text or type '/' for commands"
msgstr ""
#. js-lingui-id: yZMXC2
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
msgid "Enter text or Type '/' for commands"
@@ -5488,6 +5553,7 @@ msgstr "Έξοδος από Ρυθμίσεις"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Expand"
@@ -5787,9 +5853,9 @@ msgstr ""
msgid "Failed to save workspace instructions"
msgstr ""
#. js-lingui-id: YMSYb+
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update fast model"
#. js-lingui-id: YzURPo
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update auto-enable setting"
msgstr ""
#. js-lingui-id: P1NmNz
@@ -5797,6 +5863,27 @@ msgstr ""
msgid "Failed to update feature flag. {errorMessage}"
msgstr "Αποτυχία ενημέρωσης σημαίας δυνατότητας. {errorMessage}"
#. js-lingui-id: 1R13Ov
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model"
msgstr ""
#. js-lingui-id: W7Ff/4
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update model availability"
msgstr ""
#. js-lingui-id: LgZlJ7
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model availability settings"
msgstr ""
#. js-lingui-id: rCUG3c
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model selection mode"
msgstr ""
#. js-lingui-id: HnBqPY
#: src/modules/billing/components/internal/MeteredPriceSelector.tsx
msgid "Failed to update price."
@@ -5812,11 +5899,6 @@ msgstr ""
msgid "Failed to update role"
msgstr "Αποτυχία ενημέρωσης ρόλου"
#. js-lingui-id: h/0aT5
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update smart model"
msgstr ""
#. js-lingui-id: Dzh4a2
#: src/modules/settings/admin-panel/config-variables/hooks/useConfigVariableActions.ts
msgid "Failed to update variable"
@@ -5865,15 +5947,10 @@ msgid "False"
msgstr "Ψευδής"
#. js-lingui-id: XVIZ7v
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Fast Model"
msgstr ""
#. js-lingui-id: UJHTjm
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Fast model updated successfully"
msgstr ""
#. js-lingui-id: X9kySA
#: src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx
#: src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx
@@ -6018,6 +6095,11 @@ msgstr ""
msgid "File URL is not defined"
msgstr ""
#. js-lingui-id: sER+bs
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Files"
msgstr ""
#. js-lingui-id: o7J4JM
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
@@ -6027,6 +6109,7 @@ msgstr ""
#: src/modules/views/components/ViewBarFilterButton.tsx
#: src/modules/settings/roles/components/SettingsRolesList.tsx
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
#: src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx
@@ -6121,6 +6204,7 @@ msgstr "Το μικρό όνομα δεν μπορεί να είναι κενό"
#. js-lingui-id: ylQd2j
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "Flow"
msgstr "Ροή"
@@ -6255,7 +6339,9 @@ msgstr "Διάγραμμα δείκτη"
#: src/pages/settings/SettingsWorkspace.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetEditorGroupsData.ts
#: src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenuOpenContent.tsx
msgid "General"
msgstr "Γενικά"
@@ -6497,11 +6583,15 @@ msgstr ""
msgid "Heading 3"
msgstr ""
#. js-lingui-id: UPqS9C
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health"
msgstr ""
#. js-lingui-id: I1IOmb
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
#: src/modules/settings/admin-panel/health-status/components/SettingsAdminHealthStatus.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health Status"
msgstr "Κατάσταση Υγείας"
@@ -6586,6 +6676,11 @@ msgstr "Απόκρυψη ομάδας {groupValue}"
msgid "Hide hidden groups"
msgstr "Απόκρυψη κρυφών ομάδων"
#. js-lingui-id: i0qMbr
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Home"
msgstr ""
#. js-lingui-id: Xkd22/
#: src/modules/page-layout/utils/getWidgetTitle.ts
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
@@ -6897,6 +6992,7 @@ msgstr "Πληροφορίες"
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Input"
msgstr "Εισαγωγή"
@@ -6973,11 +7069,6 @@ msgstr "Οδηγίες για το AI"
msgid "Integrations - Settings"
msgstr "Ενσωματώσεις - Ρυθμίσεις"
#. js-lingui-id: ntgzzG
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Interact with your workspace data"
msgstr "Αλληλεπιδράστε με τα δεδομένα του χώρου εργασίας σας"
#. js-lingui-id: jyjroS
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Interval switching has been cancelled."
@@ -7954,6 +8045,11 @@ msgstr "Μέγιστο εύρος"
msgid "Maximum email addresses"
msgstr "Μέγιστος αριθμός διευθύνσεων email"
#. js-lingui-id: 9UHNQc
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Maximum execution time in seconds (1-900)"
msgstr ""
#. js-lingui-id: PAhTVY
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
msgid "Maximum files"
@@ -8086,11 +8182,6 @@ msgstr "Μεταδεδομένα"
msgid "Metadata file generation failed"
msgstr "Αποτυχία δημιουργίας αρχείου μεταδεδομένων"
#. js-lingui-id: 0BF9eC
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Metadata Schema"
msgstr "Σχήμα μεταδεδομένων"
#. js-lingui-id: onCJJ6
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Metered tier switching has been cancelled."
@@ -8149,6 +8240,17 @@ msgstr ""
msgid "Mission accomplished!"
msgstr "Αποστολή ολοκληρώθηκε!"
#. js-lingui-id: //nm2/
#: src/pages/settings/ai/SettingsAI.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models"
msgstr ""
#. js-lingui-id: oHM560
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models available in the chat model picker"
msgstr ""
#. js-lingui-id: hty0d5
#: src/pages/settings/profile/appearance/components/DateTimeSettingsCalendarStartDaySelect.tsx
msgid "Monday"
@@ -8194,6 +8296,7 @@ msgid "months"
msgstr ""
#. js-lingui-id: 2FYpfJ
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/ui/layout/tab-list/components/TabMoreButton.tsx
msgid "More"
msgstr "Περισσότερα"
@@ -8483,6 +8586,11 @@ msgstr "Νέο Πεδίο"
msgid "New folder"
msgstr ""
#. js-lingui-id: 93KA8w
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationEditor.tsx
msgid "New Group"
msgstr ""
#. js-lingui-id: o8MyXb
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "New key"
@@ -8656,6 +8764,11 @@ msgstr "Δεν υπάρχουν διαθέσιμα πεδία για επιλο
msgid "No body"
msgstr "Χωρίς σώμα"
#. js-lingui-id: c3+z7H
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
msgid "No calling code"
msgstr ""
#. js-lingui-id: OTe3RI
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "No change detected"
@@ -8686,7 +8799,6 @@ msgstr "Δεν παρέχεται πλαίσιο για αυτό το αίτημ
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
msgid "No country"
msgstr "Χωρίς χώρα"
@@ -8887,7 +8999,6 @@ msgstr "Δεν υπάρχουν διαθέσιμα δεδομένα μετρήσ
#. js-lingui-id: UWZZdQ
#: src/pages/settings/ai/forms/components/SettingsAIAgentForm.tsx
#: src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "No models available. Please configure AI models in your workspace settings."
msgstr "Δεν υπάρχουν διαθέσιμα μοντέλα. Παρακαλούμε ρυθμίστε τα μοντέλα AI στις ρυθμίσεις χώρου εργασίας σας."
@@ -9124,7 +9235,13 @@ msgstr "Δεν κοινοποιήθηκε από τον/την {notSharedByFullN
msgid "Not synced"
msgstr "Δεν συγχρονίζεται"
#. js-lingui-id: KiJn9B
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Note"
msgstr ""
#. js-lingui-id: 1DBGsz
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Notes"
msgstr "Σημειώματα"
@@ -9502,6 +9619,11 @@ msgstr ""
msgid "Organization"
msgstr "Οργανωτικός"
#. js-lingui-id: zi/p7n
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Organization plan"
msgstr ""
#. js-lingui-id: nV6twc
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
msgid "Organize"
@@ -9514,7 +9636,7 @@ msgstr ""
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/pages/settings/admin-panel/SettingsAdmin.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemMainMenu.tsx
msgid "Other"
msgstr "Άλλο"
@@ -9560,6 +9682,7 @@ msgstr "Διακοπή λειτουργίας"
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/TerminalOutput.tsx
#: src/modules/ai/components/CodeExecutionDisplay.tsx
msgid "Output"
@@ -10061,6 +10184,11 @@ msgstr "Πολιτική Απορρήτου"
msgid "Pro"
msgstr "Pro"
#. js-lingui-id: r5je1s
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Pro plan"
msgstr ""
#. js-lingui-id: k1ifdL
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
@@ -10196,11 +10324,6 @@ msgstr "Επιδόσεις Ουράς"
msgid "Queue: {queueName}"
msgstr "Ουρά: {queueName}"
#. js-lingui-id: GaAG2G
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Quick model for routing decisions"
msgstr ""
#. js-lingui-id: opSifa
#: src/modules/ai/utils/getToolDisplayMessage.ts
msgid "Ran {formattedName}"
@@ -10677,6 +10800,11 @@ msgstr "Επαναφορά εγγραφών"
msgid "Restore Records"
msgstr "Επαναφορά εγγραφών"
#. js-lingui-id: hO3AfV
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Restrict available models to a curated list"
msgstr ""
#. js-lingui-id: RD6AE9
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
msgid "Result"
@@ -10958,6 +11086,12 @@ msgstr "Αναζήτηση πεδίου..."
msgid "Search a folder..."
msgstr ""
#. js-lingui-id: 8J0e5B
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Search a model..."
msgstr ""
#. js-lingui-id: WXvlVa
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "Search a role..."
@@ -11511,6 +11645,11 @@ msgstr "Αποστέλλονται και Λήφθηκαν"
msgid "Serbian (Cyrillic)"
msgstr "Σερβικά (Κυριλλικά)"
#. js-lingui-id: 8ZSrlB
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Server-wide AI model availability settings"
msgstr ""
#. js-lingui-id: LUc0oL
#: src/modules/settings/security/components/SSO/SettingsSSOSAMLForm.tsx
msgid "Service Provider Details"
@@ -11593,7 +11732,6 @@ msgstr "Ρύθμιση της βάσης δεδομένων σας..."
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
#: src/pages/settings/ai/SettingsAgentForm.tsx
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/sign-in-background-mock/components/SignInAppNavigationDrawerMock.tsx
#: src/modules/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsSection.tsx
#: src/modules/settings/roles/role/components/SettingsRole.tsx
@@ -11814,15 +11952,10 @@ msgid "Small section heading"
msgstr ""
#. js-lingui-id: 5J8ZFl
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Smart Model"
msgstr ""
#. js-lingui-id: qgvZ/2
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Smart model updated successfully"
msgstr ""
#. js-lingui-id: w+rJId
#: src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx
msgid "SMTP Configuration"
@@ -11922,6 +12055,14 @@ msgstr "Κενά και κόμμα - {spacesAndCommaExample}"
msgid "Spanish"
msgstr "Ισπανικά"
#. js-lingui-id: gsifzp
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Split multiple values"
msgstr ""
#. js-lingui-id: vnS6Rf
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "SSO"
@@ -12400,6 +12541,7 @@ msgid "Task Title"
msgstr "Τίτλος εργασίας"
#. js-lingui-id: GtycJ/
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Tasks"
msgstr "Εργασίες"
@@ -12599,6 +12741,11 @@ msgstr "Δεν υπάρχει δραστηριότητα που να σχετί
msgid "There was an error while updating password."
msgstr "Παρουσιάστηκε σφάλμα κατά την ενημέρωση του κωδικού πρόσβασης."
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
msgstr ""
#. js-lingui-id: Ed99mE
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
msgid "Thinking..."
@@ -12788,6 +12935,11 @@ msgstr "Αυτό θα διαγράψει μόνιμα τη μέθοδο ελέγ
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
msgstr "Αυτό θα επαναφέρει την τιμή της βάσης δεδομένων στην προεπιλεγμένη/τιμή περιβάλλοντος. Η υπερισχύ του περιβάλλοντος βάσης δεδομένων θα αφαιρεθεί και το σύστημα θα χρησιμοποιήσει τις ρυθμίσεις περιβάλλοντος."
#. js-lingui-id: f8HOUp
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thought"
msgstr ""
#. js-lingui-id: 5g/sE8
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
msgid "Tidy up"
@@ -12819,10 +12971,16 @@ msgid "Time zone"
msgstr "Ζώνη ώρας"
#. js-lingui-id: cklVjM
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
msgid "Timeline"
msgstr "Χρονολόγιο"
#. js-lingui-id: xY9s5E
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Timeout"
msgstr ""
#. js-lingui-id: 8TMaZI
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
@@ -12878,6 +13036,11 @@ msgstr "Εναλλαγή όλων των δικαιωμάτων αντικειμ
msgid "Toggle all settings permissions"
msgstr "Εναλλαγή όλων των δικαιωμάτων ρυθμίσεων"
#. js-lingui-id: 93pMSK
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Toggle model availability across all workspaces"
msgstr ""
#. js-lingui-id: WOr+hW
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
msgid "tokens"
@@ -13135,7 +13298,6 @@ msgid "Type"
msgstr "Τύπος"
#. js-lingui-id: SKD2e4
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
#: src/modules/activities/components/ActivityRichTextEditor.tsx
msgid "Type '/' for commands, '@' for mentions"
msgstr ""
@@ -13176,6 +13338,11 @@ msgstr ""
msgid "Unable to Reach Back-end"
msgstr "Μη διαθέσιμη σύνδεση με το Back-end"
#. js-lingui-id: EbnX+O
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Unconfigured models"
msgstr ""
#. js-lingui-id: EUHN7i
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableValueInput.tsx
msgid "Undefined"
@@ -13486,11 +13653,26 @@ msgstr "Χρήση ως πρόχειρο"
msgid "Use authenticator apps and browser extensions like 1Password, Authy, Microsoft Authenticator to generate one-time passwords"
msgstr "Χρησιμοποιήστε εφαρμογές ταυτοποίησης και επεκτάσεις περιηγητή, όπως 1Password, Authy, Microsoft Authenticator, για να δημιουργήσετε μονοχρόνιους κωδικούς πρόσβασης"
#. js-lingui-id: hCZsJ0
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Use best models only"
msgstr ""
#. js-lingui-id: c6uZUV
#: src/modules/object-record/record-table/empty-state/utils/getEmptyStateSubTitle.ts
msgid "Use our API or add your first {objectLabel} manually"
msgstr "Χρησιμοποιήστε το API μας ή προσθέστε το πρώτο σας {objectLabel} χειροκίνητα"
#. js-lingui-id: 664z2C
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for chats, agents, and complex reasoning"
msgstr ""
#. js-lingui-id: C41qgx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for lightweight tasks like title generation"
msgstr ""
#. js-lingui-id: AQVj2A
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Useful for pivot/junction tables"
@@ -13739,8 +13921,6 @@ msgid "View Logs"
msgstr ""
#. js-lingui-id: ecVcAx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
msgid "View Previous AI Chats"
@@ -13996,6 +14176,21 @@ msgstr ""
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
msgstr ""
#. js-lingui-id: 8jc/Xn
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "When enabled, AI agents and workflow automations can discover and call this function"
msgstr ""
#. js-lingui-id: i2V4DO
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "When enabled, new AI models will be available to users by default"
msgstr ""
#. js-lingui-id: 01e9rV
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "When enabled, newly added models are available to all workspaces by default"
msgstr ""
#. js-lingui-id: C51ilI
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "When the API key will expire."
@@ -14128,6 +14323,7 @@ msgid "Workspace Domain"
msgstr "Τομέας Χώρου εργασίας"
#. js-lingui-id: J2q6WC
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/components/EventLogTableSelector.tsx
msgid "Workspace Events"
msgstr ""
+286 -90
View File
@@ -101,6 +101,7 @@ msgstr "(selected: {selectedIconKey})"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "[empty string]"
@@ -305,6 +306,11 @@ msgstr "{morphRelationCount} Objects"
msgid "{num, selectordinal, one {{num}st} two {{num}nd} few {{num}rd} other {{num}th}}"
msgstr "{num, selectordinal, one {{num}st} two {{num}nd} few {{num}rd} other {{num}th}}"
#. js-lingui-id: fTSz8d
#: src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownActorSelect.tsx
msgid "{numberOfSelectedItems} workspace members"
msgstr "{numberOfSelectedItems} workspace members"
#. js-lingui-id: 7kYa/u
#: src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts
msgid "{objectLabelPlural} ({totalCount})"
@@ -325,6 +331,16 @@ msgstr "{permissionLabel} Permission removed"
msgid "{positionLabel} record holds priority"
msgstr "{positionLabel} record holds priority"
#. js-lingui-id: YG/wl5
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — API key not configured"
msgstr "{providerLabel} — API key not configured"
#. js-lingui-id: s80lrU
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — Deprecated"
msgstr "{providerLabel} — Deprecated"
#. js-lingui-id: Sxx5Hr
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "{recordCount} of {totalCount} records"
@@ -376,6 +392,11 @@ msgstr "{selectedCount} source types"
msgid "{serviceLabel} service is unreachable"
msgstr "{serviceLabel} service is unreachable"
#. js-lingui-id: 8vJ+2V
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "{stepCount, plural, one {# step} other {# steps}}"
msgstr "{stepCount, plural, one {# step} other {# steps}}"
#. js-lingui-id: Bzjg0/
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
msgid "{stepNumber}. Calendar"
@@ -759,6 +780,11 @@ msgstr "Add \"{trimmedName}\" to options"
msgid "Add a {objectLabelSingular}"
msgstr "Add a {objectLabelSingular}"
#. js-lingui-id: 7W8nJr
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationGroupEditor.tsx
msgid "Add a Group"
msgstr "Add a Group"
#. js-lingui-id: CZDwqQ
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
msgid "Add a new company we're in touch with (e.g. name, website, industry). Details: "
@@ -775,11 +801,6 @@ msgstr "Add a node"
msgid "Add a record"
msgstr "Add a record"
#. js-lingui-id: r8W+9y
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
msgid "Add a Section"
msgstr "Add a Section"
#. js-lingui-id: eMc2xs
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
msgid "Add a step"
@@ -1106,6 +1127,11 @@ msgstr "Adjust the role-related settings"
msgid "Admin"
msgstr "Admin"
#. js-lingui-id: K2OX5h
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Admin Model Controls"
msgstr "Admin Model Controls"
#. js-lingui-id: g1in8j
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
@@ -1134,11 +1160,6 @@ msgstr "Advanced feature to improve the performance of queries and to enforce un
msgid "Advanced filter"
msgstr "Advanced filter"
#. js-lingui-id: luNzWN
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Advanced model for complex planning"
msgstr "Advanced model for complex planning"
#. js-lingui-id: miuPUc
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
@@ -1241,6 +1262,7 @@ msgstr "Aggregate Chart"
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
#: src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectForm.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "AI"
msgstr "AI"
@@ -1252,11 +1274,6 @@ msgstr "AI"
msgid "AI Model"
msgstr "AI Model"
#. js-lingui-id: tGx4Zn
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "AI Models"
msgstr "AI Models"
#. js-lingui-id: Sfwld8
#: src/modules/ai/components/AIChatApiKeyNotConfiguredMessage.tsx
msgid "AI not configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or XAI_API_KEY in your environment."
@@ -1340,6 +1357,11 @@ msgstr "All Members"
msgid "All Metadata"
msgstr "All Metadata"
#. js-lingui-id: AJgjR+
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "All Models"
msgstr "All Models"
#. js-lingui-id: aFE/OW
#: src/pages/settings/security/event-logs/components/EventLogFilters.tsx
#: src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableHeader.tsx
@@ -1501,6 +1523,9 @@ msgstr "An error occurred while uploading the picture."
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
@@ -1597,6 +1622,11 @@ msgstr "API Key"
msgid "API Key copied to clipboard"
msgstr "API Key copied to clipboard"
#. js-lingui-id: jjaYji
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "API key not configured"
msgstr "API key not configured"
#. js-lingui-id: Widx6n
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "API key roles"
@@ -1824,6 +1854,7 @@ msgstr "Ascending"
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
@@ -1962,7 +1993,6 @@ msgstr "Attachments"
#. js-lingui-id: EPEFrH
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "Audit Logs"
msgstr "Audit Logs"
@@ -2052,6 +2082,16 @@ msgstr "Automatically create contacts for people."
msgid "Automatically create People records when receiving or sending emails"
msgstr "Automatically create People records when receiving or sending emails"
#. js-lingui-id: erwsgX
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Automatically enable new models"
msgstr "Automatically enable new models"
#. js-lingui-id: fx8TeY
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Automatically mark new models as available"
msgstr "Automatically mark new models as available"
#. js-lingui-id: lXkUEV
#: src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerManual.tsx
msgid "Availability"
@@ -2059,10 +2099,16 @@ msgstr "Availability"
#. js-lingui-id: csDS2L
#: src/pages/settings/applications/SettingsApplications.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/data-model/new-object/components/SettingsAvailableStandardObjectsSection.tsx
msgid "Available"
msgstr "Available"
#. js-lingui-id: 06gA3L
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Available as tool"
msgstr "Available as tool"
#. js-lingui-id: oD38t2
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Available tools"
@@ -2234,10 +2280,10 @@ msgstr "Brown"
msgid "Build a dashboard that shows: (1) total pipeline value by stage for the last 3 months, (2) count of deals won vs lost per month, (3) average deal size. Use our standard pipeline stages."
msgstr "Build a dashboard that shows: (1) total pipeline value by stage for the last 3 months, (2) count of deals won vs lost per month, (3) average deal size. Use our standard pipeline stages."
#. js-lingui-id: 8SlslB
#. js-lingui-id: alSW5d
#: src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationJunctionForm.tsx
msgid "Build many-to-many relations. <0>Learn more</0>"
msgstr "Build many-to-many relations. <0>Learn more</0>"
msgid "Build many-to-many relations"
msgstr "Build many-to-many relations"
#. js-lingui-id: +7fBMP
#: src/pages/settings/ai/components/SettingsToolsTable.tsx
@@ -2307,6 +2353,7 @@ msgstr "caldav.example.com"
#. js-lingui-id: AjVXBS
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
msgid "Calendar"
msgstr "Calendar"
@@ -2359,6 +2406,11 @@ msgstr "Calendar View"
msgid "Calendars"
msgstr "Calendars"
#. js-lingui-id: qIlodj
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Calling Code"
msgstr "Calling Code"
#. js-lingui-id: msssZq
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Can't change API names for standard objects"
@@ -2495,11 +2547,6 @@ msgstr "Change node type"
msgid "Change Password"
msgstr "Change Password"
#. js-lingui-id: wRtBJP
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Change Plan"
msgstr "Change Plan"
#. js-lingui-id: EYSFEW
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "Change subdomain?"
@@ -2597,7 +2644,7 @@ msgid "Choose the fields that will identify your records"
msgstr "Choose the fields that will identify your records"
#. js-lingui-id: hIJigY
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Choose the format used to display date value"
msgstr "Choose the format used to display date value"
@@ -2700,6 +2747,11 @@ msgstr "Client Secret"
msgid "Client Settings"
msgstr "Client Settings"
#. js-lingui-id: mekEJ5
#: src/hooks/useCopyToClipboard.tsx
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
msgstr "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
#. js-lingui-id: yz7wBu
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
msgid "Close"
@@ -2742,6 +2794,7 @@ msgstr "Code your function"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Collapse"
@@ -2842,10 +2895,14 @@ msgstr "Completed jobs kept for {completedDuration}, failed jobs kept for {faile
msgid "Conditions"
msgstr "Conditions"
#. js-lingui-id: 14PdY0
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config"
msgstr "Config"
#. js-lingui-id: Vj43Y/
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config Variables"
msgstr "Config Variables"
@@ -2860,11 +2917,6 @@ msgstr "Configuration"
msgid "Configure"
msgstr "Configure"
#. js-lingui-id: 9px+al
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Configure AI models for routing and planning"
msgstr "Configure AI models for routing and planning"
#. js-lingui-id: +zUMwJ
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure an SSO connection"
@@ -2890,6 +2942,11 @@ msgstr "Configure CalDAV settings to sync your calendar events."
msgid "Configure date, time, number, timezone, and calendar start day"
msgstr "Configure date, time, number, timezone, and calendar start day"
#. js-lingui-id: +SQwHr
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Configure default AI models and availability"
msgstr "Configure default AI models and availability"
#. js-lingui-id: utsXG8
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure fallback login methods for users with SSO bypass permissions"
@@ -3220,11 +3277,6 @@ msgstr "Core"
msgid "Core Objects"
msgstr "Core Objects"
#. js-lingui-id: cfa2VJ
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Core Schema"
msgstr "Core Schema"
#. js-lingui-id: I99Miw
#: src/modules/billing/components/SettingsBillingCreditsSection.tsx
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
@@ -3296,11 +3348,6 @@ msgstr "Count unique values"
msgid "Country"
msgstr "Country"
#. js-lingui-id: j2OqfX
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Country Code"
msgstr "Country Code"
#. js-lingui-id: gJdfqX
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "create"
@@ -4248,6 +4295,16 @@ msgstr "Deleted records"
msgid "Deleting this method will remove it permanently from your account."
msgstr "Deleting this method will remove it permanently from your account."
#. js-lingui-id: Ssdrw4
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated"
msgstr "Deprecated"
#. js-lingui-id: 8OJZ/p
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated models"
msgstr "Deprecated models"
#. js-lingui-id: O3LJh6
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
@@ -4821,6 +4878,7 @@ msgstr "Emailing Domains"
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Emails"
msgstr "Emails"
@@ -4872,6 +4930,7 @@ msgstr "Empty"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Array"
@@ -4892,6 +4951,7 @@ msgstr "Empty Inbox"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Object"
@@ -5019,10 +5079,10 @@ msgstr "Enter files as JSON array"
msgid "Enter filter"
msgstr "Enter filter"
#. js-lingui-id: 9/30HU
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
msgid "Enter in <0>Unicode</0> format"
msgstr "Enter in <0>Unicode</0> format"
#. js-lingui-id: f09Lhk
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Enter in Unicode format"
msgstr "Enter in Unicode format"
#. js-lingui-id: 9CjMQ7
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx
@@ -5087,6 +5147,11 @@ msgstr "Enter test value"
msgid "Enter text"
msgstr "Enter text"
#. js-lingui-id: +rrO69
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
msgid "Enter text or type '/' for commands"
msgstr "Enter text or type '/' for commands"
#. js-lingui-id: yZMXC2
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
msgid "Enter text or Type '/' for commands"
@@ -5483,6 +5548,7 @@ msgstr "Exit Settings"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Expand"
@@ -5782,16 +5848,37 @@ msgstr "Failed to save role permissions: {errorMessage}"
msgid "Failed to save workspace instructions"
msgstr "Failed to save workspace instructions"
#. js-lingui-id: YMSYb+
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update fast model"
msgstr "Failed to update fast model"
#. js-lingui-id: YzURPo
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update auto-enable setting"
msgstr "Failed to update auto-enable setting"
#. js-lingui-id: P1NmNz
#: src/modules/settings/admin-panel/components/SettingsAdminWorkspaceContent.tsx
msgid "Failed to update feature flag. {errorMessage}"
msgstr "Failed to update feature flag. {errorMessage}"
#. js-lingui-id: 1R13Ov
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model"
msgstr "Failed to update model"
#. js-lingui-id: W7Ff/4
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update model availability"
msgstr "Failed to update model availability"
#. js-lingui-id: LgZlJ7
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model availability settings"
msgstr "Failed to update model availability settings"
#. js-lingui-id: rCUG3c
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model selection mode"
msgstr "Failed to update model selection mode"
#. js-lingui-id: HnBqPY
#: src/modules/billing/components/internal/MeteredPriceSelector.tsx
msgid "Failed to update price."
@@ -5807,11 +5894,6 @@ msgstr "Failed to update records. Please try again."
msgid "Failed to update role"
msgstr "Failed to update role"
#. js-lingui-id: h/0aT5
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update smart model"
msgstr "Failed to update smart model"
#. js-lingui-id: Dzh4a2
#: src/modules/settings/admin-panel/config-variables/hooks/useConfigVariableActions.ts
msgid "Failed to update variable"
@@ -5860,15 +5942,10 @@ msgid "False"
msgstr "False"
#. js-lingui-id: XVIZ7v
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Fast Model"
msgstr "Fast Model"
#. js-lingui-id: UJHTjm
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Fast model updated successfully"
msgstr "Fast model updated successfully"
#. js-lingui-id: X9kySA
#: src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx
#: src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx
@@ -6013,6 +6090,11 @@ msgstr "File upload failed"
msgid "File URL is not defined"
msgstr "File URL is not defined"
#. js-lingui-id: sER+bs
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Files"
msgstr "Files"
#. js-lingui-id: o7J4JM
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
@@ -6022,6 +6104,7 @@ msgstr "File URL is not defined"
#: src/modules/views/components/ViewBarFilterButton.tsx
#: src/modules/settings/roles/components/SettingsRolesList.tsx
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
#: src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx
@@ -6116,6 +6199,7 @@ msgstr "First name can not be empty"
#. js-lingui-id: ylQd2j
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "Flow"
msgstr "Flow"
@@ -6250,7 +6334,9 @@ msgstr "Gauge Chart"
#: src/pages/settings/SettingsWorkspace.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetEditorGroupsData.ts
#: src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenuOpenContent.tsx
msgid "General"
msgstr "General"
@@ -6492,11 +6578,15 @@ msgstr "Heading 2"
msgid "Heading 3"
msgstr "Heading 3"
#. js-lingui-id: UPqS9C
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health"
msgstr "Health"
#. js-lingui-id: I1IOmb
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
#: src/modules/settings/admin-panel/health-status/components/SettingsAdminHealthStatus.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health Status"
msgstr "Health Status"
@@ -6581,6 +6671,11 @@ msgstr "Hide group {groupValue}"
msgid "Hide hidden groups"
msgstr "Hide hidden groups"
#. js-lingui-id: i0qMbr
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Home"
msgstr "Home"
#. js-lingui-id: Xkd22/
#: src/modules/page-layout/utils/getWidgetTitle.ts
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
@@ -6892,6 +6987,7 @@ msgstr "Infos"
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Input"
msgstr "Input"
@@ -6968,11 +7064,6 @@ msgstr "Instructions for AI"
msgid "Integrations - Settings"
msgstr "Integrations - Settings"
#. js-lingui-id: ntgzzG
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Interact with your workspace data"
msgstr "Interact with your workspace data"
#. js-lingui-id: jyjroS
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Interval switching has been cancelled."
@@ -7949,6 +8040,11 @@ msgstr "Max range"
msgid "Maximum email addresses"
msgstr "Maximum email addresses"
#. js-lingui-id: 9UHNQc
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Maximum execution time in seconds (1-900)"
msgstr "Maximum execution time in seconds (1-900)"
#. js-lingui-id: PAhTVY
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
msgid "Maximum files"
@@ -8081,11 +8177,6 @@ msgstr "Metadata"
msgid "Metadata file generation failed"
msgstr "Metadata file generation failed"
#. js-lingui-id: 0BF9eC
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Metadata Schema"
msgstr "Metadata Schema"
#. js-lingui-id: onCJJ6
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Metered tier switching has been cancelled."
@@ -8144,6 +8235,17 @@ msgstr "Missing email draft permission."
msgid "Mission accomplished!"
msgstr "Mission accomplished!"
#. js-lingui-id: //nm2/
#: src/pages/settings/ai/SettingsAI.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models"
msgstr "Models"
#. js-lingui-id: oHM560
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models available in the chat model picker"
msgstr "Models available in the chat model picker"
#. js-lingui-id: hty0d5
#: src/pages/settings/profile/appearance/components/DateTimeSettingsCalendarStartDaySelect.tsx
msgid "Monday"
@@ -8189,6 +8291,7 @@ msgid "months"
msgstr "months"
#. js-lingui-id: 2FYpfJ
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/ui/layout/tab-list/components/TabMoreButton.tsx
msgid "More"
msgstr "More"
@@ -8478,6 +8581,11 @@ msgstr "New Field"
msgid "New folder"
msgstr "New folder"
#. js-lingui-id: 93KA8w
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationEditor.tsx
msgid "New Group"
msgstr "New Group"
#. js-lingui-id: o8MyXb
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "New key"
@@ -8651,6 +8759,11 @@ msgstr "No available fields to select"
msgid "No body"
msgstr "No body"
#. js-lingui-id: c3+z7H
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
msgid "No calling code"
msgstr "No calling code"
#. js-lingui-id: OTe3RI
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "No change detected"
@@ -8681,7 +8794,6 @@ msgstr "No context was provided for this request"
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
msgid "No country"
msgstr "No country"
@@ -8882,7 +8994,6 @@ msgstr "No metrics data available"
#. js-lingui-id: UWZZdQ
#: src/pages/settings/ai/forms/components/SettingsAIAgentForm.tsx
#: src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "No models available. Please configure AI models in your workspace settings."
msgstr "No models available. Please configure AI models in your workspace settings."
@@ -9119,7 +9230,13 @@ msgstr "Not shared by {notSharedByFullName}"
msgid "Not synced"
msgstr "Not synced"
#. js-lingui-id: KiJn9B
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Note"
msgstr "Note"
#. js-lingui-id: 1DBGsz
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Notes"
msgstr "Notes"
@@ -9497,6 +9614,11 @@ msgstr "Ordered List"
msgid "Organization"
msgstr "Organization"
#. js-lingui-id: zi/p7n
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Organization plan"
msgstr "Organization plan"
#. js-lingui-id: nV6twc
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
msgid "Organize"
@@ -9509,7 +9631,7 @@ msgstr "Organize"
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/pages/settings/admin-panel/SettingsAdmin.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemMainMenu.tsx
msgid "Other"
msgstr "Other"
@@ -9555,6 +9677,7 @@ msgstr "Outage"
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/TerminalOutput.tsx
#: src/modules/ai/components/CodeExecutionDisplay.tsx
msgid "Output"
@@ -10056,6 +10179,11 @@ msgstr "Privacy Policy"
msgid "Pro"
msgstr "Pro"
#. js-lingui-id: r5je1s
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Pro plan"
msgstr "Pro plan"
#. js-lingui-id: k1ifdL
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
@@ -10191,11 +10319,6 @@ msgstr "Queue performance"
msgid "Queue: {queueName}"
msgstr "Queue: {queueName}"
#. js-lingui-id: GaAG2G
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Quick model for routing decisions"
msgstr "Quick model for routing decisions"
#. js-lingui-id: opSifa
#: src/modules/ai/utils/getToolDisplayMessage.ts
msgid "Ran {formattedName}"
@@ -10672,6 +10795,11 @@ msgstr "Restore records"
msgid "Restore Records"
msgstr "Restore Records"
#. js-lingui-id: hO3AfV
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Restrict available models to a curated list"
msgstr "Restrict available models to a curated list"
#. js-lingui-id: RD6AE9
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
msgid "Result"
@@ -10953,6 +11081,12 @@ msgstr "Search a field..."
msgid "Search a folder..."
msgstr "Search a folder..."
#. js-lingui-id: 8J0e5B
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Search a model..."
msgstr "Search a model..."
#. js-lingui-id: WXvlVa
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "Search a role..."
@@ -11506,6 +11640,11 @@ msgstr "Sent and Received"
msgid "Serbian (Cyrillic)"
msgstr "Serbian (Cyrillic)"
#. js-lingui-id: 8ZSrlB
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Server-wide AI model availability settings"
msgstr "Server-wide AI model availability settings"
#. js-lingui-id: LUc0oL
#: src/modules/settings/security/components/SSO/SettingsSSOSAMLForm.tsx
msgid "Service Provider Details"
@@ -11588,7 +11727,6 @@ msgstr "Setting up your database..."
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
#: src/pages/settings/ai/SettingsAgentForm.tsx
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/sign-in-background-mock/components/SignInAppNavigationDrawerMock.tsx
#: src/modules/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsSection.tsx
#: src/modules/settings/roles/role/components/SettingsRole.tsx
@@ -11807,15 +11945,10 @@ msgid "Small section heading"
msgstr "Small section heading"
#. js-lingui-id: 5J8ZFl
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Smart Model"
msgstr "Smart Model"
#. js-lingui-id: qgvZ/2
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Smart model updated successfully"
msgstr "Smart model updated successfully"
#. js-lingui-id: w+rJId
#: src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx
msgid "SMTP Configuration"
@@ -11915,6 +12048,14 @@ msgstr "Spaces and comma - {spacesAndCommaExample}"
msgid "Spanish"
msgstr "Spanish"
#. js-lingui-id: gsifzp
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Split multiple values"
msgstr "Split multiple values"
#. js-lingui-id: vnS6Rf
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "SSO"
@@ -12393,6 +12534,7 @@ msgid "Task Title"
msgstr "Task Title"
#. js-lingui-id: GtycJ/
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Tasks"
msgstr "Tasks"
@@ -12592,6 +12734,11 @@ msgstr "There is no activity associated with this record."
msgid "There was an error while updating password."
msgstr "There was an error while updating password."
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
msgstr "Thinking"
#. js-lingui-id: Ed99mE
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
msgid "Thinking..."
@@ -12781,6 +12928,11 @@ msgstr "This will permanently delete your two factor authentication method.<0/>S
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
msgstr "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
#. js-lingui-id: f8HOUp
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thought"
msgstr "Thought"
#. js-lingui-id: 5g/sE8
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
msgid "Tidy up"
@@ -12812,10 +12964,16 @@ msgid "Time zone"
msgstr "Time zone"
#. js-lingui-id: cklVjM
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
msgid "Timeline"
msgstr "Timeline"
#. js-lingui-id: xY9s5E
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Timeout"
msgstr "Timeout"
#. js-lingui-id: 8TMaZI
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
@@ -12871,6 +13029,11 @@ msgstr "Toggle all object permissions"
msgid "Toggle all settings permissions"
msgstr "Toggle all settings permissions"
#. js-lingui-id: 93pMSK
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Toggle model availability across all workspaces"
msgstr "Toggle model availability across all workspaces"
#. js-lingui-id: WOr+hW
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
msgid "tokens"
@@ -13128,7 +13291,6 @@ msgid "Type"
msgstr "Type"
#. js-lingui-id: SKD2e4
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
#: src/modules/activities/components/ActivityRichTextEditor.tsx
msgid "Type '/' for commands, '@' for mentions"
msgstr "Type '/' for commands, '@' for mentions"
@@ -13169,6 +13331,11 @@ msgstr "Unable to delete member right now"
msgid "Unable to Reach Back-end"
msgstr "Unable to Reach Back-end"
#. js-lingui-id: EbnX+O
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Unconfigured models"
msgstr "Unconfigured models"
#. js-lingui-id: EUHN7i
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableValueInput.tsx
msgid "Undefined"
@@ -13479,11 +13646,26 @@ msgstr "Use as draft"
msgid "Use authenticator apps and browser extensions like 1Password, Authy, Microsoft Authenticator to generate one-time passwords"
msgstr "Use authenticator apps and browser extensions like 1Password, Authy, Microsoft Authenticator to generate one-time passwords"
#. js-lingui-id: hCZsJ0
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Use best models only"
msgstr "Use best models only"
#. js-lingui-id: c6uZUV
#: src/modules/object-record/record-table/empty-state/utils/getEmptyStateSubTitle.ts
msgid "Use our API or add your first {objectLabel} manually"
msgstr "Use our API or add your first {objectLabel} manually"
#. js-lingui-id: 664z2C
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for chats, agents, and complex reasoning"
msgstr "Used for chats, agents, and complex reasoning"
#. js-lingui-id: C41qgx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for lightweight tasks like title generation"
msgstr "Used for lightweight tasks like title generation"
#. js-lingui-id: AQVj2A
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Useful for pivot/junction tables"
@@ -13732,8 +13914,6 @@ msgid "View Logs"
msgstr "View Logs"
#. js-lingui-id: ecVcAx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
msgid "View Previous AI Chats"
@@ -13989,6 +14169,21 @@ msgstr "When a new lead is created with source \"Website\", assign it to the sal
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
msgstr "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
#. js-lingui-id: 8jc/Xn
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "When enabled, AI agents and workflow automations can discover and call this function"
msgstr "When enabled, AI agents and workflow automations can discover and call this function"
#. js-lingui-id: i2V4DO
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "When enabled, new AI models will be available to users by default"
msgstr "When enabled, new AI models will be available to users by default"
#. js-lingui-id: 01e9rV
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "When enabled, newly added models are available to all workspaces by default"
msgstr "When enabled, newly added models are available to all workspaces by default"
#. js-lingui-id: C51ilI
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "When the API key will expire."
@@ -14121,6 +14316,7 @@ msgid "Workspace Domain"
msgstr "Workspace Domain"
#. js-lingui-id: J2q6WC
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/components/EventLogTableSelector.tsx
msgid "Workspace Events"
msgstr "Workspace Events"
+284 -88
View File
@@ -106,6 +106,7 @@ msgstr "(seleccionado: {selectedIconKey})"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "[empty string]"
@@ -310,6 +311,11 @@ msgstr "{morphRelationCount} objetos"
msgid "{num, selectordinal, one {{num}st} two {{num}nd} few {{num}rd} other {{num}th}}"
msgstr "{num, selectordinal, one {{num}º} other {{num}.º}}"
#. js-lingui-id: fTSz8d
#: src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownActorSelect.tsx
msgid "{numberOfSelectedItems} workspace members"
msgstr ""
#. js-lingui-id: 7kYa/u
#: src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts
msgid "{objectLabelPlural} ({totalCount})"
@@ -330,6 +336,16 @@ msgstr ""
msgid "{positionLabel} record holds priority"
msgstr "El registro {positionLabel} tiene prioridad"
#. js-lingui-id: YG/wl5
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — API key not configured"
msgstr ""
#. js-lingui-id: s80lrU
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — Deprecated"
msgstr ""
#. js-lingui-id: Sxx5Hr
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "{recordCount} of {totalCount} records"
@@ -381,6 +397,11 @@ msgstr "{selectedCount} tipos de origen"
msgid "{serviceLabel} service is unreachable"
msgstr "El servicio {serviceLabel} no es accesible"
#. js-lingui-id: 8vJ+2V
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "{stepCount, plural, one {# step} other {# steps}}"
msgstr ""
#. js-lingui-id: Bzjg0/
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
msgid "{stepNumber}. Calendar"
@@ -764,6 +785,11 @@ msgstr "Agregar \"{trimmedName}\" a las opciones"
msgid "Add a {objectLabelSingular}"
msgstr "Agregar un {objectLabelSingular}"
#. js-lingui-id: 7W8nJr
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationGroupEditor.tsx
msgid "Add a Group"
msgstr ""
#. js-lingui-id: CZDwqQ
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
msgid "Add a new company we're in touch with (e.g. name, website, industry). Details: "
@@ -780,11 +806,6 @@ msgstr "Añadir un nodo"
msgid "Add a record"
msgstr ""
#. js-lingui-id: r8W+9y
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
msgid "Add a Section"
msgstr ""
#. js-lingui-id: eMc2xs
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
msgid "Add a step"
@@ -1111,6 +1132,11 @@ msgstr "Ajusta la configuración relacionada con el rol"
msgid "Admin"
msgstr ""
#. js-lingui-id: K2OX5h
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Admin Model Controls"
msgstr ""
#. js-lingui-id: g1in8j
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
@@ -1139,11 +1165,6 @@ msgstr "Característica avanzada para mejorar el rendimiento de consultas y para
msgid "Advanced filter"
msgstr "Filtro avanzado"
#. js-lingui-id: luNzWN
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Advanced model for complex planning"
msgstr ""
#. js-lingui-id: miuPUc
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
@@ -1246,6 +1267,7 @@ msgstr ""
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
#: src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectForm.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "AI"
msgstr "IA"
@@ -1257,11 +1279,6 @@ msgstr "IA"
msgid "AI Model"
msgstr "Modelo de IA"
#. js-lingui-id: tGx4Zn
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "AI Models"
msgstr ""
#. js-lingui-id: Sfwld8
#: src/modules/ai/components/AIChatApiKeyNotConfiguredMessage.tsx
msgid "AI not configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or XAI_API_KEY in your environment."
@@ -1345,6 +1362,11 @@ msgstr ""
msgid "All Metadata"
msgstr ""
#. js-lingui-id: AJgjR+
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "All Models"
msgstr ""
#. js-lingui-id: aFE/OW
#: src/pages/settings/security/event-logs/components/EventLogFilters.tsx
#: src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableHeader.tsx
@@ -1506,6 +1528,9 @@ msgstr "Se produjo un error al subir la imagen."
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
@@ -1602,6 +1627,11 @@ msgstr "Clave API"
msgid "API Key copied to clipboard"
msgstr "Clave API copiada al portapapeles"
#. js-lingui-id: jjaYji
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "API key not configured"
msgstr ""
#. js-lingui-id: Widx6n
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "API key roles"
@@ -1829,6 +1859,7 @@ msgstr "Ascendente"
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
@@ -1967,7 +1998,6 @@ msgstr "Adjuntos"
#. js-lingui-id: EPEFrH
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "Audit Logs"
msgstr ""
@@ -2057,6 +2087,16 @@ msgstr "Crear automáticamente contactos para las personas."
msgid "Automatically create People records when receiving or sending emails"
msgstr "Crear automáticamente registros de personas al recibir o enviar correos electrónicos"
#. js-lingui-id: erwsgX
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Automatically enable new models"
msgstr ""
#. js-lingui-id: fx8TeY
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Automatically mark new models as available"
msgstr ""
#. js-lingui-id: lXkUEV
#: src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerManual.tsx
msgid "Availability"
@@ -2064,10 +2104,16 @@ msgstr "Disponibilidad"
#. js-lingui-id: csDS2L
#: src/pages/settings/applications/SettingsApplications.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/data-model/new-object/components/SettingsAvailableStandardObjectsSection.tsx
msgid "Available"
msgstr "Disponible"
#. js-lingui-id: 06gA3L
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Available as tool"
msgstr ""
#. js-lingui-id: oD38t2
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Available tools"
@@ -2239,9 +2285,9 @@ msgstr "Marrón"
msgid "Build a dashboard that shows: (1) total pipeline value by stage for the last 3 months, (2) count of deals won vs lost per month, (3) average deal size. Use our standard pipeline stages."
msgstr ""
#. js-lingui-id: 8SlslB
#. js-lingui-id: alSW5d
#: src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationJunctionForm.tsx
msgid "Build many-to-many relations. <0>Learn more</0>"
msgid "Build many-to-many relations"
msgstr ""
#. js-lingui-id: +7fBMP
@@ -2312,6 +2358,7 @@ msgstr "caldav.example.com"
#. js-lingui-id: AjVXBS
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
msgid "Calendar"
msgstr "Calendario"
@@ -2364,6 +2411,11 @@ msgstr "Vista del calendario"
msgid "Calendars"
msgstr "Calendarios"
#. js-lingui-id: qIlodj
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Calling Code"
msgstr ""
#. js-lingui-id: msssZq
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Can't change API names for standard objects"
@@ -2500,11 +2552,6 @@ msgstr "Cambiar tipo de nodo"
msgid "Change Password"
msgstr "Cambiar contraseña"
#. js-lingui-id: wRtBJP
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Change Plan"
msgstr "Cambiar plan"
#. js-lingui-id: EYSFEW
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "Change subdomain?"
@@ -2602,7 +2649,7 @@ msgid "Choose the fields that will identify your records"
msgstr "Elige los campos que identificarán tus registros"
#. js-lingui-id: hIJigY
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Choose the format used to display date value"
msgstr "Elige el formato utilizado para mostrar el valor de la fecha"
@@ -2705,6 +2752,11 @@ msgstr "Secreto del cliente"
msgid "Client Settings"
msgstr "Configuración de Cliente"
#. js-lingui-id: mekEJ5
#: src/hooks/useCopyToClipboard.tsx
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
msgstr ""
#. js-lingui-id: yz7wBu
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
msgid "Close"
@@ -2747,6 +2799,7 @@ msgstr "Codificar su función"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Collapse"
@@ -2847,10 +2900,14 @@ msgstr "Trabajos completados guardados por {completedDuration}, trabajos fallido
msgid "Conditions"
msgstr "Condiciones"
#. js-lingui-id: 14PdY0
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config"
msgstr ""
#. js-lingui-id: Vj43Y/
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config Variables"
msgstr "Variables de configuración"
@@ -2865,11 +2922,6 @@ msgstr "Configuración"
msgid "Configure"
msgstr ""
#. js-lingui-id: 9px+al
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Configure AI models for routing and planning"
msgstr ""
#. js-lingui-id: +zUMwJ
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure an SSO connection"
@@ -2895,6 +2947,11 @@ msgstr "Configura los ajustes de CalDAV para sincronizar tus eventos de calendar
msgid "Configure date, time, number, timezone, and calendar start day"
msgstr "Configurar fecha, hora, número, zona horaria y día de inicio del calendario"
#. js-lingui-id: +SQwHr
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Configure default AI models and availability"
msgstr ""
#. js-lingui-id: utsXG8
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure fallback login methods for users with SSO bypass permissions"
@@ -3225,11 +3282,6 @@ msgstr "Núcleo"
msgid "Core Objects"
msgstr ""
#. js-lingui-id: cfa2VJ
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Core Schema"
msgstr "Esquema principal"
#. js-lingui-id: I99Miw
#: src/modules/billing/components/SettingsBillingCreditsSection.tsx
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
@@ -3301,11 +3353,6 @@ msgstr "Contar valores únicos"
msgid "Country"
msgstr "País"
#. js-lingui-id: j2OqfX
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Country Code"
msgstr "Código de país"
#. js-lingui-id: gJdfqX
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "create"
@@ -4253,6 +4300,16 @@ msgstr "Registros eliminados"
msgid "Deleting this method will remove it permanently from your account."
msgstr "Eliminar este método lo eliminará permanentemente de tu cuenta."
#. js-lingui-id: Ssdrw4
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated"
msgstr ""
#. js-lingui-id: 8OJZ/p
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated models"
msgstr ""
#. js-lingui-id: O3LJh6
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
@@ -4826,6 +4883,7 @@ msgstr "Dominios de correo electrónico"
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Emails"
msgstr "Correos electrónicos"
@@ -4877,6 +4935,7 @@ msgstr "Vacío"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Array"
@@ -4897,6 +4956,7 @@ msgstr "Bandeja de entrada vacía"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Object"
@@ -5024,10 +5084,10 @@ msgstr ""
msgid "Enter filter"
msgstr "Introduce un filtro"
#. js-lingui-id: 9/30HU
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
msgid "Enter in <0>Unicode</0> format"
msgstr "Ingresar en formato <0>Unicode</0>"
#. js-lingui-id: f09Lhk
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Enter in Unicode format"
msgstr ""
#. js-lingui-id: 9CjMQ7
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx
@@ -5092,6 +5152,11 @@ msgstr "Introduce el valor de prueba"
msgid "Enter text"
msgstr "Introduce texto"
#. js-lingui-id: +rrO69
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
msgid "Enter text or type '/' for commands"
msgstr ""
#. js-lingui-id: yZMXC2
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
msgid "Enter text or Type '/' for commands"
@@ -5488,6 +5553,7 @@ msgstr "Salir de Configuración"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Expand"
@@ -5787,9 +5853,9 @@ msgstr "Error al guardar los permisos de rol: {errorMessage}"
msgid "Failed to save workspace instructions"
msgstr ""
#. js-lingui-id: YMSYb+
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update fast model"
#. js-lingui-id: YzURPo
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update auto-enable setting"
msgstr ""
#. js-lingui-id: P1NmNz
@@ -5797,6 +5863,27 @@ msgstr ""
msgid "Failed to update feature flag. {errorMessage}"
msgstr "No se pudo actualizar el feature flag. {errorMessage}"
#. js-lingui-id: 1R13Ov
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model"
msgstr ""
#. js-lingui-id: W7Ff/4
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update model availability"
msgstr ""
#. js-lingui-id: LgZlJ7
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model availability settings"
msgstr ""
#. js-lingui-id: rCUG3c
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model selection mode"
msgstr ""
#. js-lingui-id: HnBqPY
#: src/modules/billing/components/internal/MeteredPriceSelector.tsx
msgid "Failed to update price."
@@ -5812,11 +5899,6 @@ msgstr ""
msgid "Failed to update role"
msgstr "Error al actualizar el rol"
#. js-lingui-id: h/0aT5
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update smart model"
msgstr ""
#. js-lingui-id: Dzh4a2
#: src/modules/settings/admin-panel/config-variables/hooks/useConfigVariableActions.ts
msgid "Failed to update variable"
@@ -5865,15 +5947,10 @@ msgid "False"
msgstr "Falso"
#. js-lingui-id: XVIZ7v
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Fast Model"
msgstr ""
#. js-lingui-id: UJHTjm
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Fast model updated successfully"
msgstr ""
#. js-lingui-id: X9kySA
#: src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx
#: src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx
@@ -6018,6 +6095,11 @@ msgstr ""
msgid "File URL is not defined"
msgstr ""
#. js-lingui-id: sER+bs
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Files"
msgstr ""
#. js-lingui-id: o7J4JM
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
@@ -6027,6 +6109,7 @@ msgstr ""
#: src/modules/views/components/ViewBarFilterButton.tsx
#: src/modules/settings/roles/components/SettingsRolesList.tsx
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
#: src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx
@@ -6121,6 +6204,7 @@ msgstr "El nombre no puede estar vacío"
#. js-lingui-id: ylQd2j
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "Flow"
msgstr "Flujo"
@@ -6255,7 +6339,9 @@ msgstr "Gráfico de Medidor"
#: src/pages/settings/SettingsWorkspace.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetEditorGroupsData.ts
#: src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenuOpenContent.tsx
msgid "General"
msgstr "General"
@@ -6497,11 +6583,15 @@ msgstr "Encabezado 2"
msgid "Heading 3"
msgstr "Encabezado 3"
#. js-lingui-id: UPqS9C
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health"
msgstr ""
#. js-lingui-id: I1IOmb
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
#: src/modules/settings/admin-panel/health-status/components/SettingsAdminHealthStatus.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health Status"
msgstr "Estado de Salud"
@@ -6586,6 +6676,11 @@ msgstr "Ocultar grupo {groupValue}"
msgid "Hide hidden groups"
msgstr "Ocultar grupos ocultos"
#. js-lingui-id: i0qMbr
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Home"
msgstr ""
#. js-lingui-id: Xkd22/
#: src/modules/page-layout/utils/getWidgetTitle.ts
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
@@ -6897,6 +6992,7 @@ msgstr "Información"
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Input"
msgstr "Entrada"
@@ -6973,11 +7069,6 @@ msgstr "Instrucciones para la IA"
msgid "Integrations - Settings"
msgstr "Integraciones - Ajustes"
#. js-lingui-id: ntgzzG
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Interact with your workspace data"
msgstr "Interactúe con los datos de su espacio de trabajo"
#. js-lingui-id: jyjroS
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Interval switching has been cancelled."
@@ -7954,6 +8045,11 @@ msgstr "Rango máximo"
msgid "Maximum email addresses"
msgstr "Máximo de direcciones de correo electrónico"
#. js-lingui-id: 9UHNQc
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Maximum execution time in seconds (1-900)"
msgstr ""
#. js-lingui-id: PAhTVY
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
msgid "Maximum files"
@@ -8086,11 +8182,6 @@ msgstr "Metadatos"
msgid "Metadata file generation failed"
msgstr "Fallo en la generación del archivo de metadatos"
#. js-lingui-id: 0BF9eC
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Metadata Schema"
msgstr "Esquema de metadatos"
#. js-lingui-id: onCJJ6
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Metered tier switching has been cancelled."
@@ -8149,6 +8240,17 @@ msgstr ""
msgid "Mission accomplished!"
msgstr "¡Misión cumplida!"
#. js-lingui-id: //nm2/
#: src/pages/settings/ai/SettingsAI.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models"
msgstr ""
#. js-lingui-id: oHM560
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models available in the chat model picker"
msgstr ""
#. js-lingui-id: hty0d5
#: src/pages/settings/profile/appearance/components/DateTimeSettingsCalendarStartDaySelect.tsx
msgid "Monday"
@@ -8194,6 +8296,7 @@ msgid "months"
msgstr ""
#. js-lingui-id: 2FYpfJ
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/ui/layout/tab-list/components/TabMoreButton.tsx
msgid "More"
msgstr "Más"
@@ -8483,6 +8586,11 @@ msgstr "Nuevo Campo"
msgid "New folder"
msgstr ""
#. js-lingui-id: 93KA8w
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationEditor.tsx
msgid "New Group"
msgstr ""
#. js-lingui-id: o8MyXb
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "New key"
@@ -8656,6 +8764,11 @@ msgstr "No hay campos disponibles para seleccionar"
msgid "No body"
msgstr "Sin cuerpo"
#. js-lingui-id: c3+z7H
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
msgid "No calling code"
msgstr ""
#. js-lingui-id: OTe3RI
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "No change detected"
@@ -8686,7 +8799,6 @@ msgstr "No se proporcionó contexto para esta solicitud"
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
msgid "No country"
msgstr "Sin país"
@@ -8887,7 +8999,6 @@ msgstr "No hay datos de métricas disponibles"
#. js-lingui-id: UWZZdQ
#: src/pages/settings/ai/forms/components/SettingsAIAgentForm.tsx
#: src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "No models available. Please configure AI models in your workspace settings."
msgstr "No hay modelos disponibles. Por favor configure modelos de IA en la configuración de su espacio de trabajo."
@@ -9124,7 +9235,13 @@ msgstr "No compartido por {notSharedByFullName}"
msgid "Not synced"
msgstr "No sincronizado"
#. js-lingui-id: KiJn9B
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Note"
msgstr ""
#. js-lingui-id: 1DBGsz
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Notes"
msgstr "Notas"
@@ -9502,6 +9619,11 @@ msgstr "Lista ordenada"
msgid "Organization"
msgstr "Organización"
#. js-lingui-id: zi/p7n
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Organization plan"
msgstr ""
#. js-lingui-id: nV6twc
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
msgid "Organize"
@@ -9514,7 +9636,7 @@ msgstr ""
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/pages/settings/admin-panel/SettingsAdmin.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemMainMenu.tsx
msgid "Other"
msgstr "Otros"
@@ -9560,6 +9682,7 @@ msgstr "Interrupción"
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/TerminalOutput.tsx
#: src/modules/ai/components/CodeExecutionDisplay.tsx
msgid "Output"
@@ -10061,6 +10184,11 @@ msgstr "Política de privacidad"
msgid "Pro"
msgstr "Pro"
#. js-lingui-id: r5je1s
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Pro plan"
msgstr ""
#. js-lingui-id: k1ifdL
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
@@ -10196,11 +10324,6 @@ msgstr "Rendimiento de la cola"
msgid "Queue: {queueName}"
msgstr "Cola: {queueName}"
#. js-lingui-id: GaAG2G
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Quick model for routing decisions"
msgstr ""
#. js-lingui-id: opSifa
#: src/modules/ai/utils/getToolDisplayMessage.ts
msgid "Ran {formattedName}"
@@ -10677,6 +10800,11 @@ msgstr "Restaurar registros"
msgid "Restore Records"
msgstr "Restaurar registros"
#. js-lingui-id: hO3AfV
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Restrict available models to a curated list"
msgstr ""
#. js-lingui-id: RD6AE9
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
msgid "Result"
@@ -10958,6 +11086,12 @@ msgstr "Buscar un campo..."
msgid "Search a folder..."
msgstr ""
#. js-lingui-id: 8J0e5B
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Search a model..."
msgstr ""
#. js-lingui-id: WXvlVa
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "Search a role..."
@@ -11511,6 +11645,11 @@ msgstr "Enviado y recibido"
msgid "Serbian (Cyrillic)"
msgstr "Serbio (cirílico)"
#. js-lingui-id: 8ZSrlB
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Server-wide AI model availability settings"
msgstr ""
#. js-lingui-id: LUc0oL
#: src/modules/settings/security/components/SSO/SettingsSSOSAMLForm.tsx
msgid "Service Provider Details"
@@ -11593,7 +11732,6 @@ msgstr "Configurando su base de datos..."
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
#: src/pages/settings/ai/SettingsAgentForm.tsx
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/sign-in-background-mock/components/SignInAppNavigationDrawerMock.tsx
#: src/modules/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsSection.tsx
#: src/modules/settings/roles/role/components/SettingsRole.tsx
@@ -11812,15 +11950,10 @@ msgid "Small section heading"
msgstr "Encabezado de sección pequeña"
#. js-lingui-id: 5J8ZFl
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Smart Model"
msgstr ""
#. js-lingui-id: qgvZ/2
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Smart model updated successfully"
msgstr ""
#. js-lingui-id: w+rJId
#: src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx
msgid "SMTP Configuration"
@@ -11920,6 +12053,14 @@ msgstr "Espacios y coma - {spacesAndCommaExample}"
msgid "Spanish"
msgstr "Español"
#. js-lingui-id: gsifzp
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Split multiple values"
msgstr ""
#. js-lingui-id: vnS6Rf
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "SSO"
@@ -12398,6 +12539,7 @@ msgid "Task Title"
msgstr "Título de la tarea"
#. js-lingui-id: GtycJ/
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Tasks"
msgstr "Tareas"
@@ -12597,6 +12739,11 @@ msgstr "No hay actividad asociada con este registro."
msgid "There was an error while updating password."
msgstr "Hubo un error al actualizar la contraseña."
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
msgstr ""
#. js-lingui-id: Ed99mE
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
msgid "Thinking..."
@@ -12786,6 +12933,11 @@ msgstr "Esto eliminará permanentemente tu método de autenticación de dos fact
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
msgstr "Esto revertirá el valor de la base de datos al valor de entorno/predeterminado. Se eliminará la anulación de la base de datos y el sistema utilizará la configuración del entorno."
#. js-lingui-id: f8HOUp
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thought"
msgstr ""
#. js-lingui-id: 5g/sE8
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
msgid "Tidy up"
@@ -12817,10 +12969,16 @@ msgid "Time zone"
msgstr "Zona horaria"
#. js-lingui-id: cklVjM
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
msgid "Timeline"
msgstr "Cronología"
#. js-lingui-id: xY9s5E
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Timeout"
msgstr ""
#. js-lingui-id: 8TMaZI
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
@@ -12876,6 +13034,11 @@ msgstr "Alternar permisos de todos los objetos"
msgid "Toggle all settings permissions"
msgstr "Alternar todos los permisos de configuración"
#. js-lingui-id: 93pMSK
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Toggle model availability across all workspaces"
msgstr ""
#. js-lingui-id: WOr+hW
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
msgid "tokens"
@@ -13133,7 +13296,6 @@ msgid "Type"
msgstr "Tipo"
#. js-lingui-id: SKD2e4
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
#: src/modules/activities/components/ActivityRichTextEditor.tsx
msgid "Type '/' for commands, '@' for mentions"
msgstr ""
@@ -13174,6 +13336,11 @@ msgstr ""
msgid "Unable to Reach Back-end"
msgstr "Incapaz de alcanzar el Back-end"
#. js-lingui-id: EbnX+O
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Unconfigured models"
msgstr ""
#. js-lingui-id: EUHN7i
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableValueInput.tsx
msgid "Undefined"
@@ -13484,11 +13651,26 @@ msgstr "Usar como borrador"
msgid "Use authenticator apps and browser extensions like 1Password, Authy, Microsoft Authenticator to generate one-time passwords"
msgstr "Usa aplicaciones de autenticación y extensiones de navegador como 1Password, Authy, Microsoft Authenticator para generar contraseñas de un solo uso"
#. js-lingui-id: hCZsJ0
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Use best models only"
msgstr ""
#. js-lingui-id: c6uZUV
#: src/modules/object-record/record-table/empty-state/utils/getEmptyStateSubTitle.ts
msgid "Use our API or add your first {objectLabel} manually"
msgstr "Utiliza nuestra API o añade tu primer {objectLabel} manualmente"
#. js-lingui-id: 664z2C
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for chats, agents, and complex reasoning"
msgstr ""
#. js-lingui-id: C41qgx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for lightweight tasks like title generation"
msgstr ""
#. js-lingui-id: AQVj2A
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Useful for pivot/junction tables"
@@ -13737,8 +13919,6 @@ msgid "View Logs"
msgstr ""
#. js-lingui-id: ecVcAx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
msgid "View Previous AI Chats"
@@ -13994,6 +14174,21 @@ msgstr ""
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
msgstr ""
#. js-lingui-id: 8jc/Xn
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "When enabled, AI agents and workflow automations can discover and call this function"
msgstr ""
#. js-lingui-id: i2V4DO
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "When enabled, new AI models will be available to users by default"
msgstr ""
#. js-lingui-id: 01e9rV
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "When enabled, newly added models are available to all workspaces by default"
msgstr ""
#. js-lingui-id: C51ilI
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "When the API key will expire."
@@ -14126,6 +14321,7 @@ msgid "Workspace Domain"
msgstr "Dominio del espacio de trabajo"
#. js-lingui-id: J2q6WC
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/components/EventLogTableSelector.tsx
msgid "Workspace Events"
msgstr ""
+284 -88
View File
@@ -106,6 +106,7 @@ msgstr "(valittu: {selectedIconKey})"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "[empty string]"
@@ -310,6 +311,11 @@ msgstr "{morphRelationCount} objektia"
msgid "{num, selectordinal, one {{num}st} two {{num}nd} few {{num}rd} other {{num}th}}"
msgstr "{num, selectordinal, one {{num}.} other {{num}.}}"
#. js-lingui-id: fTSz8d
#: src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownActorSelect.tsx
msgid "{numberOfSelectedItems} workspace members"
msgstr ""
#. js-lingui-id: 7kYa/u
#: src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts
msgid "{objectLabelPlural} ({totalCount})"
@@ -330,6 +336,16 @@ msgstr ""
msgid "{positionLabel} record holds priority"
msgstr "Tietue {positionLabel} on etusijalla"
#. js-lingui-id: YG/wl5
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — API key not configured"
msgstr ""
#. js-lingui-id: s80lrU
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — Deprecated"
msgstr ""
#. js-lingui-id: Sxx5Hr
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "{recordCount} of {totalCount} records"
@@ -381,6 +397,11 @@ msgstr "{selectedCount} lähdetyyppiä"
msgid "{serviceLabel} service is unreachable"
msgstr "Palveluun {serviceLabel} ei saada yhteyttä"
#. js-lingui-id: 8vJ+2V
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "{stepCount, plural, one {# step} other {# steps}}"
msgstr ""
#. js-lingui-id: Bzjg0/
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
msgid "{stepNumber}. Calendar"
@@ -764,6 +785,11 @@ msgstr "Lisää \"{trimmedName}\" valintoihin"
msgid "Add a {objectLabelSingular}"
msgstr "Lisää {objectLabelSingular}"
#. js-lingui-id: 7W8nJr
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationGroupEditor.tsx
msgid "Add a Group"
msgstr ""
#. js-lingui-id: CZDwqQ
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
msgid "Add a new company we're in touch with (e.g. name, website, industry). Details: "
@@ -780,11 +806,6 @@ msgstr "Lisää solmu"
msgid "Add a record"
msgstr ""
#. js-lingui-id: r8W+9y
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
msgid "Add a Section"
msgstr ""
#. js-lingui-id: eMc2xs
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
msgid "Add a step"
@@ -1111,6 +1132,11 @@ msgstr "Säädä rooliin liittyviä asetuksia"
msgid "Admin"
msgstr ""
#. js-lingui-id: K2OX5h
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Admin Model Controls"
msgstr ""
#. js-lingui-id: g1in8j
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
@@ -1139,11 +1165,6 @@ msgstr "Edistynyt ominaisuus tiedusteluiden suorituskyvyn parantamiseksi ja ainu
msgid "Advanced filter"
msgstr "Tarkennettu suodatin"
#. js-lingui-id: luNzWN
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Advanced model for complex planning"
msgstr ""
#. js-lingui-id: miuPUc
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
@@ -1246,6 +1267,7 @@ msgstr ""
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
#: src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectForm.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "AI"
msgstr "AI"
@@ -1257,11 +1279,6 @@ msgstr "AI"
msgid "AI Model"
msgstr "AI-malli"
#. js-lingui-id: tGx4Zn
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "AI Models"
msgstr ""
#. js-lingui-id: Sfwld8
#: src/modules/ai/components/AIChatApiKeyNotConfiguredMessage.tsx
msgid "AI not configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or XAI_API_KEY in your environment."
@@ -1345,6 +1362,11 @@ msgstr ""
msgid "All Metadata"
msgstr ""
#. js-lingui-id: AJgjR+
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "All Models"
msgstr ""
#. js-lingui-id: aFE/OW
#: src/pages/settings/security/event-logs/components/EventLogFilters.tsx
#: src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableHeader.tsx
@@ -1506,6 +1528,9 @@ msgstr "Kuvaa ladattaessa tapahtui virhe."
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
@@ -1602,6 +1627,11 @@ msgstr "API-avain"
msgid "API Key copied to clipboard"
msgstr "API-avain kopioitu leikepöydälle"
#. js-lingui-id: jjaYji
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "API key not configured"
msgstr ""
#. js-lingui-id: Widx6n
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "API key roles"
@@ -1829,6 +1859,7 @@ msgstr "Nouseva"
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
@@ -1967,7 +1998,6 @@ msgstr "Liitteet"
#. js-lingui-id: EPEFrH
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "Audit Logs"
msgstr ""
@@ -2057,6 +2087,16 @@ msgstr "Luo automaattisesti yhteystiedot henkilöille."
msgid "Automatically create People records when receiving or sending emails"
msgstr "Luo automaattisesti henkilötietueita viestejä vastaanottaessa tai lähettäessä"
#. js-lingui-id: erwsgX
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Automatically enable new models"
msgstr ""
#. js-lingui-id: fx8TeY
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Automatically mark new models as available"
msgstr ""
#. js-lingui-id: lXkUEV
#: src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerManual.tsx
msgid "Availability"
@@ -2064,10 +2104,16 @@ msgstr "Saatavuus"
#. js-lingui-id: csDS2L
#: src/pages/settings/applications/SettingsApplications.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/data-model/new-object/components/SettingsAvailableStandardObjectsSection.tsx
msgid "Available"
msgstr "Saatavilla"
#. js-lingui-id: 06gA3L
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Available as tool"
msgstr ""
#. js-lingui-id: oD38t2
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Available tools"
@@ -2239,9 +2285,9 @@ msgstr "Ruskea"
msgid "Build a dashboard that shows: (1) total pipeline value by stage for the last 3 months, (2) count of deals won vs lost per month, (3) average deal size. Use our standard pipeline stages."
msgstr ""
#. js-lingui-id: 8SlslB
#. js-lingui-id: alSW5d
#: src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationJunctionForm.tsx
msgid "Build many-to-many relations. <0>Learn more</0>"
msgid "Build many-to-many relations"
msgstr ""
#. js-lingui-id: +7fBMP
@@ -2312,6 +2358,7 @@ msgstr "caldav.example.com"
#. js-lingui-id: AjVXBS
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
msgid "Calendar"
msgstr "Kalenteri"
@@ -2364,6 +2411,11 @@ msgstr "Kalenterinäkymä"
msgid "Calendars"
msgstr "Kalenterit"
#. js-lingui-id: qIlodj
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Calling Code"
msgstr ""
#. js-lingui-id: msssZq
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Can't change API names for standard objects"
@@ -2500,11 +2552,6 @@ msgstr "Vaihda solmun tyyppi"
msgid "Change Password"
msgstr "Vaihda salasana"
#. js-lingui-id: wRtBJP
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Change Plan"
msgstr "Muuta suunnitelmaa"
#. js-lingui-id: EYSFEW
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "Change subdomain?"
@@ -2602,7 +2649,7 @@ msgid "Choose the fields that will identify your records"
msgstr "Valitse kentät, jotka identifioivat tietueesi"
#. js-lingui-id: hIJigY
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Choose the format used to display date value"
msgstr "Valitse päivämäärän näyttämiseen käytetty muoto"
@@ -2705,6 +2752,11 @@ msgstr "Asiakkaan salaisuus"
msgid "Client Settings"
msgstr "Asiakasasetukset"
#. js-lingui-id: mekEJ5
#: src/hooks/useCopyToClipboard.tsx
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
msgstr ""
#. js-lingui-id: yz7wBu
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
msgid "Close"
@@ -2747,6 +2799,7 @@ msgstr "Koodaa funktiosi"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Collapse"
@@ -2847,10 +2900,14 @@ msgstr "Valmiit työt säilytetään {completedDuration}, epäonnistuneet työt
msgid "Conditions"
msgstr "Ehdot"
#. js-lingui-id: 14PdY0
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config"
msgstr ""
#. js-lingui-id: Vj43Y/
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config Variables"
msgstr "Määritysmuuttujat"
@@ -2865,11 +2922,6 @@ msgstr "Kokoonpano"
msgid "Configure"
msgstr ""
#. js-lingui-id: 9px+al
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Configure AI models for routing and planning"
msgstr ""
#. js-lingui-id: +zUMwJ
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure an SSO connection"
@@ -2895,6 +2947,11 @@ msgstr "Määritä CalDAV-asetukset synkronoidaksesi kalenteritapahtumasi."
msgid "Configure date, time, number, timezone, and calendar start day"
msgstr "Aseta päivämäärä, aika, numero, aikavyöhyke ja kalenterin aloituspäivä"
#. js-lingui-id: +SQwHr
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Configure default AI models and availability"
msgstr ""
#. js-lingui-id: utsXG8
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure fallback login methods for users with SSO bypass permissions"
@@ -3225,11 +3282,6 @@ msgstr "Ydin"
msgid "Core Objects"
msgstr ""
#. js-lingui-id: cfa2VJ
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Core Schema"
msgstr "Ydinskeema"
#. js-lingui-id: I99Miw
#: src/modules/billing/components/SettingsBillingCreditsSection.tsx
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
@@ -3301,11 +3353,6 @@ msgstr "Laske yksilölliset arvot"
msgid "Country"
msgstr "Maa"
#. js-lingui-id: j2OqfX
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Country Code"
msgstr "Maakoodi"
#. js-lingui-id: gJdfqX
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "create"
@@ -4253,6 +4300,16 @@ msgstr "Poistetut tietueet"
msgid "Deleting this method will remove it permanently from your account."
msgstr "Tämän menetelmän poistaminen poistaa sen pysyvästi tililtäsi."
#. js-lingui-id: Ssdrw4
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated"
msgstr ""
#. js-lingui-id: 8OJZ/p
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated models"
msgstr ""
#. js-lingui-id: O3LJh6
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
@@ -4826,6 +4883,7 @@ msgstr "Sähköpostitoimialueet"
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Emails"
msgstr "Sähköpostit"
@@ -4877,6 +4935,7 @@ msgstr "Tyhjä"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Array"
@@ -4897,6 +4956,7 @@ msgstr "Tyhjä Saapuneet"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Object"
@@ -5024,10 +5084,10 @@ msgstr ""
msgid "Enter filter"
msgstr "Syötä suodatin"
#. js-lingui-id: 9/30HU
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
msgid "Enter in <0>Unicode</0> format"
msgstr "Kirjoita <0>Unicode</0>-muodossa"
#. js-lingui-id: f09Lhk
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Enter in Unicode format"
msgstr ""
#. js-lingui-id: 9CjMQ7
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx
@@ -5092,6 +5152,11 @@ msgstr "Syötä testiarvo"
msgid "Enter text"
msgstr "Syötä teksti"
#. js-lingui-id: +rrO69
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
msgid "Enter text or type '/' for commands"
msgstr ""
#. js-lingui-id: yZMXC2
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
msgid "Enter text or Type '/' for commands"
@@ -5488,6 +5553,7 @@ msgstr "Poistu asetuksista"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Expand"
@@ -5787,9 +5853,9 @@ msgstr ""
msgid "Failed to save workspace instructions"
msgstr ""
#. js-lingui-id: YMSYb+
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update fast model"
#. js-lingui-id: YzURPo
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update auto-enable setting"
msgstr ""
#. js-lingui-id: P1NmNz
@@ -5797,6 +5863,27 @@ msgstr ""
msgid "Failed to update feature flag. {errorMessage}"
msgstr "Ominaisuuslipun päivitys epäonnistui. {errorMessage}"
#. js-lingui-id: 1R13Ov
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model"
msgstr ""
#. js-lingui-id: W7Ff/4
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update model availability"
msgstr ""
#. js-lingui-id: LgZlJ7
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model availability settings"
msgstr ""
#. js-lingui-id: rCUG3c
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model selection mode"
msgstr ""
#. js-lingui-id: HnBqPY
#: src/modules/billing/components/internal/MeteredPriceSelector.tsx
msgid "Failed to update price."
@@ -5812,11 +5899,6 @@ msgstr ""
msgid "Failed to update role"
msgstr "Roolin päivitys epäonnistui"
#. js-lingui-id: h/0aT5
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update smart model"
msgstr ""
#. js-lingui-id: Dzh4a2
#: src/modules/settings/admin-panel/config-variables/hooks/useConfigVariableActions.ts
msgid "Failed to update variable"
@@ -5865,15 +5947,10 @@ msgid "False"
msgstr "Väärä"
#. js-lingui-id: XVIZ7v
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Fast Model"
msgstr ""
#. js-lingui-id: UJHTjm
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Fast model updated successfully"
msgstr ""
#. js-lingui-id: X9kySA
#: src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx
#: src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx
@@ -6018,6 +6095,11 @@ msgstr ""
msgid "File URL is not defined"
msgstr ""
#. js-lingui-id: sER+bs
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Files"
msgstr ""
#. js-lingui-id: o7J4JM
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
@@ -6027,6 +6109,7 @@ msgstr ""
#: src/modules/views/components/ViewBarFilterButton.tsx
#: src/modules/settings/roles/components/SettingsRolesList.tsx
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
#: src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx
@@ -6121,6 +6204,7 @@ msgstr "Etunimi ei saa olla tyhjä"
#. js-lingui-id: ylQd2j
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "Flow"
msgstr "Virtaus"
@@ -6255,7 +6339,9 @@ msgstr "Mittarikaavio"
#: src/pages/settings/SettingsWorkspace.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetEditorGroupsData.ts
#: src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenuOpenContent.tsx
msgid "General"
msgstr "Yleiset"
@@ -6497,11 +6583,15 @@ msgstr ""
msgid "Heading 3"
msgstr ""
#. js-lingui-id: UPqS9C
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health"
msgstr ""
#. js-lingui-id: I1IOmb
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
#: src/modules/settings/admin-panel/health-status/components/SettingsAdminHealthStatus.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health Status"
msgstr "Terveydentila"
@@ -6586,6 +6676,11 @@ msgstr "Piilota ryhmä {groupValue}"
msgid "Hide hidden groups"
msgstr "Piilota piilotetut ryhmät"
#. js-lingui-id: i0qMbr
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Home"
msgstr ""
#. js-lingui-id: Xkd22/
#: src/modules/page-layout/utils/getWidgetTitle.ts
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
@@ -6897,6 +6992,7 @@ msgstr "Tiedot"
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Input"
msgstr "Syöttö"
@@ -6973,11 +7069,6 @@ msgstr "Ohjeet tekoälylle"
msgid "Integrations - Settings"
msgstr "Integraatiot - Asetukset"
#. js-lingui-id: ntgzzG
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Interact with your workspace data"
msgstr "Vuorovaikuta työtilasi tietojen kanssa"
#. js-lingui-id: jyjroS
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Interval switching has been cancelled."
@@ -7954,6 +8045,11 @@ msgstr "Maksimirajoitus"
msgid "Maximum email addresses"
msgstr "Sähköpostiosoitteiden enimmäismäärä"
#. js-lingui-id: 9UHNQc
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Maximum execution time in seconds (1-900)"
msgstr ""
#. js-lingui-id: PAhTVY
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
msgid "Maximum files"
@@ -8086,11 +8182,6 @@ msgstr "Metatiedot"
msgid "Metadata file generation failed"
msgstr "Metatiedostotiedoston luonti epäonnistui"
#. js-lingui-id: 0BF9eC
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Metadata Schema"
msgstr "Metatietoskeema"
#. js-lingui-id: onCJJ6
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Metered tier switching has been cancelled."
@@ -8149,6 +8240,17 @@ msgstr ""
msgid "Mission accomplished!"
msgstr "Tehtävä suoritettu!"
#. js-lingui-id: //nm2/
#: src/pages/settings/ai/SettingsAI.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models"
msgstr ""
#. js-lingui-id: oHM560
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models available in the chat model picker"
msgstr ""
#. js-lingui-id: hty0d5
#: src/pages/settings/profile/appearance/components/DateTimeSettingsCalendarStartDaySelect.tsx
msgid "Monday"
@@ -8194,6 +8296,7 @@ msgid "months"
msgstr ""
#. js-lingui-id: 2FYpfJ
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/ui/layout/tab-list/components/TabMoreButton.tsx
msgid "More"
msgstr "Lisää"
@@ -8483,6 +8586,11 @@ msgstr "Uusi kenttä"
msgid "New folder"
msgstr ""
#. js-lingui-id: 93KA8w
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationEditor.tsx
msgid "New Group"
msgstr ""
#. js-lingui-id: o8MyXb
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "New key"
@@ -8656,6 +8764,11 @@ msgstr "Ei valittavissa olevia kenttiä"
msgid "No body"
msgstr "Ei viestirunkoa"
#. js-lingui-id: c3+z7H
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
msgid "No calling code"
msgstr ""
#. js-lingui-id: OTe3RI
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "No change detected"
@@ -8686,7 +8799,6 @@ msgstr "Tälle pyynnölle ei annettu kontekstia"
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
msgid "No country"
msgstr "Ei maata"
@@ -8887,7 +8999,6 @@ msgstr "Ei metriikkatietoja saatavilla"
#. js-lingui-id: UWZZdQ
#: src/pages/settings/ai/forms/components/SettingsAIAgentForm.tsx
#: src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "No models available. Please configure AI models in your workspace settings."
msgstr "Malitavoa ei ole saatavilla. Konfiguroi AI-mallit työtilan asetuksista."
@@ -9124,7 +9235,13 @@ msgstr "Ei jaettu käyttäjän {notSharedByFullName} toimesta"
msgid "Not synced"
msgstr "Ei synkronoitu"
#. js-lingui-id: KiJn9B
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Note"
msgstr ""
#. js-lingui-id: 1DBGsz
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Notes"
msgstr "Muistiinpanot"
@@ -9502,6 +9619,11 @@ msgstr ""
msgid "Organization"
msgstr "Organisaatio"
#. js-lingui-id: zi/p7n
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Organization plan"
msgstr ""
#. js-lingui-id: nV6twc
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
msgid "Organize"
@@ -9514,7 +9636,7 @@ msgstr ""
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/pages/settings/admin-panel/SettingsAdmin.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemMainMenu.tsx
msgid "Other"
msgstr "Muu"
@@ -9560,6 +9682,7 @@ msgstr "Katkos"
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/TerminalOutput.tsx
#: src/modules/ai/components/CodeExecutionDisplay.tsx
msgid "Output"
@@ -10061,6 +10184,11 @@ msgstr "Tietosuojakäytäntö"
msgid "Pro"
msgstr "Pro"
#. js-lingui-id: r5je1s
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Pro plan"
msgstr ""
#. js-lingui-id: k1ifdL
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
@@ -10196,11 +10324,6 @@ msgstr "Jonon suorituskyky"
msgid "Queue: {queueName}"
msgstr "Jono: {queueName}"
#. js-lingui-id: GaAG2G
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Quick model for routing decisions"
msgstr ""
#. js-lingui-id: opSifa
#: src/modules/ai/utils/getToolDisplayMessage.ts
msgid "Ran {formattedName}"
@@ -10677,6 +10800,11 @@ msgstr "Palauta tietueet"
msgid "Restore Records"
msgstr "Palauta tietueet"
#. js-lingui-id: hO3AfV
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Restrict available models to a curated list"
msgstr ""
#. js-lingui-id: RD6AE9
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
msgid "Result"
@@ -10958,6 +11086,12 @@ msgstr "Etsi kenttää..."
msgid "Search a folder..."
msgstr ""
#. js-lingui-id: 8J0e5B
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Search a model..."
msgstr ""
#. js-lingui-id: WXvlVa
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "Search a role..."
@@ -11511,6 +11645,11 @@ msgstr "Lähetetty ja vastaanotettu"
msgid "Serbian (Cyrillic)"
msgstr "Serbia (kyrillinen)"
#. js-lingui-id: 8ZSrlB
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Server-wide AI model availability settings"
msgstr ""
#. js-lingui-id: LUc0oL
#: src/modules/settings/security/components/SSO/SettingsSSOSAMLForm.tsx
msgid "Service Provider Details"
@@ -11593,7 +11732,6 @@ msgstr "Asetetaan tietokantaasi..."
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
#: src/pages/settings/ai/SettingsAgentForm.tsx
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/sign-in-background-mock/components/SignInAppNavigationDrawerMock.tsx
#: src/modules/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsSection.tsx
#: src/modules/settings/roles/role/components/SettingsRole.tsx
@@ -11812,15 +11950,10 @@ msgid "Small section heading"
msgstr ""
#. js-lingui-id: 5J8ZFl
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Smart Model"
msgstr ""
#. js-lingui-id: qgvZ/2
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Smart model updated successfully"
msgstr ""
#. js-lingui-id: w+rJId
#: src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx
msgid "SMTP Configuration"
@@ -11920,6 +12053,14 @@ msgstr "Välilyöntejä ja pilkku - {spacesAndCommaExample}"
msgid "Spanish"
msgstr "Espanja"
#. js-lingui-id: gsifzp
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Split multiple values"
msgstr ""
#. js-lingui-id: vnS6Rf
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "SSO"
@@ -12398,6 +12539,7 @@ msgid "Task Title"
msgstr "Tehtävän otsikko"
#. js-lingui-id: GtycJ/
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Tasks"
msgstr "Tehtävät"
@@ -12597,6 +12739,11 @@ msgstr "Tähän tietueeseen ei liity aktiivisuutta."
msgid "There was an error while updating password."
msgstr "Salasanan päivityksessä tapahtui virhe."
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
msgstr ""
#. js-lingui-id: Ed99mE
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
msgid "Thinking..."
@@ -12784,6 +12931,11 @@ msgstr "Tämä poistaa pysyvästi kaksivaiheisen todennustapasi.<0/>Koska 2FA on
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
msgstr "Tämä palauttaa tietokannan arvon ympäristö/oletusarvoksi. Tietokannan ohitus poistetaan ja järjestelmä käyttää ympäristöasetuksia."
#. js-lingui-id: f8HOUp
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thought"
msgstr ""
#. js-lingui-id: 5g/sE8
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
msgid "Tidy up"
@@ -12815,10 +12967,16 @@ msgid "Time zone"
msgstr "Aikavyöhyke"
#. js-lingui-id: cklVjM
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
msgid "Timeline"
msgstr "Aikajana"
#. js-lingui-id: xY9s5E
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Timeout"
msgstr ""
#. js-lingui-id: 8TMaZI
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
@@ -12874,6 +13032,11 @@ msgstr "Vaihda kaikkien objektien oikeudet"
msgid "Toggle all settings permissions"
msgstr "Vaihda kaikkien asetusten oikeudet"
#. js-lingui-id: 93pMSK
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Toggle model availability across all workspaces"
msgstr ""
#. js-lingui-id: WOr+hW
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
msgid "tokens"
@@ -13131,7 +13294,6 @@ msgid "Type"
msgstr "Tyyppi"
#. js-lingui-id: SKD2e4
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
#: src/modules/activities/components/ActivityRichTextEditor.tsx
msgid "Type '/' for commands, '@' for mentions"
msgstr ""
@@ -13172,6 +13334,11 @@ msgstr ""
msgid "Unable to Reach Back-end"
msgstr "Takaosaan ei saa yhteyttä"
#. js-lingui-id: EbnX+O
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Unconfigured models"
msgstr ""
#. js-lingui-id: EUHN7i
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableValueInput.tsx
msgid "Undefined"
@@ -13482,11 +13649,26 @@ msgstr "Käytä luonnoksena"
msgid "Use authenticator apps and browser extensions like 1Password, Authy, Microsoft Authenticator to generate one-time passwords"
msgstr "Käytä todennussovelluksia ja selainlaajennuksia, kuten 1Password, Authy, Microsoft Authenticator luomaan kertakäyttösalasanoja"
#. js-lingui-id: hCZsJ0
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Use best models only"
msgstr ""
#. js-lingui-id: c6uZUV
#: src/modules/object-record/record-table/empty-state/utils/getEmptyStateSubTitle.ts
msgid "Use our API or add your first {objectLabel} manually"
msgstr "Käytä APIamme tai lisää ensimmäinen {objectLabel} käsin"
#. js-lingui-id: 664z2C
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for chats, agents, and complex reasoning"
msgstr ""
#. js-lingui-id: C41qgx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for lightweight tasks like title generation"
msgstr ""
#. js-lingui-id: AQVj2A
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Useful for pivot/junction tables"
@@ -13735,8 +13917,6 @@ msgid "View Logs"
msgstr ""
#. js-lingui-id: ecVcAx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
msgid "View Previous AI Chats"
@@ -13992,6 +14172,21 @@ msgstr ""
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
msgstr ""
#. js-lingui-id: 8jc/Xn
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "When enabled, AI agents and workflow automations can discover and call this function"
msgstr ""
#. js-lingui-id: i2V4DO
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "When enabled, new AI models will be available to users by default"
msgstr ""
#. js-lingui-id: 01e9rV
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "When enabled, newly added models are available to all workspaces by default"
msgstr ""
#. js-lingui-id: C51ilI
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "When the API key will expire."
@@ -14124,6 +14319,7 @@ msgid "Workspace Domain"
msgstr "Työtilan verkkotunnus"
#. js-lingui-id: J2q6WC
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/components/EventLogTableSelector.tsx
msgid "Workspace Events"
msgstr ""
+284 -88
View File
@@ -106,6 +106,7 @@ msgstr "(sélectionné : {selectedIconKey})"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "[empty string]"
@@ -310,6 +311,11 @@ msgstr "{morphRelationCount} objets"
msgid "{num, selectordinal, one {{num}st} two {{num}nd} few {{num}rd} other {{num}th}}"
msgstr "{num, selectordinal, one {{num}er} other {{num}e}}"
#. js-lingui-id: fTSz8d
#: src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownActorSelect.tsx
msgid "{numberOfSelectedItems} workspace members"
msgstr ""
#. js-lingui-id: 7kYa/u
#: src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts
msgid "{objectLabelPlural} ({totalCount})"
@@ -330,6 +336,16 @@ msgstr ""
msgid "{positionLabel} record holds priority"
msgstr "L'enregistrement {positionLabel} a la priorité"
#. js-lingui-id: YG/wl5
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — API key not configured"
msgstr ""
#. js-lingui-id: s80lrU
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "{providerLabel} — Deprecated"
msgstr ""
#. js-lingui-id: Sxx5Hr
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "{recordCount} of {totalCount} records"
@@ -381,6 +397,11 @@ msgstr "{selectedCount} types de source"
msgid "{serviceLabel} service is unreachable"
msgstr "Le service {serviceLabel} est inaccessible"
#. js-lingui-id: 8vJ+2V
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "{stepCount, plural, one {# step} other {# steps}}"
msgstr ""
#. js-lingui-id: Bzjg0/
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
msgid "{stepNumber}. Calendar"
@@ -764,6 +785,11 @@ msgstr "Ajouter \"{trimmedName}\" aux options"
msgid "Add a {objectLabelSingular}"
msgstr "Ajouter un {objectLabelSingular}"
#. js-lingui-id: 7W8nJr
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationGroupEditor.tsx
msgid "Add a Group"
msgstr ""
#. js-lingui-id: CZDwqQ
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
msgid "Add a new company we're in touch with (e.g. name, website, industry). Details: "
@@ -780,11 +806,6 @@ msgstr "Ajouter un nœud"
msgid "Add a record"
msgstr ""
#. js-lingui-id: r8W+9y
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
msgid "Add a Section"
msgstr ""
#. js-lingui-id: eMc2xs
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
msgid "Add a step"
@@ -1111,6 +1132,11 @@ msgstr "Ajuster les paramètres liés au rôle"
msgid "Admin"
msgstr ""
#. js-lingui-id: K2OX5h
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Admin Model Controls"
msgstr ""
#. js-lingui-id: g1in8j
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
@@ -1139,11 +1165,6 @@ msgstr "Fonctionnalité avancée pour améliorer la performance des requêtes et
msgid "Advanced filter"
msgstr "Filtre avancé"
#. js-lingui-id: luNzWN
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Advanced model for complex planning"
msgstr ""
#. js-lingui-id: miuPUc
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
#: src/modules/command-menu/pages/page-layout/components/dropdown-content/ChartDataSourceDropdownContent.tsx
@@ -1246,6 +1267,7 @@ msgstr ""
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
#: src/modules/settings/roles/role-permissions/object-level-permissions/object-form/components/SettingsRolePermissionsObjectLevelObjectForm.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "AI"
msgstr "IA"
@@ -1257,11 +1279,6 @@ msgstr "IA"
msgid "AI Model"
msgstr "Modèle IA"
#. js-lingui-id: tGx4Zn
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "AI Models"
msgstr ""
#. js-lingui-id: Sfwld8
#: src/modules/ai/components/AIChatApiKeyNotConfiguredMessage.tsx
msgid "AI not configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or XAI_API_KEY in your environment."
@@ -1345,6 +1362,11 @@ msgstr ""
msgid "All Metadata"
msgstr ""
#. js-lingui-id: AJgjR+
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "All Models"
msgstr ""
#. js-lingui-id: aFE/OW
#: src/pages/settings/security/event-logs/components/EventLogFilters.tsx
#: src/modules/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsTableHeader.tsx
@@ -1506,6 +1528,9 @@ msgstr "Une erreur s'est produite lors du téléversement de l'image."
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFilterAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldGroupAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
#: src/modules/views/hooks/internal/usePerformViewFieldAPIPersist.ts
@@ -1602,6 +1627,11 @@ msgstr "Clé API"
msgid "API Key copied to clipboard"
msgstr "Clé API copiée dans le presse-papiers"
#. js-lingui-id: jjaYji
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "API key not configured"
msgstr ""
#. js-lingui-id: Widx6n
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "API key roles"
@@ -1829,6 +1859,7 @@ msgstr "Ascendant"
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
@@ -1967,7 +1998,6 @@ msgstr "Pièces jointes"
#. js-lingui-id: EPEFrH
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/SettingsEventLogs.tsx
msgid "Audit Logs"
msgstr ""
@@ -2057,6 +2087,16 @@ msgstr "Créer automatiquement des contacts pour les personnes."
msgid "Automatically create People records when receiving or sending emails"
msgstr "Créer automatiquement des enregistrements de personnes lors de la réception ou de l'envoi d'emails"
#. js-lingui-id: erwsgX
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Automatically enable new models"
msgstr ""
#. js-lingui-id: fx8TeY
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Automatically mark new models as available"
msgstr ""
#. js-lingui-id: lXkUEV
#: src/modules/workflow/workflow-trigger/components/WorkflowEditTriggerManual.tsx
msgid "Availability"
@@ -2064,10 +2104,16 @@ msgstr "Disponibilité"
#. js-lingui-id: csDS2L
#: src/pages/settings/applications/SettingsApplications.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/data-model/new-object/components/SettingsAvailableStandardObjectsSection.tsx
msgid "Available"
msgstr "Disponible"
#. js-lingui-id: 06gA3L
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Available as tool"
msgstr ""
#. js-lingui-id: oD38t2
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Available tools"
@@ -2239,9 +2285,9 @@ msgstr "Marron"
msgid "Build a dashboard that shows: (1) total pipeline value by stage for the last 3 months, (2) count of deals won vs lost per month, (3) average deal size. Use our standard pipeline stages."
msgstr ""
#. js-lingui-id: 8SlslB
#. js-lingui-id: alSW5d
#: src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationJunctionForm.tsx
msgid "Build many-to-many relations. <0>Learn more</0>"
msgid "Build many-to-many relations"
msgstr ""
#. js-lingui-id: +7fBMP
@@ -2312,6 +2358,7 @@ msgstr "caldav.example.com"
#. js-lingui-id: AjVXBS
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
msgid "Calendar"
msgstr "Calendrier"
@@ -2364,6 +2411,11 @@ msgstr "Vue Calendrier"
msgid "Calendars"
msgstr "Calendriers"
#. js-lingui-id: qIlodj
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Calling Code"
msgstr ""
#. js-lingui-id: msssZq
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Can't change API names for standard objects"
@@ -2500,11 +2552,6 @@ msgstr "Changer le type de nœud"
msgid "Change Password"
msgstr "Changer le mot de passe"
#. js-lingui-id: wRtBJP
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Change Plan"
msgstr "Changer de plan"
#. js-lingui-id: EYSFEW
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "Change subdomain?"
@@ -2602,7 +2649,7 @@ msgid "Choose the fields that will identify your records"
msgstr "Choisissez les champs qui identifieront vos enregistrements"
#. js-lingui-id: hIJigY
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Choose the format used to display date value"
msgstr "Choisir le format utilisé pour afficher la valeur de la date"
@@ -2705,6 +2752,11 @@ msgstr "Secret client"
msgid "Client Settings"
msgstr "Paramètres du client"
#. js-lingui-id: mekEJ5
#: src/hooks/useCopyToClipboard.tsx
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
msgstr ""
#. js-lingui-id: yz7wBu
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
msgid "Close"
@@ -2747,6 +2799,7 @@ msgstr "Coder votre fonction"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Collapse"
@@ -2847,10 +2900,14 @@ msgstr "Tâches terminées conservées pour {completedDuration}, tâches échou
msgid "Conditions"
msgstr "Conditions"
#. js-lingui-id: 14PdY0
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config"
msgstr ""
#. js-lingui-id: Vj43Y/
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Config Variables"
msgstr "Variables de configuration"
@@ -2865,11 +2922,6 @@ msgstr "Configuration"
msgid "Configure"
msgstr ""
#. js-lingui-id: 9px+al
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Configure AI models for routing and planning"
msgstr ""
#. js-lingui-id: +zUMwJ
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure an SSO connection"
@@ -2895,6 +2947,11 @@ msgstr "Configurez les paramètres de CalDAV pour synchroniser vos événements
msgid "Configure date, time, number, timezone, and calendar start day"
msgstr "Configurer la date, l'heure, le nombre, le fuseau horaire et le jour de début du calendrier"
#. js-lingui-id: +SQwHr
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Configure default AI models and availability"
msgstr ""
#. js-lingui-id: utsXG8
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "Configure fallback login methods for users with SSO bypass permissions"
@@ -3225,11 +3282,6 @@ msgstr "Noyau"
msgid "Core Objects"
msgstr ""
#. js-lingui-id: cfa2VJ
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Core Schema"
msgstr "Schéma principal"
#. js-lingui-id: I99Miw
#: src/modules/billing/components/SettingsBillingCreditsSection.tsx
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
@@ -3301,11 +3353,6 @@ msgstr "Compter les valeurs uniques"
msgid "Country"
msgstr "Pays"
#. js-lingui-id: j2OqfX
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
msgid "Country Code"
msgstr "Code du pays"
#. js-lingui-id: gJdfqX
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
msgid "create"
@@ -4253,6 +4300,16 @@ msgstr "Enregistrements supprimés"
msgid "Deleting this method will remove it permanently from your account."
msgstr "La suppression de cette méthode l'éliminera définitivement de votre compte."
#. js-lingui-id: Ssdrw4
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated"
msgstr ""
#. js-lingui-id: 8OJZ/p
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Deprecated models"
msgstr ""
#. js-lingui-id: O3LJh6
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
#: src/modules/command-menu/pages/page-layout/utils/getSortLabelSuffixForFieldType.ts
@@ -4826,6 +4883,7 @@ msgstr "Domaines d'envoi d'e-mail"
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Emails"
msgstr "Courriels"
@@ -4877,6 +4935,7 @@ msgstr "Vide"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Array"
@@ -4897,6 +4956,7 @@ msgstr "Boîte de réception vide"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Empty Object"
@@ -5024,10 +5084,10 @@ msgstr ""
msgid "Enter filter"
msgstr "Saisissez un filtre"
#. js-lingui-id: 9/30HU
#: src/modules/settings/data-model/fields/forms/date/utils/getDisplayFormatSelectDescription.tsx
msgid "Enter in <0>Unicode</0> format"
msgstr "Entrer au format <0>Unicode</0>"
#. js-lingui-id: f09Lhk
#: src/modules/settings/data-model/fields/forms/date/components/SettingsDataModelFieldDateForm.tsx
msgid "Enter in Unicode format"
msgstr ""
#. js-lingui-id: 9CjMQ7
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableDatabaseInput.tsx
@@ -5092,6 +5152,11 @@ msgstr "Saisissez une valeur de test"
msgid "Enter text"
msgstr "Saisissez du texte"
#. js-lingui-id: +rrO69
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
msgid "Enter text or type '/' for commands"
msgstr ""
#. js-lingui-id: yZMXC2
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
msgid "Enter text or Type '/' for commands"
@@ -5488,6 +5553,7 @@ msgstr "Quitter les paramètres"
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Expand"
@@ -5787,9 +5853,9 @@ msgstr ""
msgid "Failed to save workspace instructions"
msgstr ""
#. js-lingui-id: YMSYb+
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update fast model"
#. js-lingui-id: YzURPo
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update auto-enable setting"
msgstr ""
#. js-lingui-id: P1NmNz
@@ -5797,6 +5863,27 @@ msgstr ""
msgid "Failed to update feature flag. {errorMessage}"
msgstr "Échec de la mise à jour du feature flag. {errorMessage}"
#. js-lingui-id: 1R13Ov
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model"
msgstr ""
#. js-lingui-id: W7Ff/4
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Failed to update model availability"
msgstr ""
#. js-lingui-id: LgZlJ7
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model availability settings"
msgstr ""
#. js-lingui-id: rCUG3c
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Failed to update model selection mode"
msgstr ""
#. js-lingui-id: HnBqPY
#: src/modules/billing/components/internal/MeteredPriceSelector.tsx
msgid "Failed to update price."
@@ -5812,11 +5899,6 @@ msgstr ""
msgid "Failed to update role"
msgstr "Échec de la mise à jour du rôle"
#. js-lingui-id: h/0aT5
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Failed to update smart model"
msgstr ""
#. js-lingui-id: Dzh4a2
#: src/modules/settings/admin-panel/config-variables/hooks/useConfigVariableActions.ts
msgid "Failed to update variable"
@@ -5865,15 +5947,10 @@ msgid "False"
msgstr "Faux"
#. js-lingui-id: XVIZ7v
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Fast Model"
msgstr ""
#. js-lingui-id: UJHTjm
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Fast model updated successfully"
msgstr ""
#. js-lingui-id: X9kySA
#: src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx
#: src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx
@@ -6018,6 +6095,11 @@ msgstr ""
msgid "File URL is not defined"
msgstr ""
#. js-lingui-id: sER+bs
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Files"
msgstr ""
#. js-lingui-id: o7J4JM
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
@@ -6027,6 +6109,7 @@ msgstr ""
#: src/modules/views/components/ViewBarFilterButton.tsx
#: src/modules/settings/roles/components/SettingsRolesList.tsx
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
#: src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/components/ChartFiltersSettings.tsx
@@ -6121,6 +6204,7 @@ msgstr "Le prénom ne peut pas être vide"
#. js-lingui-id: ylQd2j
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
msgid "Flow"
msgstr "Flux"
@@ -6255,7 +6339,9 @@ msgstr ""
#: src/pages/settings/SettingsWorkspace.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetEditorGroupsData.ts
#: src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenuOpenContent.tsx
msgid "General"
msgstr "Général"
@@ -6497,11 +6583,15 @@ msgstr ""
msgid "Heading 3"
msgstr ""
#. js-lingui-id: UPqS9C
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health"
msgstr ""
#. js-lingui-id: I1IOmb
#: src/pages/settings/admin-panel/SettingsAdminQueueDetail.tsx
#: src/pages/settings/admin-panel/SettingsAdminIndicatorHealthStatus.tsx
#: src/modules/settings/admin-panel/health-status/components/SettingsAdminHealthStatus.tsx
#: src/modules/settings/admin-panel/components/SettingsAdminContent.tsx
msgid "Health Status"
msgstr "Statut de santé"
@@ -6586,6 +6676,11 @@ msgstr "Masquer le groupe {groupValue}"
msgid "Hide hidden groups"
msgstr "Masquer les groupes cachés"
#. js-lingui-id: i0qMbr
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Home"
msgstr ""
#. js-lingui-id: Xkd22/
#: src/modules/page-layout/utils/getWidgetTitle.ts
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
@@ -6897,6 +6992,7 @@ msgstr "Informations"
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Input"
msgstr "Entrée "
@@ -6973,11 +7069,6 @@ msgstr "Instructions pour l'IA"
msgid "Integrations - Settings"
msgstr "Intégrations - Paramètres"
#. js-lingui-id: ntgzzG
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Interact with your workspace data"
msgstr "Interagissez avec les données de votre espace de travail"
#. js-lingui-id: jyjroS
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Interval switching has been cancelled."
@@ -7954,6 +8045,11 @@ msgstr "Portée max"
msgid "Maximum email addresses"
msgstr "Adresses e-mail maximales"
#. js-lingui-id: 9UHNQc
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Maximum execution time in seconds (1-900)"
msgstr ""
#. js-lingui-id: PAhTVY
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
msgid "Maximum files"
@@ -8086,11 +8182,6 @@ msgstr "Métadonnées"
msgid "Metadata file generation failed"
msgstr "Échec de la génération du fichier des métadonnées"
#. js-lingui-id: 0BF9eC
#: src/pages/settings/ai/components/SettingsAIMCP.tsx
msgid "Metadata Schema"
msgstr "Schéma des métadonnées"
#. js-lingui-id: onCJJ6
#: src/modules/billing/components/SettingsBillingSubscriptionInfo.tsx
msgid "Metered tier switching has been cancelled."
@@ -8149,6 +8240,17 @@ msgstr ""
msgid "Mission accomplished!"
msgstr "Mission accomplie !"
#. js-lingui-id: //nm2/
#: src/pages/settings/ai/SettingsAI.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models"
msgstr ""
#. js-lingui-id: oHM560
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Models available in the chat model picker"
msgstr ""
#. js-lingui-id: hty0d5
#: src/pages/settings/profile/appearance/components/DateTimeSettingsCalendarStartDaySelect.tsx
msgid "Monday"
@@ -8194,6 +8296,7 @@ msgid "months"
msgstr ""
#. js-lingui-id: 2FYpfJ
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/ui/layout/tab-list/components/TabMoreButton.tsx
msgid "More"
msgstr "Plus"
@@ -8483,6 +8586,11 @@ msgstr "Nouveau champ"
msgid "New folder"
msgstr ""
#. js-lingui-id: 93KA8w
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationEditor.tsx
msgid "New Group"
msgstr ""
#. js-lingui-id: o8MyXb
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "New key"
@@ -8656,6 +8764,11 @@ msgstr "Aucun champ disponible à sélectionner"
msgid "No body"
msgstr "Aucun corps"
#. js-lingui-id: c3+z7H
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
msgid "No calling code"
msgstr ""
#. js-lingui-id: OTe3RI
#: src/pages/settings/domains/SettingsDomain.tsx
msgid "No change detected"
@@ -8686,7 +8799,6 @@ msgstr "Aucun contexte n'a été fourni pour cette requête"
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
msgid "No country"
msgstr "Aucun pays"
@@ -8887,7 +8999,6 @@ msgstr "Aucune donnée de métriques disponible"
#. js-lingui-id: UWZZdQ
#: src/pages/settings/ai/forms/components/SettingsAIAgentForm.tsx
#: src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "No models available. Please configure AI models in your workspace settings."
msgstr "Aucun modèle disponible. Veuillez configurer les modèles IA dans les paramètres de votre espace de travail."
@@ -9124,7 +9235,13 @@ msgstr "Non partagé par {notSharedByFullName}"
msgid "Not synced"
msgstr "Non synchronisé"
#. js-lingui-id: KiJn9B
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
msgid "Note"
msgstr ""
#. js-lingui-id: 1DBGsz
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Notes"
msgstr "Notes"
@@ -9502,6 +9619,11 @@ msgstr ""
msgid "Organization"
msgstr "Organisation"
#. js-lingui-id: zi/p7n
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Organization plan"
msgstr ""
#. js-lingui-id: nV6twc
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
msgid "Organize"
@@ -9514,7 +9636,7 @@ msgstr ""
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
#: src/pages/settings/admin-panel/SettingsAdmin.tsx
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
#: src/modules/page-layout/hooks/useTemporaryFieldsConfiguration.ts
#: src/modules/page-layout/widgets/fields/hooks/useFieldsWidgetGroups.ts
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemMainMenu.tsx
msgid "Other"
msgstr "Autres"
@@ -9560,6 +9682,7 @@ msgstr "Panne"
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
#: src/modules/ai/components/ToolStepRenderer.tsx
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
#: src/modules/ai/components/TerminalOutput.tsx
#: src/modules/ai/components/CodeExecutionDisplay.tsx
msgid "Output"
@@ -10061,6 +10184,11 @@ msgstr "Politique de confidentialité"
msgid "Pro"
msgstr "Pro"
#. js-lingui-id: r5je1s
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
msgid "Pro plan"
msgstr ""
#. js-lingui-id: k1ifdL
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
@@ -10196,11 +10324,6 @@ msgstr "Performance de la file d'attente"
msgid "Queue: {queueName}"
msgstr "File d'attente : {queueName}"
#. js-lingui-id: GaAG2G
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Quick model for routing decisions"
msgstr ""
#. js-lingui-id: opSifa
#: src/modules/ai/utils/getToolDisplayMessage.ts
msgid "Ran {formattedName}"
@@ -10677,6 +10800,11 @@ msgstr "Restaurer les enregistrements"
msgid "Restore Records"
msgstr "Restaurer les enregistrements"
#. js-lingui-id: hO3AfV
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Restrict available models to a curated list"
msgstr ""
#. js-lingui-id: RD6AE9
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
msgid "Result"
@@ -10958,6 +11086,12 @@ msgstr "Rechercher un champ..."
msgid "Search a folder..."
msgstr ""
#. js-lingui-id: 8J0e5B
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Search a model..."
msgstr ""
#. js-lingui-id: WXvlVa
#: src/modules/settings/roles/components/SettingsRolesList.tsx
msgid "Search a role..."
@@ -11511,6 +11645,11 @@ msgstr "Envoyé et reçu"
msgid "Serbian (Cyrillic)"
msgstr "Serbe (Cyrillique)"
#. js-lingui-id: 8ZSrlB
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Server-wide AI model availability settings"
msgstr ""
#. js-lingui-id: LUc0oL
#: src/modules/settings/security/components/SSO/SettingsSSOSAMLForm.tsx
msgid "Service Provider Details"
@@ -11593,7 +11732,6 @@ msgstr "Configuration de votre base de données..."
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
#: src/pages/settings/ai/SettingsAgentForm.tsx
#: src/pages/settings/ai/SettingsAI.tsx
#: src/modules/sign-in-background-mock/components/SignInAppNavigationDrawerMock.tsx
#: src/modules/settings/roles/role-permissions/permission-flags/components/SettingsRolePermissionsSettingsSection.tsx
#: src/modules/settings/roles/role/components/SettingsRole.tsx
@@ -11812,15 +11950,10 @@ msgid "Small section heading"
msgstr ""
#. js-lingui-id: 5J8ZFl
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Smart Model"
msgstr ""
#. js-lingui-id: qgvZ/2
#: src/pages/settings/ai/components/SettingsAIRouterSettings.tsx
msgid "Smart model updated successfully"
msgstr ""
#. js-lingui-id: w+rJId
#: src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx
msgid "SMTP Configuration"
@@ -11920,6 +12053,14 @@ msgstr "Espaces et virgule - {spacesAndCommaExample}"
msgid "Spanish"
msgstr "Espagnol"
#. js-lingui-id: gsifzp
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Split multiple values"
msgstr ""
#. js-lingui-id: vnS6Rf
#: src/pages/settings/security/SettingsSecurity.tsx
msgid "SSO"
@@ -12398,6 +12539,7 @@ msgid "Task Title"
msgstr "Titre de la tâche"
#. js-lingui-id: GtycJ/
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Tasks"
msgstr "Tâches"
@@ -12597,6 +12739,11 @@ msgstr "Aucune activité n'est associée à cet enregistrement."
msgid "There was an error while updating password."
msgstr "Une erreur est survenue lors de la mise à jour du mot de passe."
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
msgstr ""
#. js-lingui-id: Ed99mE
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
msgid "Thinking..."
@@ -12786,6 +12933,11 @@ msgstr "Cela supprimera définitivement votre méthode d'authentification à deu
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
msgstr "Cela restaurera la valeur de la base de données à la valeur d'environnement/ou par défaut. La surcharge de la base de données sera supprimée et le système utilisera les paramètres d'environnement."
#. js-lingui-id: f8HOUp
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thought"
msgstr ""
#. js-lingui-id: 5g/sE8
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
msgid "Tidy up"
@@ -12817,10 +12969,16 @@ msgid "Time zone"
msgstr "Fuseau horaire"
#. js-lingui-id: cklVjM
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
msgid "Timeline"
msgstr "Chronologie"
#. js-lingui-id: xY9s5E
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "Timeout"
msgstr ""
#. js-lingui-id: 8TMaZI
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
@@ -12876,6 +13034,11 @@ msgstr "Basculer toutes les permissions des objets"
msgid "Toggle all settings permissions"
msgstr "Basculer toutes les permissions des paramètres"
#. js-lingui-id: 93pMSK
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Toggle model availability across all workspaces"
msgstr ""
#. js-lingui-id: WOr+hW
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
msgid "tokens"
@@ -13133,7 +13296,6 @@ msgid "Type"
msgstr "Type"
#. js-lingui-id: SKD2e4
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
#: src/modules/activities/components/ActivityRichTextEditor.tsx
msgid "Type '/' for commands, '@' for mentions"
msgstr ""
@@ -13174,6 +13336,11 @@ msgstr ""
msgid "Unable to Reach Back-end"
msgstr "Impossible d'atteindre le serveur arrière"
#. js-lingui-id: EbnX+O
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "Unconfigured models"
msgstr ""
#. js-lingui-id: EUHN7i
#: src/modules/settings/admin-panel/config-variables/components/ConfigVariableValueInput.tsx
msgid "Undefined"
@@ -13484,11 +13651,26 @@ msgstr "Utiliser comme brouillon"
msgid "Use authenticator apps and browser extensions like 1Password, Authy, Microsoft Authenticator to generate one-time passwords"
msgstr "Utilisez des applications d'authentification et des extensions de navigateur comme 1Password, Authy, Microsoft Authenticator pour générer des mots de passe à usage unique"
#. js-lingui-id: hCZsJ0
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Use best models only"
msgstr ""
#. js-lingui-id: c6uZUV
#: src/modules/object-record/record-table/empty-state/utils/getEmptyStateSubTitle.ts
msgid "Use our API or add your first {objectLabel} manually"
msgstr "Utilisez notre API ou ajoutez manuellement votre premier {objectLabel}"
#. js-lingui-id: 664z2C
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for chats, agents, and complex reasoning"
msgstr ""
#. js-lingui-id: C41qgx
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "Used for lightweight tasks like title generation"
msgstr ""
#. js-lingui-id: AQVj2A
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
msgid "Useful for pivot/junction tables"
@@ -13737,8 +13919,6 @@ msgid "View Logs"
msgstr ""
#. js-lingui-id: ecVcAx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/ai/components/AIChatTab.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
msgid "View Previous AI Chats"
@@ -13994,6 +14174,21 @@ msgstr ""
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
msgstr ""
#. js-lingui-id: 8jc/Xn
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
msgid "When enabled, AI agents and workflow automations can discover and call this function"
msgstr ""
#. js-lingui-id: i2V4DO
#: src/pages/settings/ai/components/SettingsAIModelsTab.tsx
msgid "When enabled, new AI models will be available to users by default"
msgstr ""
#. js-lingui-id: 01e9rV
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
msgid "When enabled, newly added models are available to all workspaces by default"
msgstr ""
#. js-lingui-id: C51ilI
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
msgid "When the API key will expire."
@@ -14126,6 +14321,7 @@ msgid "Workspace Domain"
msgstr "Domaine de l'espace de travail"
#. js-lingui-id: J2q6WC
#: src/pages/settings/security/SettingsSecurity.tsx
#: src/pages/settings/security/event-logs/components/EventLogTableSelector.tsx
msgid "Workspace Events"
msgstr ""
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

Some files were not shown because too many files have changed in this diff Show More