i18n - docs translations (#18541)
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
committed by
GitHub
parent
621962e049
commit
e7fe435f60
@@ -321,11 +321,11 @@ Sie können Standardfelder überschreiben, indem Sie in Ihrem `fields`-Array ein
|
||||
dies wird jedoch nicht empfohlen.
|
||||
</Note>
|
||||
|
||||
### Defining fields on existing objects
|
||||
### Felder für bestehende Objekte definieren
|
||||
|
||||
Use `defineField()` to add custom fields to existing objects — both standard objects (like `company`, `person`, `opportunity`) and custom objects defined by other apps. Each field lives in its own file and references the target object by its `universalIdentifier`.
|
||||
Verwenden Sie `defineField()`, um benutzerdefinierte Felder zu bestehenden Objekten hinzuzufügen — sowohl zu Standardobjekten (wie `company`, `person`, `opportunity`) als auch zu benutzerdefinierten Objekten, die von anderen Apps definiert werden. Jedes Feld befindet sich in einer eigenen Datei und verweist auf das Zielobjekt über dessen `universalIdentifier`.
|
||||
|
||||
To reference standard objects, import `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` from `twenty-sdk`. This constant provides stable identifiers for all built-in objects and their fields:
|
||||
Um auf Standardobjekte zu verweisen, importieren Sie `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` aus `twenty-sdk`. Diese Konstante stellt stabile Bezeichner für alle integrierten Objekte und deren Felder bereit:
|
||||
|
||||
```typescript
|
||||
// src/fields/apollo-total-funding.field.ts
|
||||
@@ -349,22 +349,22 @@ export default defineField({
|
||||
|
||||
Hauptpunkte:
|
||||
|
||||
* `objectUniversalIdentifier` tells Twenty which object to attach the field to. Use `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.<objectName>.universalIdentifier` for standard objects.
|
||||
* Each field requires its own stable `universalIdentifier`, a `name`, `type`, `label`, and the target `objectUniversalIdentifier`.
|
||||
* You can scaffold new fields using `yarn twenty entity:add` and choosing the field option.
|
||||
* `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` is also exported as `STANDARD_OBJECT` for convenience — both refer to the same constant.
|
||||
* `objectUniversalIdentifier` teilt Twenty mit, an welches Objekt das Feld angehängt werden soll. Verwenden Sie `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.<objectName>.universalIdentifier` für Standardobjekte.
|
||||
* Jedes Feld benötigt einen eigenen stabilen `universalIdentifier`, `name`, `type`, `label` und den Ziel-`objectUniversalIdentifier`.
|
||||
* Sie können mit `yarn twenty entity:add` neue Felder anlegen, indem Sie die Feldoption wählen.
|
||||
* `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` wird der Einfachheit halber auch als `STANDARD_OBJECT` exportiert — beide verweisen auf dieselbe Konstante.
|
||||
|
||||
Available standard objects include: `attachment`, `blocklist`, `calendarChannel`, `calendarEvent`, `calendarEventParticipant`, `company`, `connectedAccount`, `dashboard`, `favorite`, `favoriteFolder`, `message`, `messageChannel`, `messageParticipant`, `messageThread`, `note`, `noteTarget`, `opportunity`, `person`, `task`, `taskTarget`, `timelineActivity`, `workflow`, `workflowAutomatedTrigger`, `workflowRun`, `workflowVersion`, and `workspaceMember`.
|
||||
Verfügbare Standardobjekte sind unter anderem: `attachment`, `blocklist`, `calendarChannel`, `calendarEvent`, `calendarEventParticipant`, `company`, `connectedAccount`, `dashboard`, `favorite`, `favoriteFolder`, `message`, `messageChannel`, `messageParticipant`, `messageThread`, `note`, `noteTarget`, `opportunity`, `person`, `task`, `taskTarget`, `timelineActivity`, `workflow`, `workflowAutomatedTrigger`, `workflowRun`, `workflowVersion` und `workspaceMember`.
|
||||
|
||||
Each standard object also exposes its field identifiers. For example, to reference a specific field on a standard object in role permissions:
|
||||
Jedes Standardobjekt stellt außerdem seine Feldbezeichner bereit. Beispielsweise, um in Rollenberechtigungen auf ein bestimmtes Feld eines Standardobjekts zu verweisen:
|
||||
|
||||
```typescript
|
||||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name.universalIdentifier
|
||||
```
|
||||
|
||||
#### Relation fields on existing objects
|
||||
#### Beziehungsfelder bei bestehenden Objekten
|
||||
|
||||
You can also define relation fields that link existing objects to your custom objects:
|
||||
Sie können auch Beziehungsfelder definieren, die bestehende Objekte mit Ihren benutzerdefinierten Objekten verknüpfen:
|
||||
|
||||
```typescript
|
||||
// src/fields/people-on-call-recording.field.ts
|
||||
@@ -837,6 +837,255 @@ 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 `.tsx`-Datei und verwenden Sie `defineFrontComponent()` nach demselben Muster.
|
||||
|
||||
#### Where front components can be used
|
||||
|
||||
Front components can render in two locations within Twenty:
|
||||
|
||||
* **Side panel** — Non-headless front components open in the right-hand side panel. This is the default behavior when a front component is triggered from the command menu.
|
||||
* **Widgets (dashboards and record pages)** — Front components can be embedded as widgets inside page layouts. When configuring a dashboard or a record page layout, users can add a front component widget.
|
||||
|
||||
#### Headless vs non-headless
|
||||
|
||||
Front components come in two rendering modes controlled by the `isHeadless` option:
|
||||
|
||||
**Non-headless (default)** — The component renders a visible UI. When triggered from the command menu it opens in the side panel. This is the default behavior when `isHeadless` is `false` or omitted.
|
||||
|
||||
**Headless** — The component mounts invisibly in the background. It does not open the side panel. Headless components are designed for actions that execute logic and then unmount themselves — for example, running an async task, navigating to a page, or showing a confirmation modal. They pair naturally with the SDK Command components described below.
|
||||
|
||||
```typescript
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
|
||||
name: 'my-action',
|
||||
description: 'Runs an action without opening the side panel',
|
||||
component: MyAction,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'b2c3d4e5-f6a7-8901-bcde-f12345678901',
|
||||
label: 'Run my action',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### Adding command menu items
|
||||
|
||||
To make a front component appear as an item in Twenty's command menu, add the `command` property to `defineFrontComponent()`. When users open the command menu (Cmd+K / Ctrl+K), the item shows up and triggers the front component on click.
|
||||
|
||||
The `command` object accepts the following fields:
|
||||
|
||||
| Feld | Typ | Beschreibung |
|
||||
| --------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| `universalIdentifier` | `string` (required) | Unique ID for the command menu item |
|
||||
| `beschriftung` | `string` (required) | Display label shown in the command menu |
|
||||
| `symbol` | `string` (optional) | Icon name (e.g., `'IconSparkles'`) |
|
||||
| `isPinned` | `boolean` (optional) | Whether the command is pinned at the top of the menu |
|
||||
| `availabilityType` | `'GLOBAL' \| 'RECORD_SELECTION'` (optional) | `GLOBAL` shows the command everywhere; `RECORD_SELECTION` shows it only in record contexts |
|
||||
| `availabilityObjectUniversalIdentifier` | `string` (optional) | Restrict the command to a specific object type (e.g., Person) |
|
||||
|
||||
Here is an example from the call-recording app that adds a command scoped to Person records:
|
||||
|
||||
```typescript
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'c3d4e5f6-a7b8-9012-cdef-123456789012',
|
||||
name: 'Summarize Person Call Recordings',
|
||||
description: 'Generates a summary of call recordings for a person',
|
||||
component: SummarizePersonRecordings,
|
||||
command: {
|
||||
universalIdentifier: 'd4e5f6a7-b8c9-0123-defa-234567890123',
|
||||
label: 'Summarize call recordings',
|
||||
icon: 'IconSparkles',
|
||||
isPinned: false,
|
||||
availabilityType: 'RECORD_SELECTION',
|
||||
availabilityObjectUniversalIdentifier:
|
||||
'20202020-e674-48e5-a542-72570eee7213',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
When the command is synced, it appears in the command menu. If the front component is non-headless the side panel opens with the component rendered inside. If it is headless the component mounts in the background and executes its logic.
|
||||
|
||||
#### SDK Command components
|
||||
|
||||
The `twenty-sdk` package provides four Command helper components designed for headless front components. Each component executes an action on mount, handles errors by showing a snackbar notification, and automatically unmounts the front component when done.
|
||||
|
||||
Import them from `twenty-sdk/command`:
|
||||
|
||||
* **`Command`** — Runs an async callback via the `execute` prop.
|
||||
* **`CommandLink`** — Navigates to an app path. Props: `to`, `params`, `queryParams`, `options`.
|
||||
* **`CommandModal`** — Opens a confirmation modal. If the user confirms, executes the `execute` callback. Props: `title`, `subtitle`, `execute`, `confirmButtonText`, `confirmButtonAccent`.
|
||||
* **`CommandOpenSidePanelPage`** — Opens a specific side panel page. Props: `page`, `pageTitle`, `pageIcon`.
|
||||
|
||||
Here is a full example of a headless front component using `Command` to run an action from the command menu:
|
||||
|
||||
```typescript
|
||||
// src/front-components/run-action.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { Command } from 'twenty-sdk/command';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const RunAction = () => {
|
||||
const execute = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
createTask: {
|
||||
__args: { data: { title: 'Created by my app' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return <Command execute={execute} />;
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'e5f6a7b8-c9d0-1234-efab-345678901234',
|
||||
name: 'run-action',
|
||||
description: 'Creates a task from the command menu',
|
||||
component: RunAction,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'f6a7b8c9-d0e1-2345-fabc-456789012345',
|
||||
label: 'Run my action',
|
||||
icon: 'IconPlayerPlay',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
And an example using `CommandModal` to ask for confirmation before executing:
|
||||
|
||||
```typescript
|
||||
// src/front-components/delete-draft.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { CommandModal } from 'twenty-sdk/command';
|
||||
|
||||
const DeleteDraft = () => {
|
||||
const execute = async () => {
|
||||
// perform the deletion
|
||||
};
|
||||
|
||||
return (
|
||||
<CommandModal
|
||||
title="Delete draft?"
|
||||
subtitle="This action cannot be undone."
|
||||
execute={execute}
|
||||
confirmButtonText="Delete"
|
||||
confirmButtonAccent="danger"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'a7b8c9d0-e1f2-3456-abcd-567890123456',
|
||||
name: 'delete-draft',
|
||||
description: 'Deletes a draft with confirmation',
|
||||
component: DeleteDraft,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'b8c9d0e1-f2a3-4567-bcde-678901234567',
|
||||
label: 'Delete draft',
|
||||
icon: 'IconTrash',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### Execution context
|
||||
|
||||
Every front component receives an execution context that provides information about where and how it is running. Access context values using hooks from `twenty-sdk`:
|
||||
|
||||
| Hook | Return type | Beschreibung |
|
||||
| ----------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `useFrontComponentId()` | `string` | The unique ID of the current front component instance |
|
||||
| `useRecordId()` | `string \| null` | The ID of the current record, when the component runs in a record context (e.g., a record page widget or a command scoped to a record). Returns `null` otherwise. |
|
||||
| `useUserId()` | `string \| null` | The ID of the current user |
|
||||
|
||||
```typescript
|
||||
import { useRecordId, useUserId } from 'twenty-sdk';
|
||||
|
||||
const MyWidget = () => {
|
||||
const recordId = useRecordId();
|
||||
const userId = useUserId();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>Record: {recordId ?? 'none'}</p>
|
||||
<p>User: {userId ?? 'anonymous'}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
The context is reactive — if the surrounding record changes, hooks automatically return the updated values.
|
||||
|
||||
#### Host API functions
|
||||
|
||||
Front components run in an isolated sandbox but can interact with Twenty's UI through a set of functions provided by the host. Import them directly from `twenty-sdk`:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
navigate,
|
||||
closeSidePanel,
|
||||
enqueueSnackbar,
|
||||
unmountFrontComponent,
|
||||
openSidePanelPage,
|
||||
openCommandConfirmationModal,
|
||||
} from 'twenty-sdk';
|
||||
```
|
||||
|
||||
| Funktion | Signature | Beschreibung |
|
||||
| ------------------------------ | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `navigieren` | `(to, params?, queryParams?, options?) => Promise<void>` | Navigate to a typed app path within Twenty |
|
||||
| `closeSidePanel` | `() => Promise<void>` | Close the side panel |
|
||||
| `enqueueSnackbar` | `(params) => Promise<void>` | Show a snackbar notification. Params: `message`, `variant` (`'error'`, `'success'`, `'info'`, `'warning'`), optional `duration`, `detailedMessage`, `dedupeKey` |
|
||||
| `unmountFrontComponent` | `() => Promise<void>` | Unmount the current front component (used by headless components to clean up after execution) |
|
||||
| `openSidePanelPage` | `(params) => Promise<void>` | Open a page in the side panel. Params: `page`, `pageTitle`, `pageIcon`, `shouldResetSearchState` |
|
||||
| `openCommandConfirmationModal` | `(params) => Promise<'confirm' \| 'cancel'>` | Show a confirmation modal and wait for the user's response. Params: `title`, `subtitle`, `confirmButtonText`, `confirmButtonAccent` (`'default'`, `'blue'`, `'danger'`) |
|
||||
|
||||
Here is an example that uses the host API to show a snackbar and close the side panel after an action completes:
|
||||
|
||||
```typescript
|
||||
import { defineFrontComponent, useRecordId } from 'twenty-sdk';
|
||||
import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const ArchiveRecord = () => {
|
||||
const recordId = useRecordId();
|
||||
|
||||
const handleArchive = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
updateTask: {
|
||||
__args: { id: recordId, data: { status: 'ARCHIVED' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
await enqueueSnackbar({
|
||||
message: 'Record archived',
|
||||
variant: 'success',
|
||||
});
|
||||
|
||||
await closeSidePanel();
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px' }}>
|
||||
<p>Archive this record?</p>
|
||||
<button onClick={handleArchive}>Archive</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'c9d0e1f2-a3b4-5678-cdef-789012345678',
|
||||
name: 'archive-record',
|
||||
description: 'Archives the current record',
|
||||
component: ArchiveRecord,
|
||||
});
|
||||
```
|
||||
|
||||
### 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:
|
||||
@@ -974,12 +1223,12 @@ uploadFile(
|
||||
): 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 |
|
||||
| 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` | `Zeichenkette` | Der `universalIdentifier` des Dateityp-Felds in Ihrem Objekt |
|
||||
|
||||
Hauptpunkte:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user