diff --git a/packages/twenty-docs/l/pt/developers/extend/apps/building.mdx b/packages/twenty-docs/l/pt/developers/extend/apps/building.mdx index a0e2cf9f09..4c85dc2ac4 100644 --- a/packages/twenty-docs/l/pt/developers/extend/apps/building.mdx +++ b/packages/twenty-docs/l/pt/developers/extend/apps/building.mdx @@ -760,22 +760,22 @@ Clique nele para renderizar o componente inline. #### Campos de configuração -| Campo | Obrigatório | Descrição | -| --------------------- | ----------- | ----------------------------------------------------------------------------------- | -| `universalIdentifier` | Sim | ID único e estável para este componente | -| `component` | Sim | Uma função de componente React | -| `name` | Não | Nome de Exibição | -| `description` | Não | Descrição do que o componente faz | -| `isHeadless` | Não | Set to `true` if the component has no visible UI (see below) | -| `command` | Não | Register the component as a command (see [command options](#command-options) below) | +| Campo | Obrigatório | Descrição | +| --------------------- | ----------- | ----------------------------------------------------------------------------------------- | +| `universalIdentifier` | Sim | ID único e estável para este componente | +| `component` | Sim | Uma função de componente React | +| `name` | Não | Nome de Exibição | +| `description` | Não | Descrição do que o componente faz | +| `isHeadless` | Não | Defina como `true` se o componente não tiver interface visível (veja abaixo) | +| `command` | Não | Registre o componente como um comando (veja [opções de comando](#command-options) abaixo) | -#### Placing a front component on a page +#### Colocando um componente de front-end em uma página -Beyond commands, you can embed a front component directly into a record page by adding it as a widget in a **page layout**. See the [definePageLayout](#definepagelayout) section for details. +Além de comandos, você pode incorporar um componente de front-end diretamente em uma página de registro adicionando-o como um widget em um **layout de página**. Veja a seção [definePageLayout](#definepagelayout) para obter detalhes. -#### Headless components (`isHeadless: true`) +#### Componentes sem interface (`isHeadless: true`) -Headless components render no visible UI but still run React logic. This is useful for **effect components** — components that perform side effects when mounted, such as syncing data, starting a timer, listening to events, or triggering a notification. +Componentes sem interface não renderizam nenhuma UI visível, mas ainda executam a lógica do React. Isso é útil para **componentes de efeito** — componentes que executam efeitos colaterais quando montados, como sincronizar dados, iniciar um temporizador, ouvir eventos ou disparar uma notificação. ```tsx src/front-components/sync-tracker.tsx import { defineFrontComponent, useRecordId, enqueueSnackbar } from 'twenty-sdk'; @@ -800,11 +800,11 @@ export default defineFrontComponent({ }); ``` -Because the component returns `null`, Twenty skips rendering a container for it — no empty space appears in the layout. The component still has access to all hooks and the host communication API. +Como o componente retorna `null`, o Twenty ignora renderizar um contêiner para ele — nenhum espaço vazio aparece no layout. O componente ainda tem acesso a todos os hooks e à API de comunicação do host. -#### Accessing runtime context +#### Acessando o contexto de execução -Inside your component, use SDK hooks to access the current user, record, and component instance: +Dentro do seu componente, use hooks do SDK para acessar o usuário atual, o registro e a instância do componente: ```tsx src/front-components/record-info.tsx import { @@ -835,47 +835,47 @@ export default defineFrontComponent({ }); ``` -Available hooks: +Hooks disponíveis: -| Hook | Returns | Descrição | -| --------------------------------------------- | ------------------ | ---------------------------------------------------------- | -| `useUserId()` | `string` or `null` | The current user's ID | -| `useRecordId()` | `string` or `null` | The current record's ID (when placed on a record page) | -| `useFrontComponentId()` | `string` | This component instance's ID | -| `useFrontComponentExecutionContext(selector)` | varia | Access the full execution context with a selector function | +| Hook | Retorna | Descrição | +| --------------------------------------------- | ------------------ | ------------------------------------------------------------------ | +| `useUserId()` | `string` ou `null` | O ID do usuário atual | +| `useRecordId()` | `string` ou `null` | O ID do registro atual (quando colocado em uma página de registro) | +| `useFrontComponentId()` | `string` | O ID desta instância do componente | +| `useFrontComponentExecutionContext(selector)` | varia | Acesse o contexto de execução completo com uma função seletora | -#### Host communication API +#### API de comunicação do host -Front components can trigger navigation, modals, and notifications using functions from `twenty-sdk`: +Componentes de front-end podem acionar navegação, modais e notificações usando funções de `twenty-sdk`: -| Função | Descrição | -| ----------------------------------------------- | ----------------------------- | -| `navigate(to, params?, queryParams?, options?)` | Navigate to a page in the app | -| `openSidePanelPage(params)` | Open a side panel | -| `closeSidePanel()` | Fecha o painel lateral | -| `openCommandConfirmationModal(params)` | Show a confirmation dialog | -| `enqueueSnackbar(params)` | Show a toast notification | -| `unmountFrontComponent()` | Unmount the component | -| `updateProgress(progress)` | Update a progress indicator | +| Função | Descrição | +| ----------------------------------------------- | ------------------------------------- | +| `navigate(to, params?, queryParams?, options?)` | Navegar para uma página no app | +| `openSidePanelPage(params)` | Abrir um painel lateral | +| `closeSidePanel()` | Fecha o painel lateral | +| `openCommandConfirmationModal(params)` | Mostrar um diálogo de confirmação | +| `enqueueSnackbar(params)` | Mostrar uma notificação do tipo toast | +| `unmountFrontComponent()` | Desmontar o componente | +| `updateProgress(progress)` | Atualizar um indicador de progresso | -#### Command options +#### Opções de comando -Adding a `command` field to `defineFrontComponent` registers the component in the command menu (Cmd+K). If `isPinned` is `true`, it also appears as a quick-action button in the top-right corner of the page. +Adicionar um campo `command` a `defineFrontComponent` registra o componente no menu de comandos (Cmd+K). Se `isPinned` for `true`, ele também aparece como um botão de ação rápida no canto superior direito da página. -| Campo | Obrigatório | Descrição | -| --------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `universalIdentifier` | Sim | Stable unique ID for the command | -| `label` | Sim | Full label shown in the command menu (Cmd+K) | -| `shortLabel` | Não | Shorter label displayed on the pinned quick-action button | -| `icon` | Não | Icon name displayed next to the label (e.g. `'IconBolt'`, `'IconSend'`) | -| `isPinned` | Não | When `true`, shows the command as a quick-action button in the top-right corner of the page | -| `availabilityType` | Não | Controls where the command appears: `'GLOBAL'` (always available), `'RECORD_SELECTION'` (only when records are selected), or `'FALLBACK'` (shown when no other commands match) | -| `availabilityObjectUniversalIdentifier` | Não | Restrict the command to pages of a specific object type (e.g. only on Company records) | -| `conditionalAvailabilityExpression` | Não | A boolean expression to dynamically control whether the command is visible (see below) | +| Campo | Obrigatório | Descrição | +| --------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `universalIdentifier` | Sim | ID exclusivo e estável para o comando | +| `label` | Sim | Rótulo completo exibido no menu de comandos (Cmd+K) | +| `shortLabel` | Não | Rótulo mais curto exibido no botão fixado de ação rápida | +| `icon` | Não | Nome do ícone exibido ao lado do rótulo (por exemplo, `'IconBolt'`, `'IconSend'`) | +| `isPinned` | Não | Quando `true`, mostra o comando como um botão de ação rápida no canto superior direito da página | +| `availabilityType` | Não | Controla onde o comando aparece: `'GLOBAL'` (sempre disponível), `'RECORD_SELECTION'` (apenas quando registros estão selecionados) ou `'FALLBACK'` (exibido quando nenhum outro comando corresponde) | +| `availabilityObjectUniversalIdentifier` | Não | Restringe o comando a páginas de um tipo específico de objeto (por exemplo, somente em registros de Company) | +| `conditionalAvailabilityExpression` | Não | Uma expressão booleana para controlar dinamicamente se o comando é visível (veja abaixo) | -#### Conditional availability expressions +#### Expressões de disponibilidade condicional -The `conditionalAvailabilityExpression` field lets you control when a command is visible based on the current page context. Import typed variables and operators from `twenty-sdk` to build expressions: +O campo `conditionalAvailabilityExpression` permite controlar quando um comando é visível com base no contexto da página atual. Importe variáveis tipadas e operadores de `twenty-sdk` para construir expressões: ```tsx import { @@ -904,45 +904,45 @@ export default defineFrontComponent({ }); ``` -**Context variables** — these represent the current state of the page: +**Variáveis de contexto** — representam o estado atual da página: -| Variável | Tipo | Descrição | -| ------------------------------ | --------- | ---------------------------------------------------------------- | -| `pageType` | `string` | Current page type (e.g. `'RecordIndexPage'`, `'RecordShowPage'`) | -| `isInSidePanel` | `boolean` | Whether the component is rendered in a side panel | -| `numberOfSelectedRecords` | `number` | Number of currently selected records | -| `isSelectAll` | `boolean` | Whether "select all" is active | -| `selectedRecords` | `array` | The selected record objects | -| `favoriteRecordIds` | `array` | IDs of favorited records | -| `objectPermissions` | `object` | Permissions for the current object type | -| `targetObjectReadPermissions` | `object` | Read permissions for the target object | -| `targetObjectWritePermissions` | `object` | Write permissions for the target object | -| `featureFlags` | `object` | Active feature flags | -| `objectMetadataItem` | `object` | Metadata of the current object type | -| `hasAnySoftDeleteFilterOnView` | `boolean` | Whether the current view has a soft-delete filter | +| Variável | Tipo | Descrição | +| ------------------------------ | --------- | --------------------------------------------------------------------------- | +| `pageType` | `string` | Tipo de página atual (por exemplo, `'RecordIndexPage'`, `'RecordShowPage'`) | +| `isInSidePanel` | `boolean` | Se o componente é renderizado em um painel lateral | +| `numberOfSelectedRecords` | `number` | Número de registros atualmente selecionados | +| `isSelectAll` | `boolean` | Se "selecionar tudo" está ativo | +| `selectedRecords` | `array` | Os objetos de registro selecionados | +| `favoriteRecordIds` | `array` | IDs dos registros marcados como favoritos | +| `objectPermissions` | `object` | Permissões para o tipo de objeto atual | +| `targetObjectReadPermissions` | `object` | Permissões de leitura para o objeto alvo | +| `targetObjectWritePermissions` | `object` | Permissões de escrita para o objeto alvo | +| `featureFlags` | `object` | Flags de recurso ativas | +| `objectMetadataItem` | `object` | Metadados do tipo de objeto atual | +| `hasAnySoftDeleteFilterOnView` | `boolean` | Se a visualização atual tem um filtro de soft-delete | -**Operators** — combine variables into boolean expressions: +**Operadores** — combine variáveis em expressões booleanas: -| Operator | Descrição | -| ----------------------------------- | ----------------------------------------------------------------- | -| `isDefined(value)` | `true` if the value is not null/undefined | -| `isNonEmptyString(value)` | `true` if the value is a non-empty string | -| `includes(array, value)` | `true` if the array contains the value | -| `includesEvery(array, prop, value)` | `true` if every item's property includes the value | -| `every(array, prop)` | `true` if the property is truthy on every item | -| `everyDefined(array, prop)` | `true` if the property is defined on every item | -| `everyEquals(array, prop, value)` | `true` if the property equals the value on every item | -| `some(array, prop)` | `true` if the property is truthy on at least one item | -| `someDefined(array, prop)` | `true` if the property is defined on at least one item | -| `someEquals(array, prop, value)` | `true` if the property equals the value on at least one item | -| `someNonEmptyString(array, prop)` | `true` if the property is a non-empty string on at least one item | -| `none(array, prop)` | `true` if the property is falsy on every item | -| `noneDefined(array, prop)` | `true` if the property is undefined on every item | -| `noneEquals(array, prop, value)` | `true` if the property does not equal the value on any item | +| Operador | Descrição | +| ----------------------------------- | ---------------------------------------------------------------------- | +| `isDefined(value)` | `true` se o valor não for null/undefined | +| `isNonEmptyString(value)` | `true` se o valor for uma string não vazia | +| `includes(array, value)` | `true` se o array contiver o valor | +| `includesEvery(array, prop, value)` | `true` se a propriedade de cada item incluir o valor | +| `every(array, prop)` | `true` se a propriedade for truthy em cada item | +| `everyDefined(array, prop)` | `true` se a propriedade estiver definida em cada item | +| `everyEquals(array, prop, value)` | `true` se a propriedade for igual ao valor em cada item | +| `some(array, prop)` | `true` se a propriedade for truthy em pelo menos um item | +| `someDefined(array, prop)` | `true` se a propriedade estiver definida em pelo menos um item | +| `someEquals(array, prop, value)` | `true` se a propriedade for igual ao valor em pelo menos um item | +| `someNonEmptyString(array, prop)` | `true` se a propriedade for uma string não vazia em pelo menos um item | +| `none(array, prop)` | `true` se a propriedade for falsy em cada item | +| `noneDefined(array, prop)` | `true` se a propriedade for undefined em cada item | +| `noneEquals(array, prop, value)` | `true` se a propriedade não for igual ao valor em nenhum item | -#### Public assets +#### Recursos públicos -Front components can access files from the app's `public/` directory using `getPublicAssetUrl`: +Componentes de front-end podem acessar arquivos do diretório `public/` do app usando `getPublicAssetUrl`: ```tsx import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk'; @@ -956,18 +956,18 @@ export default defineFrontComponent({ }); ``` -See the [public assets section](#accessing-public-assets-with-getpublicasseturl) for details. +Veja a [seção de recursos públicos](#accessing-public-assets-with-getpublicasseturl) para obter detalhes. #### Estilização -Front components support multiple styling approaches. You can use: +Componentes de front-end suportam várias abordagens de estilização. Você pode usar: -* **Inline styles** — `style={{ color: 'red' }}` -* **Twenty UI components** — import from `twenty-sdk/ui` (Button, Tag, Status, Chip, Avatar, and more) -* **Emotion** — CSS-in-JS with `@emotion/react` -* **Styled-components** — `styled.div` patterns -* **Tailwind CSS** — utility classes -* **Any CSS-in-JS library** compatible with React +* **Estilos inline** — `style={{ color: 'red' }}` +* **Componentes de UI do Twenty** — importe de `twenty-sdk/ui` (Button, Tag, Status, Chip, Avatar e mais) +* **Emotion** — CSS-in-JS com `@emotion/react` +* **Styled-components** — padrões `styled.div` +* **Tailwind CSS** — classes utilitárias +* **Qualquer biblioteca CSS-in-JS** compatível com React ```tsx import { defineFrontComponent } from 'twenty-sdk'; @@ -1021,9 +1021,9 @@ Pontos-chave: * `description` (opcional) fornece contexto adicional sobre a finalidade da habilidade. - + -Agents are AI assistants that live inside your workspace. Use `defineAgent()` to create agents with a custom system prompt: +Agentes são assistentes de IA que vivem dentro do seu espaço de trabalho. Use `defineAgent()` para criar agentes com um prompt de sistema personalizado: ```ts src/agents/example-agent.ts import { defineAgent } from 'twenty-sdk'; @@ -1039,17 +1039,17 @@ export default defineAgent({ ``` Pontos-chave: -* `name` is the unique identifier string for the agent (kebab-case recommended). -* `label` is the display name shown in the UI. -* `prompt` is the system prompt that defines the agent's behavior. -* `description` (optional) provides context about what the agent does. +* `name` é a string de identificador exclusiva do agente (recomenda-se kebab-case). +* `label` é o nome de exibição mostrado na UI. +* `prompt` é o prompt do sistema que define o comportamento do agente. +* `description` (opcional) fornece contexto sobre o que o agente faz. * `icon` (opcional) define o ícone exibido na UI. -* `modelId` (optional) overrides the default AI model used by the agent. +* `modelId` (opcional) substitui o modelo de IA padrão usado pelo agente. -Views are saved configurations for how records of an object are displayed — including which fields are visible, their order, and any filters or groups applied. Use `defineView()` to ship pre-configured views with your app: +As visualizações são configurações salvas de como os registros de um objeto são exibidos — incluindo quais campos são visíveis, sua ordem e quaisquer filtros ou grupos aplicados. Use `defineView()` para enviar visualizações pré-configuradas com seu app: ```ts src/views/example-view.ts import { defineView, ViewKey } from 'twenty-sdk'; @@ -1076,16 +1076,16 @@ export default defineView({ ``` Pontos-chave: -* `objectUniversalIdentifier` specifies which object this view applies to. -* `key` determines the view type (e.g., `ViewKey.INDEX` for the main list view). -* `fields` controls which columns appear and their order. Each field references a `fieldMetadataUniversalIdentifier`. -* You can also define `filters`, `filterGroups`, `groups`, and `fieldGroups` for more advanced configurations. -* `position` controls the ordering when multiple views exist for the same object. +* `objectUniversalIdentifier` especifica a qual objeto esta visualização se aplica. +* `key` determina o tipo de visualização (por exemplo, `ViewKey.INDEX` para a visualização de lista principal). +* `fields` controla quais colunas aparecem e sua ordem. Cada campo referencia um `fieldMetadataUniversalIdentifier`. +* Você também pode definir `filters`, `filterGroups`, `groups` e `fieldGroups` para configurações mais avançadas. +* `position` controla a ordenação quando existem várias visualizações para o mesmo objeto. -Navigation menu items add custom entries to the workspace sidebar. Use `defineNavigationMenuItem()` to link to views, external URLs, or objects: +Os itens do menu de navegação adicionam entradas personalizadas à barra lateral do espaço de trabalho. Use `defineNavigationMenuItem()` para vincular a visualizações, URLs externas ou objetos: ```ts src/navigation-menu-items/example-navigation-menu-item.ts import { defineNavigationMenuItem, NavigationMenuItemType } from 'twenty-sdk'; @@ -1103,15 +1103,15 @@ export default defineNavigationMenuItem({ ``` Pontos-chave: -* `type` determines what the menu item links to: `NavigationMenuItemType.VIEW` for a saved view, or `NavigationMenuItemType.LINK` for an external URL. -* For view links, set `viewUniversalIdentifier`. For external links, set `link`. -* `position` controls the ordering in the sidebar. -* `icon` and `color` (optional) customize the appearance. +* `type` determina para o que o item de menu aponta: `NavigationMenuItemType.VIEW` para uma visualização salva ou `NavigationMenuItemType.LINK` para uma URL externa. +* Para links de visualização, defina `viewUniversalIdentifier`. Para links externos, defina `link`. +* `position` controla a ordenação na barra lateral. +* `icon` e `color` (opcionais) personalizam a aparência. - + -Page layouts let you customize how a record detail page looks — which tabs appear, what widgets are inside each tab, and how they are arranged. Use `definePageLayout()` to ship custom layouts with your app: +Layouts de página permitem personalizar como uma página de detalhes do registro se parece — quais abas aparecem, quais widgets estão dentro de cada aba e como eles são organizados. Use `definePageLayout()` para enviar layouts personalizados com seu app: ```ts src/page-layouts/example-record-page-layout.ts import { definePageLayout, PageLayoutTabLayoutMode } from 'twenty-sdk'; @@ -1148,33 +1148,33 @@ export default definePageLayout({ ``` Pontos-chave: -* `type` is typically `'RECORD_PAGE'` to customize the detail view of a specific object. -* `objectUniversalIdentifier` specifies which object this layout applies to. -* Each `tab` defines a section of the page with a `title`, `position`, and `layoutMode` (`CANVAS` for free-form layout). -* Each `widget` inside a tab can render a front component, a relation list, or other built-in widget types. -* `position` on tabs controls their order. Use higher values (e.g., 50) to place custom tabs after built-in ones. +* `type` geralmente é `'RECORD_PAGE'` para personalizar a visualização de detalhes de um objeto específico. +* `objectUniversalIdentifier` especifica a qual objeto este layout se aplica. +* Cada `tab` define uma seção da página com um `title`, `position` e `layoutMode` (`CANVAS` para layout livre). +* Cada `widget` dentro de uma aba pode renderizar um componente de front-end, uma lista de relações ou outros tipos de widget incorporados. +* `position` nas abas controla sua ordem. Use valores mais altos (por exemplo, 50) para colocar abas personalizadas após as nativas. -## Public assets (`public/` folder) +## Recursos públicos (pasta `public/`) -The `public/` folder at the root of your app holds static files — images, icons, fonts, or any other assets your app needs at runtime. These files are automatically included in builds, synced during dev mode, and uploaded to the server. +A pasta `public/` na raiz do seu app contém arquivos estáticos — imagens, ícones, fontes ou quaisquer outros recursos de que seu app precisa em tempo de execução. Esses arquivos são incluídos automaticamente nas compilações, sincronizados durante o modo de desenvolvimento e enviados para o servidor. -Files placed in `public/` are: +Arquivos colocados em `public/` são: -* **Publicly accessible** — once synced to the server, assets are served at a public URL. No authentication is needed to access them. -* **Available in front components** — use asset URLs to display images, icons, or any media inside your React components. -* **Available in logic functions** — reference asset URLs in emails, API responses, or any server-side logic. -* **Used for marketplace metadata** — the `logoUrl` and `screenshots` fields in `defineApplication()` reference files from this folder (e.g., `public/logo.png`). These are displayed in the marketplace when your app is published. -* **Auto-synced in dev mode** — when you add, update, or delete a file in `public/`, it is synced to the server automatically. No restart needed. -* **Included in builds** — `yarn twenty build` bundles all public assets into the distribution output. +* **Publicamente acessíveis** — depois de sincronizados com o servidor, os recursos são servidos em uma URL pública. Não é necessária autenticação para acessá-los. +* **Disponíveis em componentes de front-end** — use URLs de recursos para exibir imagens, ícones ou qualquer mídia dentro de seus componentes React. +* **Disponíveis em funções lógicas** — referencie URLs de recursos em e-mails, respostas de API ou qualquer lógica no lado do servidor. +* **Usados para metadados do marketplace** — os campos `logoUrl` e `screenshots` em `defineApplication()` referenciam arquivos desta pasta (por exemplo, `public/logo.png`). Eles são exibidos no marketplace quando seu app é publicado. +* **Sincronizados automaticamente no modo de desenvolvimento** — quando você adiciona, atualiza ou exclui um arquivo em `public/`, ele é sincronizado automaticamente com o servidor. Não é necessário reiniciar. +* **Incluídos nas compilações** — `yarn twenty build` agrupa todos os recursos públicos na saída de distribuição. -### Accessing public assets with `getPublicAssetUrl` +### Acessando recursos públicos com `getPublicAssetUrl` -Use the `getPublicAssetUrl` helper from `twenty-sdk` to get the full URL of a file in your `public/` directory. It works in both **logic functions** and **front components**. +Use o helper `getPublicAssetUrl` de `twenty-sdk` para obter a URL completa de um arquivo no seu diretório `public/`. Funciona tanto em **funções lógicas** quanto em **componentes de front-end**. -**In a logic function:** +**Em uma função lógica:** ```ts src/logic-functions/send-invoice.ts import { defineLogicFunction, getPublicAssetUrl } from 'twenty-sdk'; @@ -1199,7 +1199,7 @@ export default defineLogicFunction({ }); ``` -**In a front component:** +**Em um componente de front-end:** ```tsx src/front-components/company-card.tsx import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk'; @@ -1211,19 +1211,19 @@ export default defineFrontComponent(() => { }); ``` -The `path` argument is relative to your app's `public/` folder. Both `getPublicAssetUrl('logo.png')` and `getPublicAssetUrl('public/logo.png')` resolve to the same URL — the `public/` prefix is stripped automatically if present. +O argumento `path` é relativo à pasta `public/` do seu app. Tanto `getPublicAssetUrl('logo.png')` quanto `getPublicAssetUrl('public/logo.png')` resolvem para a mesma URL — o prefixo `public/` é removido automaticamente, se presente. -## Using npm packages +## Usando pacotes npm -You can install and use any npm package in your app. Both logic functions and front components are bundled with [esbuild](https://esbuild.github.io/), which inlines all dependencies into the output — no `node_modules` are needed at runtime. +Você pode instalar e usar qualquer pacote npm no seu app. Tanto funções lógicas quanto componentes de front-end são empacotados com [esbuild](https://esbuild.github.io/), que incorpora todas as dependências na saída — nenhum `node_modules` é necessário em tempo de execução. -### Installing a package +### Instalando um pacote ```bash filename="Terminal" yarn add axios ``` -Then import it in your code: +Em seguida, importe-o no seu código: ```ts src/logic-functions/fetch-data.ts import { defineLogicFunction } from 'twenty-sdk'; @@ -1244,7 +1244,7 @@ export default defineLogicFunction({ }); ``` -The same works for front components: +O mesmo vale para componentes de front-end: ```tsx src/front-components/chart.tsx import { defineFrontComponent } from 'twenty-sdk'; @@ -1261,27 +1261,27 @@ export default defineFrontComponent({ }); ``` -### How bundling works +### Como o empacotamento funciona -The build step (`yarn twenty dev` or `yarn twenty build`) uses esbuild to produce a single self-contained file per logic function and per front component. All imported packages are inlined into the bundle. +A etapa de build (`yarn twenty dev` ou `yarn twenty build`) usa o esbuild para produzir um único arquivo independente por função lógica e por componente de front-end. Todos os pacotes importados são incorporados ao bundle. -**Logic functions** run in a Node.js environment. Node built-in modules (`fs`, `path`, `crypto`, `http`, etc.) are available and do not need to be installed. +**Funções lógicas** são executadas em um ambiente Node.js. Módulos nativos do Node (`fs`, `path`, `crypto`, `http`, etc.) estão disponíveis e não precisam ser instalados. -**Front components** run in a Web Worker. Node built-in modules are **not** available — only browser APIs and npm packages that work in a browser environment. +**Componentes de front-end** são executados em um Web Worker. Módulos nativos do Node **não** estão disponíveis — apenas APIs do navegador e pacotes npm que funcionam em um ambiente de navegador. -Both environments have `twenty-client-sdk/core` and `twenty-client-sdk/metadata` available as pre-provided modules — these are not bundled but resolved at runtime by the server. +Ambos os ambientes têm `twenty-client-sdk/core` e `twenty-client-sdk/metadata` disponíveis como módulos pré-fornecidos — eles não são empacotados, mas resolvidos em tempo de execução pelo servidor. -## Scaffolding entities with `yarn twenty add` +## Gerando entidades com `yarn twenty add` -Instead of creating entity files by hand, you can use the interactive scaffolder: +Em vez de criar arquivos de entidade manualmente, você pode usar o scaffolder interativo: ```bash filename="Terminal" yarn twenty add ``` -This prompts you to pick an entity type and walks you through the required fields. It generates a ready-to-use file with a stable `universalIdentifier` and the correct `defineEntity()` call. +Isso solicita que você escolha um tipo de entidade e orienta você pelos campos obrigatórios. Ele gera um arquivo pronto para uso com um `universalIdentifier` estável e a chamada correta de `defineEntity()`. -You can also pass the entity type directly to skip the first prompt: +Você também pode passar o tipo de entidade diretamente para pular o primeiro prompt: ```bash filename="Terminal" yarn twenty add object @@ -1289,20 +1289,20 @@ yarn twenty add logicFunction yarn twenty add frontComponent ``` -### Available entity types +### Tipos de entidade disponíveis -| Tipo de entidade | Comando | Generated file | -| -------------------- | ------------------------------------ | ------------------------------------- | -| Objeto | `yarn twenty add object` | `src/objects/.ts` | -| Campo | `yarn twenty add field` | `src/fields/.ts` | -| Logic function | `yarn twenty add logicFunction` | `src/logic-functions/.ts` | -| Front component | `yarn twenty add frontComponent` | `src/front-components/.tsx` | -| Função | `yarn twenty add role` | `src/roles/.ts` | -| Habilidade | `yarn twenty add skill` | `src/skills/.ts` | -| Agente | `yarn twenty add agent` | `src/agents/.ts` | -| Vista | `yarn twenty add view` | `src/views/.ts` | -| Navigation menu item | `yarn twenty add navigationMenuItem` | `src/navigation-menu-items/.ts` | -| Page layout | `yarn twenty add pageLayout` | `src/page-layouts/.ts` | +| Tipo de entidade | Comando | Arquivo gerado | +| ----------------------- | ------------------------------------ | ------------------------------------- | +| Objeto | `yarn twenty add object` | `src/objects/.ts` | +| Campo | `yarn twenty add field` | `src/fields/.ts` | +| Função lógica | `yarn twenty add logicFunction` | `src/logic-functions/.ts` | +| Componente de front-end | `yarn twenty add frontComponent` | `src/front-components/.tsx` | +| Função | `yarn twenty add role` | `src/roles/.ts` | +| Habilidade | `yarn twenty add skill` | `src/skills/.ts` | +| Agente | `yarn twenty add agent` | `src/agents/.ts` | +| Vista | `yarn twenty add view` | `src/views/.ts` | +| Navigation menu item | `yarn twenty add navigationMenuItem` | `src/navigation-menu-items/.ts` | +| Page layout | `yarn twenty add pageLayout` | `src/page-layouts/.ts` | ### What the scaffolder generates diff --git a/packages/twenty-docs/l/ru/developers/extend/apps/building.mdx b/packages/twenty-docs/l/ru/developers/extend/apps/building.mdx index e23ea3164f..0fdc81d5fc 100644 --- a/packages/twenty-docs/l/ru/developers/extend/apps/building.mdx +++ b/packages/twenty-docs/l/ru/developers/extend/apps/building.mdx @@ -760,22 +760,22 @@ export default defineFrontComponent({ #### Поля конфигурации -| Поле | Обязательно | Описание | -| --------------------- | ----------- | ----------------------------------------------------------------------------------- | -| `universalIdentifier` | Да | Стабильный уникальный идентификатор для этого компонента | -| `component` | Да | Функция компонента React | -| `name` | Нет | Отображаемое имя | -| `description` | Нет | Описание того, что делает компонент | -| `isHeadless` | Нет | Set to `true` if the component has no visible UI (see below) | -| `command` | Нет | Register the component as a command (see [command options](#command-options) below) | +| Поле | Обязательно | Описание | +| --------------------- | ----------- | -------------------------------------------------------------------------------------------------- | +| `universalIdentifier` | Да | Стабильный уникальный идентификатор для этого компонента | +| `component` | Да | Функция компонента React | +| `name` | Нет | Отображаемое имя | +| `description` | Нет | Описание того, что делает компонент | +| `isHeadless` | Нет | Установите значение `true`, если у компонента нет видимого пользовательского интерфейса (см. ниже) | +| `command` | Нет | Зарегистрируйте компонент как команду (см. [параметры команды](#command-options) ниже) | -#### Placing a front component on a page +#### Размещение фронт-компонента на странице -Beyond commands, you can embed a front component directly into a record page by adding it as a widget in a **page layout**. See the [definePageLayout](#definepagelayout) section for details. +Помимо команд, вы можете встроить фронт-компонент непосредственно на страницу записи, добавив его как виджет в **макет страницы**. См. раздел [definePageLayout](#definepagelayout) для подробностей. -#### Headless components (`isHeadless: true`) +#### Headless-компоненты (`isHeadless: true`) -Headless components render no visible UI but still run React logic. This is useful for **effect components** — components that perform side effects when mounted, such as syncing data, starting a timer, listening to events, or triggering a notification. +Headless-компоненты не отображают видимый UI, но при этом выполняют логику React. Это полезно для **компонентов-эффектов** — компонентов, которые выполняют побочные эффекты при монтировании, например синхронизацию данных, запуск таймера, прослушивание событий или показ уведомления. ```tsx src/front-components/sync-tracker.tsx import { defineFrontComponent, useRecordId, enqueueSnackbar } from 'twenty-sdk'; @@ -800,11 +800,11 @@ export default defineFrontComponent({ }); ``` -Because the component returns `null`, Twenty skips rendering a container for it — no empty space appears in the layout. The component still has access to all hooks and the host communication API. +Поскольку компонент возвращает `null`, Twenty пропускает рендеринг контейнера для него — в макете не появляется пустое место. Компонент по-прежнему имеет доступ ко всем хукам и API взаимодействия с хостом. -#### Accessing runtime context +#### Доступ к контексту времени выполнения -Inside your component, use SDK hooks to access the current user, record, and component instance: +Внутри вашего компонента используйте хуки SDK для доступа к текущему пользователю, записи и экземпляру компонента: ```tsx src/front-components/record-info.tsx import { @@ -835,47 +835,47 @@ export default defineFrontComponent({ }); ``` -Available hooks: +Доступные хуки: -| Хук | Returns | Описание | -| --------------------------------------------- | ------------------ | ---------------------------------------------------------- | -| `useUserId()` | `string` or `null` | The current user's ID | -| `useRecordId()` | `string` or `null` | The current record's ID (when placed on a record page) | -| `useFrontComponentId()` | `строка` | This component instance's ID | -| `useFrontComponentExecutionContext(selector)` | различается | Access the full execution context with a selector function | +| Хук | Возвращает | Описание | +| --------------------------------------------- | ------------------- | ----------------------------------------------------------------- | +| `useUserId()` | `string` или `null` | ID текущего пользователя | +| `useRecordId()` | `string` или `null` | ID текущей записи (при размещении на странице записи) | +| `useFrontComponentId()` | `строка` | ID этого экземпляра компонента | +| `useFrontComponentExecutionContext(selector)` | различается | Доступ к полному контексту выполнения с помощью функции-селектора | -#### Host communication API +#### API взаимодействия с хостом -Front components can trigger navigation, modals, and notifications using functions from `twenty-sdk`: +Компоненты фронтенда могут вызывать навигацию, модальные окна и уведомления с помощью функций из `twenty-sdk`: -| Функция | Описание | -| ----------------------------------------------- | ----------------------------- | -| `navigate(to, params?, queryParams?, options?)` | Navigate to a page in the app | -| `openSidePanelPage(params)` | Open a side panel | -| `closeSidePanel()` | Закрыть боковую панель | -| `openCommandConfirmationModal(params)` | Show a confirmation dialog | -| `enqueueSnackbar(params)` | Show a toast notification | -| `unmountFrontComponent()` | Unmount the component | -| `updateProgress(progress)` | Update a progress indicator | +| Функция | Описание | +| ----------------------------------------------- | -------------------------------- | +| `navigate(to, params?, queryParams?, options?)` | Перейти на страницу в приложении | +| `openSidePanelPage(params)` | Открыть боковую панель | +| `closeSidePanel()` | Закрыть боковую панель | +| `openCommandConfirmationModal(params)` | Показать диалог подтверждения | +| `enqueueSnackbar(params)` | Показать всплывающее уведомление | +| `unmountFrontComponent()` | Размонтировать компонент | +| `updateProgress(progress)` | Обновить индикатор прогресса | -#### Command options +#### Параметры команды -Adding a `command` field to `defineFrontComponent` registers the component in the command menu (Cmd+K). If `isPinned` is `true`, it also appears as a quick-action button in the top-right corner of the page. +Добавление поля `command` в `defineFrontComponent` регистрирует компонент в меню команд (Cmd+K). Если `isPinned` имеет значение `true`, команда также отображается как кнопка быстрого действия в правом верхнем углу страницы. -| Поле | Обязательно | Описание | -| --------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `universalIdentifier` | Да | Stable unique ID for the command | -| `label` | Да | Full label shown in the command menu (Cmd+K) | -| `shortLabel` | Нет | Shorter label displayed on the pinned quick-action button | -| `icon` | Нет | Icon name displayed next to the label (e.g. `'IconBolt'`, `'IconSend'`) | -| `isPinned` | Нет | When `true`, shows the command as a quick-action button in the top-right corner of the page | -| `availabilityType` | Нет | Controls where the command appears: `'GLOBAL'` (always available), `'RECORD_SELECTION'` (only when records are selected), or `'FALLBACK'` (shown when no other commands match) | -| `availabilityObjectUniversalIdentifier` | Нет | Restrict the command to pages of a specific object type (e.g. only on Company records) | -| `conditionalAvailabilityExpression` | Нет | A boolean expression to dynamically control whether the command is visible (see below) | +| Поле | Обязательно | Описание | +| --------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `universalIdentifier` | Да | Стабильный уникальный идентификатор для команды | +| `label` | Да | Полная метка, отображаемая в меню команд (Cmd+K) | +| `shortLabel` | Нет | Короткая метка, отображаемая на закреплённой кнопке быстрого действия | +| `icon` | Нет | Имя значка, отображаемое рядом с меткой (например, `'IconBolt'`, `'IconSend'`) | +| `isPinned` | Нет | При значении `true` показывает команду как кнопку быстрого действия в правом верхнем углу страницы | +| `availabilityType` | Нет | Определяет, где отображается команда: `'GLOBAL'` (доступна всегда), `'RECORD_SELECTION'` (только при выборе записей) или `'FALLBACK'` (показывается, когда другие команды не подходят) | +| `availabilityObjectUniversalIdentifier` | Нет | Ограничивает команду страницами определённого типа объектов (например, только для записей Company) | +| `conditionalAvailabilityExpression` | Нет | Логическое выражение для динамического управления видимостью команды (см. ниже) | -#### Conditional availability expressions +#### Выражения условной доступности -The `conditionalAvailabilityExpression` field lets you control when a command is visible based on the current page context. Import typed variables and operators from `twenty-sdk` to build expressions: +Поле `conditionalAvailabilityExpression` позволяет управлять видимостью команды в зависимости от текущего контекста страницы. Импортируйте типизированные переменные и операторы из `twenty-sdk`, чтобы составлять выражения: ```tsx import { @@ -904,45 +904,45 @@ export default defineFrontComponent({ }); ``` -**Context variables** — these represent the current state of the page: +**Переменные контекста** — представляют текущее состояние страницы: -| Переменная | Тип | Описание | -| ------------------------------ | --------- | ---------------------------------------------------------------- | -| `pageType` | `строка` | Current page type (e.g. `'RecordIndexPage'`, `'RecordShowPage'`) | -| `isInSidePanel` | `boolean` | Whether the component is rendered in a side panel | -| `numberOfSelectedRecords` | `number` | Number of currently selected records | -| `isSelectAll` | `boolean` | Whether "select all" is active | -| `selectedRecords` | `array` | The selected record objects | -| `favoriteRecordIds` | `array` | IDs of favorited records | -| `objectPermissions` | `object` | Permissions for the current object type | -| `targetObjectReadPermissions` | `object` | Read permissions for the target object | -| `targetObjectWritePermissions` | `object` | Write permissions for the target object | -| `featureFlags` | `object` | Active feature flags | -| `objectMetadataItem` | `object` | Metadata of the current object type | -| `hasAnySoftDeleteFilterOnView` | `boolean` | Whether the current view has a soft-delete filter | +| Переменная | Тип | Описание | +| ------------------------------ | --------- | ------------------------------------------------------------------------ | +| `pageType` | `строка` | Текущий тип страницы (например, `'RecordIndexPage'`, `'RecordShowPage'`) | +| `isInSidePanel` | `boolean` | Указывает, рендерится ли компонент в боковой панели | +| `numberOfSelectedRecords` | `number` | Количество выбранных в данный момент записей | +| `isSelectAll` | `boolean` | Активен ли режим "выбрать все" | +| `selectedRecords` | `массив` | Объекты выбранных записей | +| `favoriteRecordIds` | `массив` | ID избранных записей | +| `objectPermissions` | `object` | Разрешения для текущего типа объекта | +| `targetObjectReadPermissions` | `object` | Права на чтение для целевого объекта | +| `targetObjectWritePermissions` | `object` | Права на запись для целевого объекта | +| `featureFlags` | `object` | Активные флаги функций | +| `objectMetadataItem` | `object` | Метаданные текущего типа объекта | +| `hasAnySoftDeleteFilterOnView` | `boolean` | Есть ли у текущего представления фильтр мягкого удаления | -**Operators** — combine variables into boolean expressions: +**Операторы** — комбинируют переменные в логические выражения: -| Operator | Описание | -| ----------------------------------- | ----------------------------------------------------------------- | -| `isDefined(value)` | `true` if the value is not null/undefined | -| `isNonEmptyString(value)` | `true` if the value is a non-empty string | -| `includes(array, value)` | `true` if the array contains the value | -| `includesEvery(array, prop, value)` | `true` if every item's property includes the value | -| `every(array, prop)` | `true` if the property is truthy on every item | -| `everyDefined(array, prop)` | `true` if the property is defined on every item | -| `everyEquals(array, prop, value)` | `true` if the property equals the value on every item | -| `some(array, prop)` | `true` if the property is truthy on at least one item | -| `someDefined(array, prop)` | `true` if the property is defined on at least one item | -| `someEquals(array, prop, value)` | `true` if the property equals the value on at least one item | -| `someNonEmptyString(array, prop)` | `true` if the property is a non-empty string on at least one item | -| `none(array, prop)` | `true` if the property is falsy on every item | -| `noneDefined(array, prop)` | `true` if the property is undefined on every item | -| `noneEquals(array, prop, value)` | `true` if the property does not equal the value on any item | +| Оператор | Описание | +| ----------------------------------- | ------------------------------------------------------------------------- | +| `isDefined(value)` | `true`, если значение не null/undefined | +| `isNonEmptyString(value)` | `true`, если значение — непустая строка | +| `includes(array, value)` | `true`, если массив содержит значение | +| `includesEvery(array, prop, value)` | `true`, если свойство каждого элемента включает значение | +| `every(array, prop)` | `true`, если свойство истинно для каждого элемента | +| `everyDefined(array, prop)` | `true`, если свойство определено у каждого элемента | +| `everyEquals(array, prop, value)` | `true`, если свойство равно значению у каждого элемента | +| `some(array, prop)` | `true`, если свойство истинно хотя бы у одного элемента | +| `someDefined(array, prop)` | `true`, если свойство определено хотя бы у одного элемента | +| `someEquals(array, prop, value)` | `true`, если свойство равно значению хотя бы у одного элемента | +| `someNonEmptyString(array, prop)` | `true`, если свойство является непустой строкой хотя бы у одного элемента | +| `none(array, prop)` | `true`, если свойство ложно для каждого элемента | +| `noneDefined(array, prop)` | `true`, если свойство не определено ни у одного элемента | +| `noneEquals(array, prop, value)` | `true`, если свойство не равно значению ни у одного элемента | -#### Public assets +#### Публичные ресурсы -Front components can access files from the app's `public/` directory using `getPublicAssetUrl`: +Компоненты фронтенда могут получать доступ к файлам из каталога приложения `public/` с помощью `getPublicAssetUrl`: ```tsx import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk'; @@ -956,18 +956,18 @@ export default defineFrontComponent({ }); ``` -See the [public assets section](#accessing-public-assets-with-getpublicasseturl) for details. +См. [раздел о публичных ресурсах](#accessing-public-assets-with-getpublicasseturl) для подробностей. #### Стилизация -Front components support multiple styling approaches. You can use: +Компоненты фронтенда поддерживают несколько подходов к стилизации. Вы можете использовать: -* **Inline styles** — `style={{ color: 'red' }}` -* **Twenty UI components** — import from `twenty-sdk/ui` (Button, Tag, Status, Chip, Avatar, and more) -* **Emotion** — CSS-in-JS with `@emotion/react` -* **Styled-components** — `styled.div` patterns -* **Tailwind CSS** — utility classes -* **Any CSS-in-JS library** compatible with React +* **Встроенные стили** — `style={{ color: 'red' }}` +* **Компоненты Twenty UI** — импорт из `twenty-sdk/ui` (Button, Tag, Status, Chip, Avatar и другие) +* **Emotion** — CSS-in-JS с `@emotion/react` +* **Styled-components** — паттерны `styled.div` +* **Tailwind CSS** — утилитарные классы +* **Любая библиотека CSS-in-JS**, совместимая с React ```tsx import { defineFrontComponent } from 'twenty-sdk'; @@ -1021,9 +1021,9 @@ export default defineSkill({ * `description` (необязательно) предоставляет дополнительный контекст о назначении навыка. - + -Agents are AI assistants that live inside your workspace. Use `defineAgent()` to create agents with a custom system prompt: +Агенты — это ИИ-помощники, работающие в вашем рабочем пространстве. Используйте `defineAgent()` для создания агентов с пользовательским системным промптом: ```ts src/agents/example-agent.ts import { defineAgent } from 'twenty-sdk'; @@ -1039,17 +1039,17 @@ export default defineAgent({ ``` Основные моменты: -* `name` is the unique identifier string for the agent (kebab-case recommended). -* `label` is the display name shown in the UI. -* `prompt` is the system prompt that defines the agent's behavior. -* `description` (optional) provides context about what the agent does. +* `name` — уникальная строка-идентификатор агента (рекомендуется kebab-case). +* `label` — отображаемое имя, показываемое в UI. +* `prompt` — это системный промпт, определяющий поведение агента. +* `description` (необязательно) предоставляет контекст о том, что делает агент. * `icon` (необязательно) задаёт значок, отображаемый в UI. -* `modelId` (optional) overrides the default AI model used by the agent. +* `modelId` (необязательно) переопределяет модель ИИ по умолчанию, используемую агентом. -Views are saved configurations for how records of an object are displayed — including which fields are visible, their order, and any filters or groups applied. Use `defineView()` to ship pre-configured views with your app: +Представления — это сохранённые конфигурации отображения записей объекта: какие поля видны, их порядок, а также применённые фильтры и группы. Используйте `defineView()` для поставки преднастроенных представлений вместе с вашим приложением: ```ts src/views/example-view.ts import { defineView, ViewKey } from 'twenty-sdk'; @@ -1076,16 +1076,16 @@ export default defineView({ ``` Основные моменты: -* `objectUniversalIdentifier` specifies which object this view applies to. -* `key` determines the view type (e.g., `ViewKey.INDEX` for the main list view). -* `fields` controls which columns appear and their order. Each field references a `fieldMetadataUniversalIdentifier`. -* You can also define `filters`, `filterGroups`, `groups`, and `fieldGroups` for more advanced configurations. -* `position` controls the ordering when multiple views exist for the same object. +* `objectUniversalIdentifier` указывает, к какому объекту применяется это представление. +* `key` определяет тип представления (например, `ViewKey.INDEX` для основного списка). +* `fields` управляет тем, какие столбцы отображаются и в каком порядке. Каждое поле ссылается на `fieldMetadataUniversalIdentifier`. +* Также вы можете определить `filters`, `filterGroups`, `groups` и `fieldGroups` для более продвинутых конфигураций. +* `position` управляет порядком, когда для одного и того же объекта существует несколько представлений. -Navigation menu items add custom entries to the workspace sidebar. Use `defineNavigationMenuItem()` to link to views, external URLs, or objects: +Пункты навигационного меню добавляют пользовательские элементы в боковую панель рабочего пространства. Используйте `defineNavigationMenuItem()` для ссылок на представления, внешние URL или объекты: ```ts src/navigation-menu-items/example-navigation-menu-item.ts import { defineNavigationMenuItem, NavigationMenuItemType } from 'twenty-sdk'; @@ -1103,15 +1103,15 @@ export default defineNavigationMenuItem({ ``` Основные моменты: -* `type` determines what the menu item links to: `NavigationMenuItemType.VIEW` for a saved view, or `NavigationMenuItemType.LINK` for an external URL. -* For view links, set `viewUniversalIdentifier`. For external links, set `link`. -* `position` controls the ordering in the sidebar. -* `icon` and `color` (optional) customize the appearance. +* `type` определяет, на что ссылается пункт меню: `NavigationMenuItemType.VIEW` для сохранённого представления или `NavigationMenuItemType.LINK` для внешнего URL. +* Для ссылок на представления укажите `viewUniversalIdentifier`. Для внешних ссылок укажите `link`. +* `position` управляет порядком в боковой панели. +* `icon` и `color` (необязательно) настраивают внешний вид. - + -Page layouts let you customize how a record detail page looks — which tabs appear, what widgets are inside each tab, and how they are arranged. Use `definePageLayout()` to ship custom layouts with your app: +Макеты страниц позволяют настраивать вид страницы с деталями записи: какие вкладки отображаются, какие виджеты внутри каждой вкладки и как они расположены. Используйте `definePageLayout()` для поставки пользовательских макетов вместе с вашим приложением: ```ts src/page-layouts/example-record-page-layout.ts import { definePageLayout, PageLayoutTabLayoutMode } from 'twenty-sdk'; @@ -1148,33 +1148,33 @@ export default definePageLayout({ ``` Основные моменты: -* `type` is typically `'RECORD_PAGE'` to customize the detail view of a specific object. -* `objectUniversalIdentifier` specifies which object this layout applies to. -* Each `tab` defines a section of the page with a `title`, `position`, and `layoutMode` (`CANVAS` for free-form layout). -* Each `widget` inside a tab can render a front component, a relation list, or other built-in widget types. -* `position` on tabs controls their order. Use higher values (e.g., 50) to place custom tabs after built-in ones. +* `type` обычно равен `'RECORD_PAGE'` для настройки детального представления конкретного объекта. +* `objectUniversalIdentifier` указывает, к какому объекту применяется этот макет. +* Каждая `tab` определяет раздел страницы с `title`, `position` и `layoutMode` (`CANVAS` для свободного макета). +* Каждый `widget` внутри вкладки может отображать компонент фронтенда, список связей или другие встроенные типы виджетов. +* `position` у вкладок управляет их порядком. Используйте большие значения (например, 50), чтобы разместить пользовательские вкладки после встроенных. -## Public assets (`public/` folder) +## Публичные ресурсы (папка `public/`) -The `public/` folder at the root of your app holds static files — images, icons, fonts, or any other assets your app needs at runtime. These files are automatically included in builds, synced during dev mode, and uploaded to the server. +Папка `public/` в корне вашего приложения содержит статические файлы — изображения, значки, шрифты и любые другие ресурсы, необходимые вашему приложению во время выполнения. Эти файлы автоматически включаются в сборки, синхронизируются в режиме разработки и загружаются на сервер. -Files placed in `public/` are: +Файлы, размещённые в `public/`, являются: -* **Publicly accessible** — once synced to the server, assets are served at a public URL. No authentication is needed to access them. -* **Available in front components** — use asset URLs to display images, icons, or any media inside your React components. -* **Available in logic functions** — reference asset URLs in emails, API responses, or any server-side logic. -* **Used for marketplace metadata** — the `logoUrl` and `screenshots` fields in `defineApplication()` reference files from this folder (e.g., `public/logo.png`). These are displayed in the marketplace when your app is published. -* **Auto-synced in dev mode** — when you add, update, or delete a file in `public/`, it is synced to the server automatically. No restart needed. -* **Included in builds** — `yarn twenty build` bundles all public assets into the distribution output. +* **Публично доступными** — после синхронизации с сервером ресурсы доступны по публичному URL. Для доступа к ним аутентификация не требуется. +* **Доступными в компонентах фронтенда** — используйте URL ресурсов для отображения изображений, значков или любого медиа внутри ваших компонентов React. +* **Доступными в логических функциях** — используйте URL ресурсов в письмах, ответах API или любой серверной логике. +* **Используются для метаданных маркетплейса** — поля `logoUrl` и `screenshots` в `defineApplication()` ссылаются на файлы из этой папки (например, `public/logo.png`). Они отображаются в маркетплейсе при публикации вашего приложения. +* **Автосинхронизация в режиме разработки** — когда вы добавляете, обновляете или удаляете файл в `public/`, он автоматически синхронизируется с сервером. Перезапуск не требуется. +* **Включены в сборки** — `yarn twenty build` упаковывает все публичные ресурсы в выходной дистрибутив. -### Accessing public assets with `getPublicAssetUrl` +### Доступ к публичным ресурсам с помощью `getPublicAssetUrl` -Use the `getPublicAssetUrl` helper from `twenty-sdk` to get the full URL of a file in your `public/` directory. It works in both **logic functions** and **front components**. +Используйте хелпер `getPublicAssetUrl` из `twenty-sdk`, чтобы получить полный URL файла в каталоге `public/` вашего приложения. Он работает как в **логических функциях**, так и в **компонентах фронтенда**. -**In a logic function:** +**В логической функции:** ```ts src/logic-functions/send-invoice.ts import { defineLogicFunction, getPublicAssetUrl } from 'twenty-sdk'; @@ -1199,7 +1199,7 @@ export default defineLogicFunction({ }); ``` -**In a front component:** +**В компоненте фронтенда:** ```tsx src/front-components/company-card.tsx import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk'; @@ -1211,19 +1211,19 @@ export default defineFrontComponent(() => { }); ``` -The `path` argument is relative to your app's `public/` folder. Both `getPublicAssetUrl('logo.png')` and `getPublicAssetUrl('public/logo.png')` resolve to the same URL — the `public/` prefix is stripped automatically if present. +Аргумент `path` задаётся относительно папки `public/` вашего приложения. И `getPublicAssetUrl('logo.png')`, и `getPublicAssetUrl('public/logo.png')` приводят к одному и тому же URL — префикс `public/`, если он есть, удаляется автоматически. -## Using npm packages +## Использование пакетов npm -You can install and use any npm package in your app. Both logic functions and front components are bundled with [esbuild](https://esbuild.github.io/), which inlines all dependencies into the output — no `node_modules` are needed at runtime. +Вы можете устанавливать и использовать любые пакеты npm в своём приложении. И логические функции, и компоненты фронтенда собираются с помощью [esbuild](https://esbuild.github.io/), который встраивает все зависимости в выходной файл — каталоги `node_modules` во время выполнения не нужны. -### Installing a package +### Установка пакета ```bash filename="Terminal" yarn add axios ``` -Then import it in your code: +Затем импортируйте его в своём коде: ```ts src/logic-functions/fetch-data.ts import { defineLogicFunction } from 'twenty-sdk'; @@ -1244,7 +1244,7 @@ export default defineLogicFunction({ }); ``` -The same works for front components: +То же самое работает для компонентов фронтенда: ```tsx src/front-components/chart.tsx import { defineFrontComponent } from 'twenty-sdk'; @@ -1261,27 +1261,27 @@ export default defineFrontComponent({ }); ``` -### How bundling works +### Как работает бандлинг -The build step (`yarn twenty dev` or `yarn twenty build`) uses esbuild to produce a single self-contained file per logic function and per front component. All imported packages are inlined into the bundle. +Этап сборки (`yarn twenty dev` или `yarn twenty build`) использует esbuild для создания одного самодостаточного файла на каждую логическую функцию и на каждый компонент фронтенда. Все импортированные пакеты встроены в бандл. -**Logic functions** run in a Node.js environment. Node built-in modules (`fs`, `path`, `crypto`, `http`, etc.) are available and do not need to be installed. +**Логические функции** выполняются в среде Node.js. Встроенные модули Node (`fs`, `path`, `crypto`, `http` и т. д.) доступны и не требуют установки. -**Front components** run in a Web Worker. Node built-in modules are **not** available — only browser APIs and npm packages that work in a browser environment. +**Компоненты фронтенда** выполняются в Web Worker. Встроенные модули Node недоступны — доступны только браузерные API и пакеты npm, работающие в браузерной среде. -Both environments have `twenty-client-sdk/core` and `twenty-client-sdk/metadata` available as pre-provided modules — these are not bundled but resolved at runtime by the server. +В обеих средах доступны как предварительно предоставленные модули `twenty-client-sdk/core` и `twenty-client-sdk/metadata` — они не включаются в бандл, а подставляются сервером во время выполнения. -## Scaffolding entities with `yarn twenty add` +## Создание заготовок сущностей с помощью `yarn twenty add` -Instead of creating entity files by hand, you can use the interactive scaffolder: +Вместо ручного создания файлов сущностей вы можете использовать интерактивный генератор: ```bash filename="Terminal" yarn twenty add ``` -This prompts you to pick an entity type and walks you through the required fields. It generates a ready-to-use file with a stable `universalIdentifier` and the correct `defineEntity()` call. +Он предложит выбрать тип сущности и проведёт вас по обязательным полям. Он генерирует готовый к использованию файл со стабильным `universalIdentifier` и корректным вызовом `defineEntity()`. -You can also pass the entity type directly to skip the first prompt: +Вы также можете передать тип сущности напрямую, чтобы пропустить первый запрос: ```bash filename="Terminal" yarn twenty add object @@ -1289,14 +1289,14 @@ yarn twenty add logicFunction yarn twenty add frontComponent ``` -### Available entity types +### Доступные типы сущностей -| Тип сущности | Команда | Generated file | +| Тип сущности | Команда | Сгенерированный файл | | -------------------- | ------------------------------------ | ------------------------------------- | | Объект | `yarn twenty add object` | `src/objects/.ts` | | Поле | `yarn twenty add field` | `src/fields/.ts` | -| Logic function | `yarn twenty add logicFunction` | `src/logic-functions/.ts` | -| Front component | `yarn twenty add frontComponent` | `src/front-components/.tsx` | +| Логическая функция | `yarn twenty add logicFunction` | `src/logic-functions/.ts` | +| Компонент фронтенда | `yarn twenty add frontComponent` | `src/front-components/.tsx` | | Роль | `yarn twenty add role` | `src/roles/.ts` | | Навык | `yarn twenty add skill` | `src/skills/.ts` | | Агент | `yarn twenty add agent` | `src/agents/.ts` | diff --git a/packages/twenty-docs/l/tr/developers/extend/apps/building.mdx b/packages/twenty-docs/l/tr/developers/extend/apps/building.mdx index 8badf82f35..68a5a711e3 100644 --- a/packages/twenty-docs/l/tr/developers/extend/apps/building.mdx +++ b/packages/twenty-docs/l/tr/developers/extend/apps/building.mdx @@ -719,7 +719,7 @@ yarn twenty exec --postInstall #### Basit örnek -Bir ön bileşeni çalışırken görmenin en hızlı yolu, onu bir **komut** olarak kaydetmektir. `isPinned: true` ile bir `command` alanı eklemek, sayfanın sağ üst köşesinde hızlı işlem düğmesi olarak görünmesini sağlar — herhangi bir sayfa düzenine gerek yoktur: +Bir ön uç bileşenini çalışırken görmenin en hızlı yolu, onu bir komut olarak kaydetmektir. `isPinned: true` ile bir `command` alanı eklemek, sayfanın sağ üst köşesinde hızlı işlem düğmesi olarak görünmesini sağlar — herhangi bir sayfa düzenine gerek yoktur: ```tsx src/front-components/hello-world.tsx import { defineFrontComponent } from 'twenty-sdk'; @@ -761,22 +761,22 @@ Bileşeni satır içi işlemek için üzerine tıklayın. #### Yapılandırma alanları -| Alan | Zorunlu | Açıklama | -| --------------------- | ------- | ----------------------------------------------------------------------------------- | -| `universalIdentifier` | Evet | Bu bileşen için kararlı benzersiz kimlik | -| `component` | Evet | Bir React bileşen fonksiyonu | -| `name` | Hayır | Görünen ad | -| `description` | Hayır | Bileşenin ne yaptığına dair açıklama | -| `isHeadless` | Hayır | Set to `true` if the component has no visible UI (see below) | -| `command` | Hayır | Register the component as a command (see [command options](#command-options) below) | +| Alan | Zorunlu | Açıklama | +| --------------------- | ------- | ------------------------------------------------------------------------------------------ | +| `universalIdentifier` | Evet | Bu bileşen için kalıcı benzersiz kimlik | +| `component` | Evet | Bir React bileşen fonksiyonu | +| `name` | Hayır | Görünen Ad | +| `description` | Hayır | Bileşenin ne yaptığına dair açıklama | +| `isHeadless` | Hayır | Bileşenin görünür bir kullanıcı arayüzü yoksa `true` olarak ayarlayın (aşağıya bakın) | +| `command` | Hayır | Bileşeni bir komut olarak kaydedin (aşağıda [komut seçeneklerine](#command-options) bakın) | -#### Placing a front component on a page +#### Bir ön uç bileşenini bir sayfaya yerleştirme -Beyond commands, you can embed a front component directly into a record page by adding it as a widget in a **page layout**. See the [definePageLayout](#definepagelayout) section for details. +Komutların ötesinde, bir ön uç bileşenini bir **sayfa düzeninde** widget olarak ekleyerek doğrudan bir kayıt sayfasına gömebilirsiniz. Ayrıntılar için [definePageLayout](#definepagelayout) bölümüne bakın. -#### Headless components (`isHeadless: true`) +#### Headless bileşenler (`isHeadless: true`) -Headless components render no visible UI but still run React logic. This is useful for **effect components** — components that perform side effects when mounted, such as syncing data, starting a timer, listening to events, or triggering a notification. +Headless bileşenler görünür bir kullanıcı arayüzü oluşturmaz ancak yine de React mantığını çalıştırır. Bu, **etki bileşenleri** için kullanışlıdır — bağlandıklarında veri senkronizasyonu yapmak, bir zamanlayıcı başlatmak, olayları dinlemek veya bir bildirimi tetiklemek gibi yan etkiler gerçekleştiren bileşenler. ```tsx src/front-components/sync-tracker.tsx import { defineFrontComponent, useRecordId, enqueueSnackbar } from 'twenty-sdk'; @@ -801,11 +801,11 @@ export default defineFrontComponent({ }); ``` -Because the component returns `null`, Twenty skips rendering a container for it — no empty space appears in the layout. The component still has access to all hooks and the host communication API. +Bileşen `null` döndürdüğü için, Twenty bunun için bir kapsayıcı oluşturmayı atlar — düzende boş alan görünmez. Bileşen yine de tüm hook'lara ve host iletişim API'sine erişime sahiptir. -#### Accessing runtime context +#### Çalışma zamanı bağlamına erişme -Inside your component, use SDK hooks to access the current user, record, and component instance: +Bileşeninizin içinde, geçerli kullanıcıya, kayda ve bileşen örneğine erişmek için SDK hook'larını kullanın: ```tsx src/front-components/record-info.tsx import { @@ -836,47 +836,47 @@ export default defineFrontComponent({ }); ``` -Available hooks: +Kullanılabilir hook'lar: -| Hook | Returns | Açıklama | -| --------------------------------------------- | ------------------ | ---------------------------------------------------------- | -| `useUserId()` | `string` or `null` | The current user's ID | -| `useRecordId()` | `string` or `null` | The current record's ID (when placed on a record page) | -| `useFrontComponentId()` | `string` | This component instance's ID | -| `useFrontComponentExecutionContext(selector)` | değişir | Access the full execution context with a selector function | +| Hook | Döndürür | Açıklama | +| --------------------------------------------- | -------------------- | ------------------------------------------------------------- | +| `useUserId()` | `string` veya `null` | Geçerli kullanıcının ID'si | +| `useRecordId()` | `string` veya `null` | Geçerli kaydın ID'si (bir kayıt sayfasına yerleştirildiğinde) | +| `useFrontComponentId()` | `string` | Bu bileşen örneğinin ID'si | +| `useFrontComponentExecutionContext(selector)` | değişir | Bir seçici işlevle tam yürütme bağlamına erişin | -#### Host communication API +#### Host iletişim API'si -Front components can trigger navigation, modals, and notifications using functions from `twenty-sdk`: +Ön uç bileşenleri, `twenty-sdk`'deki işlevleri kullanarak gezinmeyi, modalları ve bildirimleri tetikleyebilir: -| Fonksiyon | Açıklama | -| ----------------------------------------------- | ----------------------------- | -| `navigate(to, params?, queryParams?, options?)` | Navigate to a page in the app | -| `openSidePanelPage(params)` | Open a side panel | -| `closeSidePanel()` | Yan paneli kapat | -| `openCommandConfirmationModal(params)` | Show a confirmation dialog | -| `enqueueSnackbar(params)` | Show a toast notification | -| `unmountFrontComponent()` | Unmount the component | -| `updateProgress(progress)` | Update a progress indicator | +| Fonksiyon | Açıklama | +| ----------------------------------------------- | ---------------------------------- | +| `navigate(to, params?, queryParams?, options?)` | Uygulamada bir sayfaya git | +| `openSidePanelPage(params)` | Bir yan panel aç | +| `closeSidePanel()` | Yan paneli kapat | +| `openCommandConfirmationModal(params)` | Bir onay iletişim kutusu göster | +| `enqueueSnackbar(params)` | Bir toast bildirimi göster | +| `unmountFrontComponent()` | Bileşeni kaldır (unmount) | +| `updateProgress(progress)` | Bir ilerleme göstergesini güncelle | -#### Command options +#### Komut seçenekleri -Adding a `command` field to `defineFrontComponent` registers the component in the command menu (Cmd+K). If `isPinned` is `true`, it also appears as a quick-action button in the top-right corner of the page. +`defineFrontComponent` içine bir `command` alanı eklemek, bileşeni komut menüsüne (Cmd+K) kaydeder. `isPinned` `true` ise, sayfanın sağ üst köşesinde bir hızlı işlem düğmesi olarak da görünür. -| Alan | Zorunlu | Açıklama | -| --------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `universalIdentifier` | Evet | Stable unique ID for the command | -| `label` | Evet | Full label shown in the command menu (Cmd+K) | -| `shortLabel` | Hayır | Shorter label displayed on the pinned quick-action button | -| `icon` | Hayır | Icon name displayed next to the label (e.g. `'IconBolt'`, `'IconSend'`) | -| `isPinned` | Hayır | When `true`, shows the command as a quick-action button in the top-right corner of the page | -| `availabilityType` | Hayır | Controls where the command appears: `'GLOBAL'` (always available), `'RECORD_SELECTION'` (only when records are selected), or `'FALLBACK'` (shown when no other commands match) | -| `availabilityObjectUniversalIdentifier` | Hayır | Restrict the command to pages of a specific object type (e.g. only on Company records) | -| `conditionalAvailabilityExpression` | Hayır | A boolean expression to dynamically control whether the command is visible (see below) | +| Alan | Zorunlu | Açıklama | +| --------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `universalIdentifier` | Evet | Komut için kararlı benzersiz kimlik | +| `label` | Evet | Komut menüsünde (Cmd+K) gösterilen tam etiket | +| `shortLabel` | Hayır | Sabitlenmiş hızlı işlem düğmesinde görüntülenen daha kısa etiket | +| `icon` | Hayır | Etiketin yanında görüntülenen simge adı (örn. `'IconBolt'`, `'IconSend'`) | +| `isPinned` | Hayır | `true` olduğunda, komutu sayfanın sağ üst köşesinde bir hızlı işlem düğmesi olarak gösterir | +| `availabilityType` | Hayır | Komutun nerede görüneceğini kontrol eder: `'GLOBAL'` (her zaman kullanılabilir), `'RECORD_SELECTION'` (yalnızca kayıtlar seçiliyken) veya `'FALLBACK'` (başka hiçbir komut eşleşmediğinde gösterilir) | +| `availabilityObjectUniversalIdentifier` | Hayır | Komutu belirli bir nesne türünün sayfalarıyla sınırlandırın (örn. yalnızca Company kayıtlarında) | +| `conditionalAvailabilityExpression` | Hayır | Komutun görünür olup olmadığını dinamik olarak kontrol eden bir boolean ifade (aşağıya bakın) | -#### Conditional availability expressions +#### Koşullu kullanılabilirlik ifadeleri -The `conditionalAvailabilityExpression` field lets you control when a command is visible based on the current page context. Import typed variables and operators from `twenty-sdk` to build expressions: +`conditionalAvailabilityExpression` alanı, geçerli sayfa bağlamına göre bir komutun ne zaman görünür olacağını kontrol etmenizi sağlar. İfadeler oluşturmak için `twenty-sdk`'den türlendirilmiş değişkenleri ve operatörleri içe aktarın: ```tsx import { @@ -905,45 +905,45 @@ export default defineFrontComponent({ }); ``` -**Context variables** — these represent the current state of the page: +**Bağlam değişkenleri** — bunlar sayfanın mevcut durumunu temsil eder: -| Değişken | Tür | Açıklama | -| ------------------------------ | --------- | ---------------------------------------------------------------- | -| `pageType` | `string` | Current page type (e.g. `'RecordIndexPage'`, `'RecordShowPage'`) | -| `isInSidePanel` | `boolean` | Whether the component is rendered in a side panel | -| `numberOfSelectedRecords` | `number` | Number of currently selected records | -| `isSelectAll` | `boolean` | Whether "select all" is active | -| `selectedRecords` | `array` | The selected record objects | -| `favoriteRecordIds` | `array` | IDs of favorited records | -| `objectPermissions` | `object` | Permissions for the current object type | -| `targetObjectReadPermissions` | `object` | Read permissions for the target object | -| `targetObjectWritePermissions` | `object` | Write permissions for the target object | -| `featureFlags` | `object` | Active feature flags | -| `objectMetadataItem` | `object` | Metadata of the current object type | -| `hasAnySoftDeleteFilterOnView` | `boolean` | Whether the current view has a soft-delete filter | +| Değişken | Tür | Açıklama | +| ------------------------------ | --------- | ----------------------------------------------------------------- | +| `pageType` | `string` | Geçerli sayfa türü (örn. `'RecordIndexPage'`, `'RecordShowPage'`) | +| `isInSidePanel` | `boolean` | Bileşenin bir yan panelde oluşturulup oluşturulmadığı | +| `numberOfSelectedRecords` | `number` | Şu anda seçili kayıt sayısı | +| `isSelectAll` | `boolean` | "tümünü seç" seçeneğinin etkin olup olmadığı | +| `selectedRecords` | `array` | Seçili kayıt nesneleri | +| `favoriteRecordIds` | `array` | Favorilere eklenen kayıtların ID'leri | +| `objectPermissions` | `object` | Geçerli nesne türü için izinler | +| `targetObjectReadPermissions` | `object` | Hedef nesne için okuma izinleri | +| `targetObjectWritePermissions` | `object` | Hedef nesne için yazma izinleri | +| `featureFlags` | `object` | Etkin özellik bayrakları | +| `objectMetadataItem` | `object` | Geçerli nesne türünün üst verileri | +| `hasAnySoftDeleteFilterOnView` | `boolean` | Geçerli görünümde soft-delete filtresi olup olmadığı | -**Operators** — combine variables into boolean expressions: +**Operatörler** — değişkenleri boolean ifadelere dönüştürmek için birleştirin: -| Operator | Açıklama | -| ----------------------------------- | ----------------------------------------------------------------- | -| `isDefined(value)` | `true` if the value is not null/undefined | -| `isNonEmptyString(value)` | `true` if the value is a non-empty string | -| `includes(array, value)` | `true` if the array contains the value | -| `includesEvery(array, prop, value)` | `true` if every item's property includes the value | -| `every(array, prop)` | `true` if the property is truthy on every item | -| `everyDefined(array, prop)` | `true` if the property is defined on every item | -| `everyEquals(array, prop, value)` | `true` if the property equals the value on every item | -| `some(array, prop)` | `true` if the property is truthy on at least one item | -| `someDefined(array, prop)` | `true` if the property is defined on at least one item | -| `someEquals(array, prop, value)` | `true` if the property equals the value on at least one item | -| `someNonEmptyString(array, prop)` | `true` if the property is a non-empty string on at least one item | -| `none(array, prop)` | `true` if the property is falsy on every item | -| `noneDefined(array, prop)` | `true` if the property is undefined on every item | -| `noneEquals(array, prop, value)` | `true` if the property does not equal the value on any item | +| Operatör | Açıklama | +| ----------------------------------- | --------------------------------------------------------- | +| `isDefined(value)` | Değer null/undefined değilse `true` | +| `isNonEmptyString(value)` | Değer boş olmayan bir string ise `true` | +| `includes(array, value)` | Dizi değeri içeriyorsa `true` | +| `includesEvery(array, prop, value)` | Her bir öğenin özelliği değeri içeriyorsa `true` | +| `every(array, prop)` | Özellik her öğede truthy ise `true` | +| `everyDefined(array, prop)` | Özellik her öğede tanımlıysa `true` | +| `everyEquals(array, prop, value)` | Özellik her öğede değere eşitse `true` | +| `some(array, prop)` | Özellik en az bir öğede truthy ise `true` | +| `someDefined(array, prop)` | Özellik en az bir öğede tanımlıysa `true` | +| `someEquals(array, prop, value)` | Özellik en az bir öğede değere eşitse `true` | +| `someNonEmptyString(array, prop)` | Özellik en az bir öğede boş olmayan bir string ise `true` | +| `none(array, prop)` | Özellik her öğede falsy ise `true` | +| `noneDefined(array, prop)` | Özellik her öğede tanımsızsa `true` | +| `noneEquals(array, prop, value)` | Özellik hiçbir öğede değere eşit değilse `true` | -#### Public assets +#### Genel varlıklar -Front components can access files from the app's `public/` directory using `getPublicAssetUrl`: +Ön uç bileşenleri, `getPublicAssetUrl` kullanarak uygulamanın `public/` dizinindeki dosyalara erişebilir: ```tsx import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk'; @@ -957,18 +957,18 @@ export default defineFrontComponent({ }); ``` -See the [public assets section](#accessing-public-assets-with-getpublicasseturl) for details. +Ayrıntılar için [genel varlıklar bölümüne](#accessing-public-assets-with-getpublicasseturl) bakın. #### Stil -Front components support multiple styling approaches. You can use: +Ön uç bileşenleri birden fazla biçimlendirme yaklaşımını destekler. Şunları kullanabilirsiniz: -* **Inline styles** — `style={{ color: 'red' }}` -* **Twenty UI components** — import from `twenty-sdk/ui` (Button, Tag, Status, Chip, Avatar, and more) -* **Emotion** — CSS-in-JS with `@emotion/react` -* **Styled-components** — `styled.div` patterns -* **Tailwind CSS** — utility classes -* **Any CSS-in-JS library** compatible with React +* **Satır içi stiller** — `style={{ color: 'red' }}` +* **Twenty UI bileşenleri** — `twenty-sdk/ui` içinden içe aktarın (Button, Tag, Status, Chip, Avatar ve daha fazlası) +* **Emotion** — `@emotion/react` ile CSS-in-JS +* **Styled-components** — `styled.div` kalıpları +* **Tailwind CSS** — yardımcı sınıflar +* **React ile uyumlu herhangi bir CSS-in-JS kitaplığı** ```tsx import { defineFrontComponent } from 'twenty-sdk'; @@ -1022,9 +1022,9 @@ export default defineSkill({ * `description` (isteğe bağlı), yeteneğin amacı hakkında ek bağlam sağlar. - + -Agents are AI assistants that live inside your workspace. Use `defineAgent()` to create agents with a custom system prompt: +Ajanlar, çalışma alanınız içinde bulunan yapay zekâ asistanlarıdır. Özel bir sistem istemiyle ajanlar oluşturmak için `defineAgent()` kullanın: ```ts src/agents/example-agent.ts import { defineAgent } from 'twenty-sdk'; @@ -1040,17 +1040,17 @@ export default defineAgent({ ``` Önemli noktalar: -* `name` is the unique identifier string for the agent (kebab-case recommended). -* `label` is the display name shown in the UI. -* `prompt` is the system prompt that defines the agent's behavior. -* `description` (optional) provides context about what the agent does. +* `name`, ajan için benzersiz bir tanımlayıcı dizedir (kebab-case önerilir). +* `label`, UI'de gösterilen görünen addır. +* `prompt`, ajanın davranışını tanımlayan sistem istemidir. +* `description` (isteğe bağlı), ajanın ne yaptığı hakkında bağlam sağlar. * `icon` (isteğe bağlı), UI'de gösterilen simgeyi ayarlar. -* `modelId` (optional) overrides the default AI model used by the agent. +* `modelId` (isteğe bağlı), ajanın kullandığı varsayılan yapay zekâ modelini geçersiz kılar. -Views are saved configurations for how records of an object are displayed — including which fields are visible, their order, and any filters or groups applied. Use `defineView()` to ship pre-configured views with your app: +Görünümler, bir nesnenin kayıtlarının nasıl görüntüleneceğine ilişkin kaydedilmiş yapılandırmalardır — hangi alanların görünür olacağını, sıralarını ve uygulanan filtreleri veya grupları içerir. Uygulamanızla önceden yapılandırılmış görünümler sunmak için `defineView()` kullanın: ```ts src/views/example-view.ts import { defineView, ViewKey } from 'twenty-sdk'; @@ -1077,16 +1077,16 @@ export default defineView({ ``` Önemli noktalar: -* `objectUniversalIdentifier` specifies which object this view applies to. -* `key` determines the view type (e.g., `ViewKey.INDEX` for the main list view). -* `fields` controls which columns appear and their order. Each field references a `fieldMetadataUniversalIdentifier`. -* You can also define `filters`, `filterGroups`, `groups`, and `fieldGroups` for more advanced configurations. -* `position` controls the ordering when multiple views exist for the same object. +* `objectUniversalIdentifier`, bu görünümün hangi nesneye uygulanacağını belirtir. +* `key`, görünüm türünü belirler (ör. ana liste görünümü için `ViewKey.INDEX`). +* `fields`, hangi sütunların görüneceğini ve sıralarını kontrol eder. Her alan bir `fieldMetadataUniversalIdentifier` öğesine referans verir. +* Daha gelişmiş yapılandırmalar için `filters`, `filterGroups`, `groups` ve `fieldGroups` de tanımlayabilirsiniz. +* `position`, aynı nesne için birden fazla görünüm olduğunda sıralamayı kontrol eder. -Navigation menu items add custom entries to the workspace sidebar. Use `defineNavigationMenuItem()` to link to views, external URLs, or objects: +Gezinme menüsü öğeleri, çalışma alanı kenar çubuğuna özel girişler ekler. Görünümlere, harici URL'lere veya nesnelere bağlanmak için `defineNavigationMenuItem()` kullanın: ```ts src/navigation-menu-items/example-navigation-menu-item.ts import { defineNavigationMenuItem, NavigationMenuItemType } from 'twenty-sdk'; @@ -1104,15 +1104,15 @@ export default defineNavigationMenuItem({ ``` Önemli noktalar: -* `type` determines what the menu item links to: `NavigationMenuItemType.VIEW` for a saved view, or `NavigationMenuItemType.LINK` for an external URL. -* For view links, set `viewUniversalIdentifier`. For external links, set `link`. -* `position` controls the ordering in the sidebar. -* `icon` and `color` (optional) customize the appearance. +* `type`, menü öğesinin neye bağlanacağını belirler: kaydedilmiş bir görünüm için `NavigationMenuItemType.VIEW` veya harici bir URL için `NavigationMenuItemType.LINK`. +* Görünüm bağlantıları için `viewUniversalIdentifier` ayarlayın. Harici bağlantılar için `link` ayarlayın. +* `position`, kenar çubuğundaki sıralamayı kontrol eder. +* `icon` ve `color` (isteğe bağlı) görünümü özelleştirir. - + -Page layouts let you customize how a record detail page looks — which tabs appear, what widgets are inside each tab, and how they are arranged. Use `definePageLayout()` to ship custom layouts with your app: +Sayfa düzenleri, bir kayıt ayrıntı sayfasının nasıl görüneceğini özelleştirmenizi sağlar — hangi sekmelerin görüneceği, her sekmenin içinde hangi widget'ların olacağı ve bunların nasıl düzenleneceği. Uygulamanızla özel düzenler sunmak için `definePageLayout()` kullanın: ```ts src/page-layouts/example-record-page-layout.ts import { definePageLayout, PageLayoutTabLayoutMode } from 'twenty-sdk'; @@ -1149,33 +1149,33 @@ export default definePageLayout({ ``` Önemli noktalar: -* `type` is typically `'RECORD_PAGE'` to customize the detail view of a specific object. -* `objectUniversalIdentifier` specifies which object this layout applies to. -* Each `tab` defines a section of the page with a `title`, `position`, and `layoutMode` (`CANVAS` for free-form layout). -* Each `widget` inside a tab can render a front component, a relation list, or other built-in widget types. -* `position` on tabs controls their order. Use higher values (e.g., 50) to place custom tabs after built-in ones. +* `type` genellikle belirli bir nesnenin ayrıntı görünümünü özelleştirmek için `'RECORD_PAGE'` olur. +* `objectUniversalIdentifier`, bu düzenin hangi nesneye uygulanacağını belirtir. +* Her `tab`, bir `title`, `position` ve `layoutMode` ile sayfanın bir bölümünü tanımlar (serbest biçimli düzen için `CANVAS`). +* Bir sekmenin içindeki her `widget`, bir ön uç bileşeni, bir ilişki listesi veya diğer yerleşik widget türlerini oluşturabilir. +* Sekmelerdeki `position`, sıralarını kontrol eder. Özel sekmeleri yerleşik olanların sonrasına yerleştirmek için daha yüksek değerler kullanın (ör. 50). -## Public assets (`public/` folder) +## Genel varlıklar (`public/` klasörü) -The `public/` folder at the root of your app holds static files — images, icons, fonts, or any other assets your app needs at runtime. These files are automatically included in builds, synced during dev mode, and uploaded to the server. +Uygulamanızın kökündeki `public/` klasörü, statik dosyaları barındırır — görseller, simgeler, yazı tipleri veya uygulamanızın çalışma zamanında ihtiyaç duyduğu diğer varlıklar. Bu dosyalar derlemelere otomatik olarak dahil edilir, geliştirme modunda senkronize edilir ve sunucuya yüklenir. -Files placed in `public/` are: +`public/` içine yerleştirilen dosyalar şunlardır: -* **Publicly accessible** — once synced to the server, assets are served at a public URL. No authentication is needed to access them. -* **Available in front components** — use asset URLs to display images, icons, or any media inside your React components. -* **Available in logic functions** — reference asset URLs in emails, API responses, or any server-side logic. -* **Used for marketplace metadata** — the `logoUrl` and `screenshots` fields in `defineApplication()` reference files from this folder (e.g., `public/logo.png`). These are displayed in the marketplace when your app is published. -* **Auto-synced in dev mode** — when you add, update, or delete a file in `public/`, it is synced to the server automatically. No restart needed. -* **Included in builds** — `yarn twenty build` bundles all public assets into the distribution output. +* **Herkese açık olarak erişilebilir** — sunucuya senkronize edildikten sonra varlıklar genel bir URL'den sunulur. Onlara erişmek için kimlik doğrulama gerekmez. +* **Ön uç bileşenlerinde kullanılabilir** — React bileşenlerinizin içinde görseller, simgeler veya herhangi bir medyayı göstermek için varlık URL'lerini kullanın. +* **Mantık işlevlerinde kullanılabilir** — e-postalarda, API yanıtlarında veya herhangi bir sunucu tarafı mantıkta varlık URL'lerine referans verin. +* **Pazar yeri üst verileri için kullanılır** — `defineApplication()` içindeki `logoUrl` ve `screenshots` alanları bu klasördeki dosyalara referans verir (örn. `public/logo.png`). Bunlar, uygulamanız yayımlandığında pazar yerinde görüntülenir. +* **Geliştirme modunda otomatik senkronize edilir** — `public/` içinde bir dosya eklediğinizde, güncellediğinizde veya sildiğinizde otomatik olarak sunucuya senkronize edilir. Yeniden başlatma gerekmez. +* **Derlemelere dahil edilir** — `yarn twenty build`, tüm genel varlıkları dağıtım çıktısına paketler. -### Accessing public assets with `getPublicAssetUrl` +### `getPublicAssetUrl` ile genel varlıklara erişme -Use the `getPublicAssetUrl` helper from `twenty-sdk` to get the full URL of a file in your `public/` directory. It works in both **logic functions** and **front components**. +`twenty-sdk` içindeki `getPublicAssetUrl` yardımcı işlevini kullanarak `public/` dizininizdeki bir dosyanın tam URL'sini alın. Hem **mantık işlevlerinde** hem de **ön uç bileşenlerinde** çalışır. -**In a logic function:** +**Bir mantık işlevinde:** ```ts src/logic-functions/send-invoice.ts import { defineLogicFunction, getPublicAssetUrl } from 'twenty-sdk'; @@ -1200,7 +1200,7 @@ export default defineLogicFunction({ }); ``` -**In a front component:** +**Bir ön uç bileşeninde:** ```tsx src/front-components/company-card.tsx import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk'; @@ -1212,19 +1212,19 @@ export default defineFrontComponent(() => { }); ``` -The `path` argument is relative to your app's `public/` folder. Both `getPublicAssetUrl('logo.png')` and `getPublicAssetUrl('public/logo.png')` resolve to the same URL — the `public/` prefix is stripped automatically if present. +`path` bağımsız değişkeni, uygulamanızın `public/` klasörüne göre görelidir. Hem `getPublicAssetUrl('logo.png')` hem de `getPublicAssetUrl('public/logo.png')` aynı URL'ye çözümlenir — `public/` öneki varsa otomatik olarak kaldırılır. -## Using npm packages +## npm paketlerini kullanma -You can install and use any npm package in your app. Both logic functions and front components are bundled with [esbuild](https://esbuild.github.io/), which inlines all dependencies into the output — no `node_modules` are needed at runtime. +Uygulamanızda herhangi bir npm paketini yükleyip kullanabilirsiniz. Hem mantık işlevleri hem de ön uç bileşenleri, tüm bağımlılıkları çıktıya satır içi olarak ekleyen [esbuild](https://esbuild.github.io/) ile paketlenir — çalışma zamanında `node_modules` gerekmez. -### Installing a package +### Bir paketi yükleme ```bash filename="Terminal" yarn add axios ``` -Then import it in your code: +Ardından kodunuza içe aktarın: ```ts src/logic-functions/fetch-data.ts import { defineLogicFunction } from 'twenty-sdk'; @@ -1245,7 +1245,7 @@ export default defineLogicFunction({ }); ``` -The same works for front components: +Aynısı ön uç bileşenleri için de geçerlidir: ```tsx src/front-components/chart.tsx import { defineFrontComponent } from 'twenty-sdk'; @@ -1262,27 +1262,27 @@ export default defineFrontComponent({ }); ``` -### How bundling works +### Paketleme nasıl çalışır -The build step (`yarn twenty dev` or `yarn twenty build`) uses esbuild to produce a single self-contained file per logic function and per front component. All imported packages are inlined into the bundle. +Derleme adımı (`yarn twenty dev` veya `yarn twenty build`), her mantık işlevi ve her ön uç bileşeni için tek bir bağımsız dosya üretmek üzere esbuild kullanır. Tüm içe aktarılan paketler pakete satır içi eklenir. -**Logic functions** run in a Node.js environment. Node built-in modules (`fs`, `path`, `crypto`, `http`, etc.) are available and do not need to be installed. +**Mantık işlevleri**, Node.js ortamında çalışır. Node yerleşik modülleri (`fs`, `path`, `crypto`, `http` vb.) kullanılabilir ve kurulmaları gerekmez. -**Front components** run in a Web Worker. Node built-in modules are **not** available — only browser APIs and npm packages that work in a browser environment. +**Ön uç bileşenleri**, bir Web Worker içinde çalışır. Node'un yerleşik modülleri **kullanılamaz** — yalnızca tarayıcı ortamında çalışan tarayıcı API'leri ve npm paketleri kullanılabilir. -Both environments have `twenty-client-sdk/core` and `twenty-client-sdk/metadata` available as pre-provided modules — these are not bundled but resolved at runtime by the server. +Her iki ortamda da `twenty-client-sdk/core` ve `twenty-client-sdk/metadata` önceden sağlanmış modüller olarak mevcuttur — bunlar paketlenmez, ancak çalışma zamanında sunucu tarafından çözülür. -## Scaffolding entities with `yarn twenty add` +## `yarn twenty add` ile varlıklar için iskelet oluşturma -Instead of creating entity files by hand, you can use the interactive scaffolder: +Varlık dosyalarını elle oluşturmak yerine etkileşimli iskelet oluşturucuyu kullanabilirsiniz: ```bash filename="Terminal" yarn twenty add ``` -This prompts you to pick an entity type and walks you through the required fields. It generates a ready-to-use file with a stable `universalIdentifier` and the correct `defineEntity()` call. +Bu, bir varlık türü seçmenizi ister ve gerekli alanlar boyunca size yol gösterir. Kararlı bir `universalIdentifier` ve doğru `defineEntity()` çağrısıyla kullanıma hazır bir dosya üretir. -You can also pass the entity type directly to skip the first prompt: +İlk istemi atlamak için varlık türünü doğrudan da geçebilirsiniz: ```bash filename="Terminal" yarn twenty add object @@ -1290,14 +1290,14 @@ yarn twenty add logicFunction yarn twenty add frontComponent ``` -### Available entity types +### Kullanılabilir varlık türleri -| Varlık türü | Komut | Generated file | +| Varlık türü | Komut | Oluşturulan dosya | | -------------------- | ------------------------------------ | ------------------------------------- | | Nesne | `yarn twenty add object` | `src/objects/.ts` | | Alan | `yarn twenty add field` | `src/fields/.ts` | -| Logic function | `yarn twenty add logicFunction` | `src/logic-functions/.ts` | -| Front component | `yarn twenty add frontComponent` | `src/front-components/.tsx` | +| Mantık işlevi | `yarn twenty add logicFunction` | `src/logic-functions/.ts` | +| Ön uç bileşeni | `yarn twenty add frontComponent` | `src/front-components/.tsx` | | Rol | `yarn twenty add role` | `src/roles/.ts` | | Beceri | `yarn twenty add skill` | `src/skills/.ts` | | Temsilci | `yarn twenty add agent` | `src/agents/.ts` |