i18n - docs translations (#17199)

Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
github-actions[bot]
2026-01-16 18:36:39 +01:00
committed by GitHub
parent 5bcbe43596
commit b7fbe1c49e
345 changed files with 11211 additions and 7495 deletions
File diff suppressed because it is too large Load Diff
@@ -2,7 +2,7 @@
title: أفضل الممارسات
---
This document outlines the best practices you should follow when working on the backend.
تحدد هذه الوثيقة أفضل الممارسات التي يجب اتباعها عند العمل في الواجهة الخلفية.
## اتبع نهجًا معياريًا
@@ -11,7 +11,7 @@ This document outlines the best practices you should follow when working on the
## إتاحة الخدمات لاستخدامها في الوحدات
قم دائمًا بإنشاء خدمات ذات مسؤولية واضحة ووحيدة، مما يعزز من قابلية قراءة وصيانة الكود. Name the services descriptively and consistently.
قم دائمًا بإنشاء خدمات ذات مسؤولية واضحة ووحيدة، مما يعزز من قابلية قراءة وصيانة الكود. قم بتسمية الخدمات بأسماء وصفية وبطريقة متسقة.
يجب أيضًا إتاحة الخدمات التي تريد استخدامها في وحدات أخرى. إتاحة الخدمات للوحدات الأخرى ممكنة عبر نظام حقن التبعيات القوي في NestJS، كما يعزز ذلك الاقتران الضعيف بين المكونات.
@@ -7,18 +7,18 @@ info: نظرة تفصيلية داخل هيكلية مجلدات الخادم
```
server
└───ability
└───constants
└───core
└───database
└───decorators
└───filters
└───guards
└───health
└───integrations
└───metadata
└───workspace
└───utils
└───قدرات
└───ثوابت
└───نواة
└───قاعدة البيانات
└───زخارف
└───فلاتر
└───حمايات
└───الصحة
└───تكاملات
└───بيانات وصفية
└───مساحة العمل
└───أدوات
```
## قدرات
@@ -56,28 +56,28 @@ server
```
workspace
└───workspace-schema-builder
└───factories
└───graphql-types
└───database
└───interfaces
└───object-definitions
└───services
└───storage
└───utils
└───workspace-resolver-builder
└───factories
└───interfaces
└───workspace-query-builder
└───factories
└───interfaces
└───workspace-query-runner
└───interfaces
└───utils
└───workspace-datasource
└───workspace-manager
└───workspace-migration-runner
└───utils
└───منشئ مساحة العمل
└───مصانع
└───أنواع GraphQL
└───قاعدة البيانات
└───واجهات
└───تعريفات الكائنات
└───خدمات
└───التخزين
└───أدوات
└───منشئ مستعرض مساحة العمل
└───مصانع
└───واجهات
└───منشئ الاستعلامات مساحة العمل
└───مصانع
└───واجهات
└───مشغل استعلامات مساحة العمل
└───واجهات
└───أدوات
└───مصدر بيانات مساحة العمل
└───مدير مساحة العمل
└───مشغل الانتقالات مساحة العمل
└───أدوات
└───workspace.module.ts
└───workspace.factory.spec.ts
└───workspace.factory.ts
@@ -96,7 +96,7 @@ workspace
مصانع متخصصة لتوليد الإنشاءات المتعلقة بـ GraphQL.
* المصنع النوعي يترجم بيانات الحقول الوصفية إلى أنواع GraphQL باستخدام `TypeMapperService`.
* The type-definition.factory creates GraphQL input or output objects derived from `objectMetadata`.
* ينشئ type-definition.factory كائنات إدخال أو إخراج لـ GraphQL مشتقة من `objectMetadata`.
#### أنواع GraphQL
@@ -1,5 +1,5 @@
---
title: Message Queue
title: قائمة انتظار الرسائل
---
تسهل القوائم العمليات غير المتزامنة. يمكن استخدامها لأداء مهام الخلفية مثل إرسال بريد ترحيبي عند التسجيل.
@@ -10,9 +10,9 @@ title: Message Queue
## خطوات إنشاء واستخدام قائمة جديدة
1. أضف اسم قائمة لقائمة جديدة تحت التعداد `MESSAGE_QUEUES`.
2. Provide the factory implementation of the queue with the queue name as the dependency token.
2. وفّر تنفيذ المصنع لقائمة الانتظار مع استخدام اسم قائمة الانتظار بوصفه رمز التبعية.
3. قم بإدراج القائمة التي أنشأتها في الوحدة/الخدمة المطلوبة مع اسم القائمة كرمز تبعية.
4. Add worker class with token based injection just like producer.
4. أضِف صنف عامل مع حقن قائم على الرمز تمامًا مثل المنتِج.
### نموذج للاستخدام
@@ -1,6 +1,6 @@
---
title: Bugs, Requests & Pull Requests
info: Report issues, request features, and contribute code
title: الأخطاء والطلبات وطلبات السحب
info: أبلغ عن المشكلات، واطلب الميزات، وساهم بالشفرة البرمجية
---
## الإبلاغ عن الأخطاء
@@ -9,70 +9,70 @@ info: Report issues, request features, and contribute code
يمكنك أيضًا طلب المساعدة عبر [Discord](https://discord.gg/cx5n4Jzs57).
## Feature Requests
## طلبات الميزات
إذا لم تكن متأكدًا مما إذا كانت مشكلة أو إذا كنت تشعر بأنها مجرد طلب ميزة، فيمكنك على الأرجح [فتح نقاش بدلاً من ذلك](https://github.com/twentyhq/twenty/discussions/new).
## Submit a Pull Request
## أرسل طلب سحب
Contributing code to Twenty starts with a pull request (PR).
تبدأ المساهمة بالشفرة في Twenty بطلب سحب (PR).
### قبل أن تبدأ
1. Check [existing issues](https://github.com/twentyhq/twenty/issues) for related work
2. For new features, open an issue first to discuss
3. Review our [Code of Conduct](https://github.com/twentyhq/twenty/blob/main/CODE_OF_CONDUCT.md)
1. تحقق من [المشكلات القائمة](https://github.com/twentyhq/twenty/issues) للعمل ذي الصلة
2. بالنسبة للميزات الجديدة، افتح مشكلة أولًا للنقاش
3. راجع [مدونة قواعد السلوك](https://github.com/twentyhq/twenty/blob/main/CODE_OF_CONDUCT.md)
### Fork and Clone
### التفريع والاستنساخ
1. Fork the repository on GitHub
2. Clone your fork:
1. فرّع المستودع على GitHub
2. استنسخ تفريعك:
```bash
git clone https://github.com/YOUR_USERNAME/twenty.git
cd twenty
```
3. Add upstream remote:
3. أضف المستودع البعيد upstream:
```bash
git remote add upstream https://github.com/twentyhq/twenty.git
```
### Create a Branch
### إنشاء فرع
```bash
git checkout -b feature/your-feature-name
```
Use descriptive branch names:
استخدم أسماء فروع وصفية:
* `feature/add-export-button`
* `fix/login-redirect-issue`
* `docs/update-api-guide`
### Make Your Changes
### أجرِ تعديلاتك
1. Write clean, well-documented code
2. Follow existing code style
3. Add tests for new functionality
4. Update documentation if needed
1. اكتب شفرة نظيفة وموثقة جيدًا
2. اتبع أسلوب الشفرة المعمول به
3. أضف اختبارات للوظائف الجديدة
4. حدّث الوثائق عند الحاجة
### Submit Your PR
### أرسل طلب السحب الخاص بك
1. Push your branch:
1. ادفع فرعك:
```bash
git push origin feature/your-feature-name
```
2. Open a PR on GitHub
3. Fill in the PR template
4. Link related issues
2. افتح طلب سحب على GitHub
3. املأ قالب طلب السحب
4. اربط المشكلات ذات الصلة
### PR Checklist
### قائمة التحقق لطلب السحب
* [ ] Code follows project style guidelines
* [ ] Tests pass locally
* [ ] Documentation is updated
* [ ] PR description explains the changes
* [ ] الشفرة تتبع إرشادات أسلوب المشروع
* [ ] تجتاز الاختبارات محليًا
* [ ] الوثائق محدّثة
* [ ] وصف طلب السحب يوضح التغييرات
@@ -77,8 +77,8 @@ If you feel like you need to add a `useEffect` in your root component, you shoul
يمكنك تطبيق نفس الشيء على منطق جلب البيانات، مع الخُطافات Apollo.
```tsx
// ❌ Bad, will cause re-renders even if data is not changing,
// because useEffect needs to be re-evaluated
// ❌ سيّئ، سيتسبب في إعادة التصيير حتى إذا لم تتغير البيانات،
// لأن useEffect يحتاج إلى إعادة التقييم
export const PageComponent = () => {
const [data, setData] = useRecoilState(dataState);
const [someDependency] = useRecoilState(someDependencyState);
@@ -100,8 +100,8 @@ export const App = () => (
```
```tsx
// ✅ Good, will not cause re-renders if data is not changing,
// because useEffect is re-evaluated in another sibling component
// ✅ جيّد، لن يتسبب في إعادة التصيير إذا لم تتغير البيانات،
// لأن useEffect يُعاد تقييمه في مكوّن شقيق آخر
export const PageComponent = () => {
const [data, setData] = useRecoilState(dataState);
@@ -168,13 +168,13 @@ export const App = () => (
الأسماء العامة في البرمجة ليست مثالية لأنها تفتقر إلى التحديد، مما يؤدي إلى الغموض وتقليل قابلية قراءة التعليمات البرمجية. مثل هذه الأسماء تفشل في التعبير عن الغرض من المتغير أو الوظيفة، مما يجعل من الصعب على المطورين فهم نية التعليمات البرمجية دون تحقيق أعمق. يمكن أن يؤدي ذلك إلى زيادة وقت إزالة الأخطاء، وزيادة قابلية التعرض للأخطاء، وصعوبات في الصيانة والتعاون. في الوقت نفسه، تجعل التسمية الوصفية التعليمات البرمجية تفسيرية بذاتها وأسهل في التنقل، مما يعزز جودة التعليمات البرمجية وإنتاجية المطور.
```tsx
// ❌ Bad, uses a generic name that doesn't communicate its
// purpose or content clearly
// ❌ سيّئ، يستخدم اسمًا عامًا لا يوضح
// الغرض أو المحتوى بوضوح
const [value, setValue] = useState('');
```
```tsx
// ✅ Good, uses a descriptive name
// ✅ جيّد، يستخدم اسمًا وصفيًا
const [email, setEmail] = useState('');
```
@@ -187,14 +187,14 @@ const [email, setEmail] = useState('');
يجب أن تبدأ أسماء معالجات الأحداث بكلمة `handle`، بينما يعتبر `on` بادئة تستخدم لتسمية الأحداث في خصائص المكونات.
```tsx
// ❌ Bad
// ❌ سيّئ
const onEmailChange = (val: string) => {
// ...
};
```
```tsx
// ✅ Good
// ✅ جيّد
const handleEmailChange = (val: string) => {
// ...
};
@@ -222,12 +222,12 @@ const EmailField = ({ value, disabled = false }: EmailFieldProps) => (
**الاستخدام**
```tsx
// ❌ Bad, passing in the same value as the default value adds no value
// ❌ سيّئ، تمرير نفس القيمة كقيمة افتراضية لا يضيف أي فائدة
const Form = () => <EmailField value="username@email.com" disabled={false} />;
```
```tsx
// ✅ Good, assumes the default value
// ✅ جيّد، يفترض القيمة الافتراضية
const Form = () => <EmailField value="username@email.com" />;
```
@@ -240,7 +240,7 @@ const Form = () => <EmailField value="username@email.com" />;
```tsx
const SomeParentComponent = () => <MyComponent Icon={MyIcon} />;
// In MyComponent
// داخل MyComponent
const MyComponent = ({ MyIcon }: { MyIcon: IconComponent }) => {
const theme = useTheme();
@@ -285,7 +285,7 @@ const MyComponent = ({ MyIcon }: { MyIcon: IconComponent }) => {
**الاستخدام**
```tsx
// ❌ Bad, specifies the entire relative path
// ❌ سيّئ، يحدد المسار النسبي بالكامل
import {
CatalogDecorator
} from '../../../../../testing/decorators/CatalogDecorator';
@@ -295,7 +295,7 @@ import {
```
```tsx
// ✅ Good, utilises the designated aliases
// ✅ جيّد، يستخدم الأسماء المستعارة المحددة
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
import { ComponentDecorator } from 'twenty-ui/testing';
```
@@ -310,10 +310,10 @@ const validationSchema = z
exist: z.boolean(),
email: z
.string()
.email('Email must be a valid email'),
.email('يجب أن يكون البريد الإلكتروني صالحًا'),
password: z
.string()
.regex(PASSWORD_REGEX, 'Password must contain at least 8 characters'),
.regex(PASSWORD_REGEX, 'يجب أن تحتوي كلمة المرور على 8 أحرف على الأقل'),
})
.required();
@@ -14,9 +14,9 @@ title: مفاتيح الاختصار
لمعالجة هذه المشكلة، لدينا خطاف مخصص يمكن من الاستماع لمفاتيح الاختصار دون أي تعارض.
You place it in a component, and it will listen to the hotkeys only when the component is mounted AND when the specified **hotkey scope** is active.
تضعه داخل مكوّن، ولن يستمع إلى مفاتيح الاختصار إلا عندما يكون المكوّن مُركّبًا وعندما يكون **نطاق مفاتيح الاختصار** المحدّد نشطًا.
## How to listen for hotkeys in practice?
## كيف تستمع إلى مفاتيح الاختصار عمليًا؟
هناك خطوتان متضمنتان في إعداد الاستماع لمفاتيح الاختصار:
@@ -73,9 +73,9 @@ const PageListeningEnter = () => {
### الاستماع لمفاتيح الاختصار في مكون من نوع مودال
For this example we'll use a modal component that listens for the Escape key to tell its parent to close it.
في هذا المثال سنستخدم مكوّن نافذة منبثقة يستمع لمفتاح Escape ليطلب من المكوّن الأب إغلاقه.
Here the user interaction is changing the scope.
هنا يتمثّل تفاعل المستخدم في تغيير النطاق.
```tsx
const ExamplePageWithModal = () => {
@@ -1,8 +1,8 @@
---
title: Storybook
description: Browse Twenty's UI component library
description: تصفح مكتبة مكونات واجهة المستخدم الخاصة بـ Twenty
---
View our complete component library and documentation in Storybook.
اطلع على مكتبة المكونات الكاملة لدينا والتوثيق في Storybook.
[Open Storybook →](https://storybook.twenty.com)
[افتح Storybook →](https://storybook.twenty.com)
@@ -4,7 +4,7 @@ title: دليل الأسلوب
تشمل هذه الوثيقة القواعد التي يجب اتباعها عند كتابة التعليمات البرمجية.
The goal here is to have a consistent codebase, which is easy to read and easy to maintain.
الهدف هنا هو وجود قاعدة شيفرة متسقة يسهل قراءتها وصيانتها.
لهذا، من الأفضل أن تكون تفصيلًا أكثر قليلاً بدلاً من أن تكون موجزًا للغاية.
@@ -67,10 +67,10 @@ const EmailField: React.FC<{
```
```tsx
/* ✅ - Good, a separate type (OwnProps) is explicitly defined for the
* component's props
* - This method doesn't automatically include the children prop. If
* you want to include it, you have to specify it in OwnProps.
/* ✅ - جيد، نوع منفصل (OwnProps) يُعرَّف صراحةً لخصائص
* المكون
* - هذه الطريقة لا تتضمن تلقائيًا خاصية الأطفال. إذا
* كنت تريد تضمينها، يجب أن تحددها في OwnProps.
*/
type EmailFieldProps = {
value: string;
@@ -81,7 +81,7 @@ const EmailField = ({ value }: EmailFieldProps) => (
);
```
#### No Single Variable Prop Spreading in JSX Elements
#### لا تستخدم انتشار متغير فردي للخصائص في عناصر JSX
تجنب استخدام انتشار متغير فردي للخصائص في عناصر JSX، مثل `{...props}`. غالبًا ما تؤدي هذه الممارسة إلى شكل تعليمي أقل قابلية للقراءة وأصعب في الصيانة لأنه من غير الواضح أي الخصائص يتلقاها المكون.
@@ -94,8 +94,8 @@ const MyComponent = (props: OwnProps) => {
```
```tsx
/* ✅ - Good, Explicitly lists all props
* - Enhances readability and maintainability
/* ✅ - جيد، يسرد جميع الخصائص بوضوح
* - يعزز من قابلية القراءة والصيانة
*/
const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => {
return <OtherComponent {...{ prop1, prop2, prop3 }} />;
@@ -110,7 +110,7 @@ const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => {
## JavaScript
### Use nullish-coalescing operator `??`
### استخدم معامل دمج القيم الفارغة `??`
```tsx
// ❌ سيء، قد يعيد 'default' حتى إذا كانت القيمة 0 أو ''
@@ -120,13 +120,13 @@ const value = process.env.MY_VALUE || 'default';
const value = process.env.MY_VALUE ?? 'default';
```
### Use optional chaining `?.`
### استخدم معامل الربط الاختياري `?.`
```tsx
// ❌ Bad
// ❌ سيء
onClick && onClick();
// ✅ Good
// ✅ جيد
onClick?.();
```
@@ -148,7 +148,7 @@ type MyType = {
};
```
### Use string literals instead of enums
### استخدم السلاسل النصية بدلاً من التعدادات
[الحروف المشفوعة](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) هي الطريقة المفضلة للتعامل مع القيم الشبيهة بالأعداد المخصصة في TypeScript. من السهل توسيعها باستخدام Pick و Omit، وتقدم تجربة مطور أفضل، خاصة مع إكمال التعليمات البرمجية.
@@ -190,7 +190,7 @@ setHotkeyScopeAndMemorizePreviousScope(
);
```
## Styling
## التنسيق
### استخدام مكونات منسقة
@@ -224,7 +224,7 @@ const StyledTitle = styled.div`
`;
```
### Theming
### السمات
استخدام السمة لتنسيق معظم المكونات هو النهج المفضل.
@@ -1,6 +1,6 @@
---
title: العمل مع فيجما
info: Learn how you can collaborate with Twenty's Figma
info: تعرّف على كيفية التعاون باستخدام Figma الخاص بـ Twenty
---
فيجما هي أداة تصميم واجهات تعاونية تساعد في سد فجوة التواصل بين المصممين والمطورين.
@@ -18,7 +18,7 @@ info: Learn how you can collaborate with Twenty's Figma
## هيكل فيجما
On the left sidebar, you can access the different pages of Twenty's Figma. هكذا هم مُنظمون:
من الشريط الجانبي الأيسر، يمكنك الوصول إلى الصفحات المختلفة في Figma الخاص بـ Twenty. هكذا هم مُنظمون:
* **صفحة المكونات:** هذه هي الصفحة الأولى. يستخدمها المصمم لإنشاء وتنظيم العناصر التصميمية القابلة لإعادة الاستخدام في ملف التصميم. على سبيل المثال، الأزرار، الأيقونات، الرموز أو أي مكونات أخرى قابلة لإعادة الاستخدام. تعمل على الحفاظ على التناسق عبر التصميم.
* **الصفحة الرئيسية:** الصفحة الثانية هي الصفحة الرئيسية التي تظهر واجهة المستخدم الكاملة للمشروع. يمكنك الضغط على ***تشغيل*** لاستخدام النموذج الأولي الكامل للتطبيق.
@@ -114,7 +114,7 @@ cd twenty
**الخيار 2:** إذا كنت قد قمت بتثبيت docker:
```bash
make postgres-on-docker
make -C packages/twenty-docker postgres-on-docker
```
</Tab>
@@ -173,7 +173,7 @@ cd twenty
**الخيار 2:** إذا كنت قد قمت بتثبيت docker:
```bash
make postgres-on-docker
make -C packages/twenty-docker postgres-on-docker
```
</Tab>
@@ -194,7 +194,7 @@ cd twenty
استخدم هذا الخيار فقط إذا كنت مرتاحًا مع الخطوات الإضافية المتضمنة، بما في ذلك تشغيل [Docker Desktop WSL2](https://docs.docker.com/desktop/wsl).
```bash
make postgres-on-docker
make -C packages/twenty-docker postgres-on-docker
```
</Tab>
</Tabs>
@@ -213,7 +213,7 @@ cd twenty
**الخيار 2:** إذا كنت قد قمت بتثبيت docker:
```bash
make redis-on-docker
make -C packages/twenty-docker redis-on-docker
```
</Tab>
@@ -230,7 +230,7 @@ cd twenty
**الخيار 2:** إذا كنت قد قمت بتثبيت docker:
```bash
make redis-on-docker
make -C packages/twenty-docker redis-on-docker
```
</Tab>
@@ -241,7 +241,7 @@ cd twenty
**الخيار 2:** إذا كنت قد قمت بتثبيت docker:
```bash
make redis-on-docker
make -C packages/twenty-docker redis-on-docker
```
</Tab>
</Tabs>
@@ -448,18 +448,18 @@ export default defineRole({
```typescript
// src/app/createPostCard.function.ts
import { defineFunction } from 'twenty-sdk';
import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload } from 'twenty-sdk';
import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload, RoutePayload } from 'twenty-sdk';
import Twenty, { type Person } from '../../generated';
const handler = async (
params:
| { name?: string }
| RoutePayload
| DatabaseEventPayload<ObjectRecordCreateEvent<Person>>
| CronPayload,
) => {
const client = new Twenty(); // generated typed client
const name = 'name' in params
? params.name ?? process.env.DEFAULT_RECIPIENT_NAME ?? 'Hello world'
const name = 'name' in params.queryStringParameters
? params.queryStringParameters.name ?? process.env.DEFAULT_RECIPIENT_NAME ?? 'Hello world'
: 'Hello world';
const result = await client.mutation({
@@ -518,6 +518,98 @@ export default defineFunction({
* المصفوفة `triggers` اختيارية. يمكن استخدام الوظائف بدون مشغلات كوظائف مساعدة تُستدعى بواسطة وظائف أخرى.
* يمكنك مزج أنواع متعددة من المشغلات في وظيفة واحدة.
### Route trigger payload
<Warning>
**Breaking change (v1.16, January 2026):** The route trigger payload format has changed. Prior to v1.16, query parameters, path parameters, and body were sent directly as the payload. Starting with v1.16, they are nested inside a structured `RoutePayload` object.
**Before v1.16:**
```typescript
const handler = async (params) => {
const { param1, param2 } = params; // Direct access
};
```
**After v1.16:**
```typescript
const handler = async (event: RoutePayload) => {
const { param1, param2 } = event.body; // Access via .body
const { queryParam } = event.queryStringParameters;
const { id } = event.pathParameters;
};
```
**To migrate existing functions:** Update your handler to destructure from `event.body`, `event.queryStringParameters`, or `event.pathParameters` instead of directly from the params object.
</Warning>
When a route trigger invokes your function, it receives a `RoutePayload` object that follows the AWS HTTP API v2 format. Import the type from `twenty-sdk`:
```typescript
import { defineFunction, type RoutePayload } from 'twenty-sdk';
const handler = async (event: RoutePayload) => {
// Access request data
const { headers, queryStringParameters, pathParameters, body } = event;
// HTTP method and path are available in requestContext
const { method, path } = event.requestContext.http;
return { message: 'Success' };
};
```
The `RoutePayload` type has the following structure:
| Property | النوع | الوصف |
| ---------------------------- | ------------------------------------- | --------------------------------------------------------------------------------------- |
| `headers` | `Record<string, string \| undefined>` | HTTP headers (only those listed in `forwardedRequestHeaders`) |
| `queryStringParameters` | `Record<string, string \| undefined>` | Query string parameters (multiple values joined with commas) |
| `pathParameters` | `Record<string, string \| undefined>` | Path parameters extracted from the route pattern (e.g., `/users/:id` → `{ id: '123' }`) |
| `المحتوى` | `object \| null` | Parsed request body (JSON) |
| `isBase64Encoded` | `قيمة منطقية` | Whether the body is base64 encoded |
| `requestContext.http.method` | `string` | HTTP method (GET, POST, PUT, PATCH, DELETE) |
| `requestContext.http.path` | `string` | Raw request path |
### Forwarding HTTP headers
By default, HTTP headers from incoming requests are **not** passed to your serverless function for security reasons. To access specific headers, explicitly list them in the `forwardedRequestHeaders` array:
```typescript
export default defineFunction({
universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
name: 'webhook-handler',
handler,
triggers: [
{
universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
type: 'route',
path: '/webhook',
httpMethod: 'POST',
isAuthRequired: false,
forwardedRequestHeaders: ['x-webhook-signature', 'content-type'],
},
],
});
```
In your handler, you can then access these headers:
```typescript
const handler = async (event: RoutePayload) => {
const signature = event.headers['x-webhook-signature'];
const contentType = event.headers['content-type'];
// Validate webhook signature...
return { received: true };
};
```
<Note>
Header names are normalized to lowercase. Access them using lowercase keys (for example, `event.headers['content-type']`).
</Note>
يمكنك إنشاء وظائف جديدة بطريقتين:
* **مُنشأ بالقالب**: شغّل `yarn create-entity` واختر خيار إضافة وظيفة جديدة. يُولّد هذا ملفًا مبدئيًا مع معالج وتكوين.
@@ -1,44 +1,44 @@
---
title: الويب هوكس
description: Receive real-time notifications when events occur in your CRM.
description: استقبل إشعارات في الوقت الفعلي عند وقوع أحداث في نظام إدارة علاقات العملاء (CRM) الخاص بك.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
Webhooks push data to your systems in real-time when events occur in Twenty — no polling required. Use them to keep external systems in sync, trigger automations, or send alerts.
تدفع خطافات الويب البيانات إلى أنظمتك في الوقت الفعلي عند وقوع أحداث في Twenty — دون الحاجة إلى الاستطلاع الدوري. استخدمها للحفاظ على تزامن الأنظمة الخارجية، وتشغيل الأتمتة، أو إرسال التنبيهات.
## إنشاء ربط ويب
1. Go to **Settings → APIs & Webhooks → Webhooks**
1. انتقل إلى **الإعدادات → APIs & Webhooks → Webhooks**
2. انقر على **+ إنشاء ربط ويب**
3. Enter your webhook URL (must be publicly accessible)
3. أدخل عنوان URL لخطاف الويب الخاص بك (يجب أن يكون قابلاً للوصول علنًا)
4. انقر على **حفظ**
The webhook activates immediately and starts sending notifications.
يتم تفعيل خطاف الويب فورًا ويبدأ في إرسال الإشعارات.
<VimeoEmbed videoId="928786708" title="Creating a webhook" />
<VimeoEmbed videoId="928786708" title="إنشاء خطاف ويب" />
### إدارة Webhooks
**Edit**: Click the webhook → Update URL → **Save**
**تحرير**: انقر على خطاف الويب → تحديث عنوان URL → **حفظ**
**Delete**: Click the webhook → **Delete** → Confirm
**حذف**: انقر على خطاف الويب → **حذف** → تأكيد
## الأحداث
Twenty sends webhooks for these event types:
يرسل Twenty خطافات الويب لأنواع الأحداث التالية:
| حدث | مثال |
| ------------------ | ---------------------------------------------------------- |
| **Record Created** | `person.created`, `company.created`, `note.created` |
| **Record Updated** | `person.updated`, `company.updated`, `opportunity.updated` |
| **Record Deleted** | `person.deleted`, `company.deleted` |
| حدث | مثال |
| --------------- | ---------------------------------------------------------- |
| **إنشاء سجل** | `person.created`, `company.created`, `note.created` |
| **تحديث السجل** | `person.updated`, `company.updated`, `opportunity.updated` |
| **حذف السجل** | `person.deleted`, `company.deleted` |
All event types are sent to your webhook URL. Event filtering may be added in future releases.
يتم إرسال جميع أنواع الأحداث إلى عنوان URL لخطاف الويب الخاص بك. قد تتم إضافة تصفية الأحداث في الإصدارات المستقبلية.
## Payload Format
## تنسيق الحمولة
Each webhook sends an HTTP POST with a JSON body:
يرسل كل خطاف ويب طلب HTTP من نوع POST يتضمن جسمًا بصيغة JSON:
```json
{
@@ -55,35 +55,35 @@ Each webhook sends an HTTP POST with a JSON body:
}
```
| الحقل | الوصف |
| --------------- | ------------------------------------------------ |
| `حدث` | What happened (e.g., `person.created`) |
| `بيانات` | The full record that was created/updated/deleted |
| `الطابع الزمني` | When the event occurred (UTC) |
| الحقل | الوصف |
| --------------- | ----------------------------------------------- |
| `حدث` | ما الذي حدث (على سبيل المثال، `person.created`) |
| `بيانات` | السجل الكامل الذي تم إنشاؤه/تحديثه/حذفه |
| `الطابع الزمني` | وقت حدوث الحدث (UTC) |
<Note>
Respond with a **2xx HTTP status** (200-299) to acknowledge receipt. Non-2xx responses are logged as delivery failures.
استجب بحالة **HTTP 2xx** (200-299) لتأكيد الاستلام. تُسجَّل الاستجابات غير 2xx كإخفاقات في التسليم.
</Note>
## Webhook Validation
## التحقق من صحة خطاف الويب
Twenty signs each webhook request for security. Validate signatures to ensure requests are authentic.
يقوم Twenty بتوقيع كل طلب خطاف ويب لأغراض الأمان. تحقّق من التواقيع للتأكد من أن الطلبات أصيلة.
### Headers
### الرؤوس
| رأس الصفحة | الوصف |
| ---------------------------- | --------------------- |
| `X-Twenty-Webhook-Signature` | HMAC SHA256 signature |
| `X-Twenty-Webhook-Timestamp` | Request timestamp |
| رأس الصفحة | الوصف |
| ---------------------------- | ------------------- |
| `X-Twenty-Webhook-Signature` | توقيع HMAC SHA256 |
| `X-Twenty-Webhook-Timestamp` | الطابع الزمني للطلب |
### Validation Steps
### خطوات التحقق
1. Get the timestamp from `X-Twenty-Webhook-Timestamp`
2. Create the string: `{timestamp}:{JSON payload}`
3. Compute HMAC SHA256 using your webhook secret
4. Compare with `X-Twenty-Webhook-Signature`
1. احصل على الطابع الزمني من `X-Twenty-Webhook-Timestamp`
2. أنشئ السلسلة: `{timestamp}:{JSON payload}`
3. احسب HMAC SHA256 باستخدام سر خطاف الويب الخاص بك
4. قارِن مع `X-Twenty-Webhook-Signature`
### Example (Node.js)
### مثال (Node.js)
```javascript
const crypto = require("crypto");
@@ -101,12 +101,12 @@ const expectedSignature = crypto
const isValid = expectedSignature === req.headers["x-twenty-webhook-signature"];
```
## Webhooks vs Workflows
## خطافات الويب مقابل سير العمل
| طريقة | الاتجاه | Use Case |
| ---------------------------- | ------- | ---------------------------------------------------------- |
| **Webhooks** | OUT | Automatically notify external systems of any record change |
| **Workflow + HTTP Request** | OUT | Send data out with custom logic (filters, transformations) |
| **Workflow Webhook Trigger** | IN | Receive data into Twenty from external systems |
| طريقة | الاتجاه | حالة الاستخدام |
| ----------------------------- | ------- | ----------------------------------------------------------- |
| **خطافات الويب** | OUT | إخطار الأنظمة الخارجية تلقائيًا بأي تغيير في السجل |
| **سير العمل + طلب HTTP** | OUT | إرسال البيانات إلى الخارج بمنطق مخصص (عوامل تصفية، تحويلات) |
| **مشغّل خطاف ويب لسير العمل** | IN | استقبال البيانات في Twenty من الأنظمة الخارجية |
For receiving external data, see [Set Up a Webhook Trigger](/l/ar/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger).
لاستقبال البيانات الخارجية، راجع [إعداد مشغّل خطاف الويب](/l/ar/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger).
@@ -1,6 +1,6 @@
---
title: Extend
description: Extend Twenty's functionality with APIs, webhooks, and custom apps.
title: التوسيع
description: وسّع وظائف Twenty باستخدام واجهات برمجة التطبيقات، وخطافات الويب، والتطبيقات المخصصة.
---
<Frame>
@@ -9,26 +9,26 @@ description: Extend Twenty's functionality with APIs, webhooks, and custom apps.
## نظرة عامة
Twenty is designed to be extensible. Use our APIs, webhooks, and app framework to integrate with your existing tools and build custom functionality.
تم تصميم Twenty ليكون قابلاً للتوسعة. استخدم واجهات برمجة التطبيقات وخطافات الويب وإطار عمل التطبيقات لدينا للتكامل مع أدواتك الحالية وبناء وظائف مخصصة.
## What You Can Do
## ما الذي يمكنك فعله
* **APIs**: Query and modify your CRM data programmatically using REST or GraphQL
* **Webhooks**: Receive real-time notifications when events occur in Twenty
* **Apps**: Build custom applications that extend Twenty's capabilities - Coming soon!
* **واجهات برمجة التطبيقات**: استعلم وعدّل بيانات إدارة علاقات العملاء (CRM) لديك برمجياً باستخدام REST أو GraphQL
* **خطافات الويب**: استقبل إشعارات في الوقت الفعلي عند وقوع أحداث في Twenty
* **التطبيقات**: أنشئ تطبيقات مخصصة توسّع قدرات Twenty - قريباً!
## البدء
<CardGroup cols={٢}>
<Card title="واجهات برمجة التطبيقات" icon="كود" href="/l/ar/developers/extend/capabilities/apis">
Connect to Twenty programmatically
اتصل بـ Twenty برمجياً
</Card>
<Card title="الويب هوكس" icon="bell" href="/l/ar/developers/extend/capabilities/webhooks">
Get notified of events in real-time
احصل على إشعارات بالأحداث في الوقت الفعلي
</Card>
<Card title="Apps" icon="puzzle-piece" href="/l/ar/developers/extend/capabilities/apps">
Build customizations as code (Alpha)
<Card title="التطبيقات" icon="puzzle-piece" href="/l/ar/developers/extend/capabilities/apps">
أنشئ تخصيصات كرمز برمجي (ألفا)
</Card>
</CardGroup>
@@ -1,23 +1,23 @@
---
title: البدء
description: Welcome to Twenty Developer Documentation, your resources for extending, self-hosting, and contributing to Twenty.
description: مرحبًا بك في وثائق المطوّرين الخاصة بـ Twenty، مرجعك للتوسيع والاستضافة الذاتية والمساهمة في Twenty.
---
import { CardTitle } from "/snippets/card-title.mdx"
<CardGroup cols={٣}>
<Card href="/l/ar/developers/extend/extend" img="/images/user-guide/integrations/plug.png">
<CardTitle>Extend</CardTitle>
Build integrations with APIs, webhooks, and custom apps.
<CardTitle>التوسيع</CardTitle>
أنشئ عمليات تكامل مع واجهات برمجة التطبيقات وخطافات الويب والتطبيقات المخصصة.
</Card>
<Card href="/l/ar/developers/self-host/self-host" img="/images/user-guide/what-is-twenty/20.png">
<CardTitle>Self-Host</CardTitle>
Deploy and manage Twenty on your own infrastructure.
<CardTitle>الاستضافة الذاتية</CardTitle>
قم بنشر Twenty وإدارته على البنية التحتية الخاصة بك.
</Card>
<Card href="/l/ar/developers/contribute/contribute" img="/images/user-guide/github/github-header.png">
<CardTitle>Contribute</CardTitle>
Join our open-source community and contribute to Twenty.
<CardTitle>المساهمة</CardTitle>
انضم إلى مجتمعنا مفتوح المصدر وساهم في Twenty.
</Card>
</CardGroup>
@@ -8,7 +8,7 @@ title: طرق أخرى
## Kubernetes عبر Terraform والمخططات
Community-led documentation for Kubernetes deployment is available [here](https://github.com/twentyhq/twenty/tree/main/packages/twenty-docker/k8s)
يتوفر توثيق يقوده المجتمع لعملية نشر Kubernetes [هنا](https://github.com/twentyhq/twenty/tree/main/packages/twenty-docker/k8s)
### Coolify
@@ -42,4 +42,4 @@ Community-led documentation for Kubernetes deployment is available [here](https:
## أخرى
Please feel free to Open a PR to add more Cloud Provider options.
لا تتردد في فتح طلب سحب لإضافة المزيد من خيارات موفّري السحابة.
@@ -1,5 +1,5 @@
---
title: 1-Click w/ Docker Compose
title: بنقرة واحدة مع Docker Compose
---
<Warning>
@@ -44,7 +44,7 @@ VERSION=vx.y.z BRANCH=branch-name bash <(curl -sL https://raw.githubusercontent.
1. **إنشاء ملف .env**
Copy the example environment file to a new .env file in your working directory:
انسخ ملف البيئة النموذجي إلى ملف .env جديد في دليل العمل لديك:
```bash
curl -o .env https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-docker/.env.example
@@ -86,7 +86,7 @@ curl -o docker-compose.yml https://raw.githubusercontent.com/twentyhq/twenty/ref
### الخطوة 3: إطلاق التطبيق
Start the Docker containers:
بدء حاويات Docker:
```bash
docker compose up -d
@@ -94,9 +94,9 @@ docker compose up -d
### الخطوة 4: الوصول إلى التطبيق
If you host twentyCRM on your own computer, open your browser and navigate to [http://localhost:3000](http://localhost:3000).
إذا كنت تستضيف twentyCRM على جهازك، فافتح المتصفح وانتقل إلى [http://localhost:3000](http://localhost:3000).
If you host it on a server, check that the server is running and that everything is ok with
إذا كنت تستضيفه على خادم، فتحقق من أن الخادم يعمل وأن كل شيء على ما يرام باستخدام
```bash
curl http://localhost:3000
@@ -186,66 +186,66 @@ SSL (HTTPS) مطلوب لعمل ميزات معينة في المتصفح بشك
* **إعدادات الجدار الناري:**
Open necessary ports in your firewall to allow external access.
افتح المنافذ اللازمة في جدار الحماية للسماح بالوصول الخارجي.
* **التناسق:**
يجب أن يتطابق `SERVER_URL` مع طريقة وصول المستخدمين إلى تطبيقك في متصفحاتهم.
#### Persistence
#### استمرارية البيانات
* **أحجام البيانات:**
The Docker Compose configuration uses volumes to persist data for the database and server storage.
يستخدم تكوين Docker Compose وحدات التخزين للاحتفاظ بالبيانات لقاعدة البيانات وتخزين الخادم.
* **البيئات غير المرتبطة بالحالة:**
إذا كنت تقوم بالنشر إلى بيئة غير مرتبطة بالحالة (مثل بعض خدمات السحابة)، فقم بتكوين التخزين الخارجي لحفظ البيانات.
## Backup and Restore
## النسخ الاحتياطي والاستعادة
Regular backups protect your CRM data from loss.
تحمي النسخ الاحتياطية المنتظمة بيانات نظام إدارة علاقات العملاء لديك من الفقدان.
### Create a Database Backup
### إنشاء نسخة احتياطية لقاعدة البيانات
```bash
docker exec twenty-postgres pg_dump -U postgres twenty > backup_$(date +%Y%m%d).sql
```
### Automate Daily Backups
### أتمتة النسخ الاحتياطية اليومية
Add to your crontab (`crontab -e`):
أضف إلى crontab لديك (`crontab -e`):
```bash
0 2 * * * docker exec twenty-postgres pg_dump -U postgres twenty > /backups/twenty_$(date +\%Y\%m\%d).sql
```
### Restore from Backup
### الاستعادة من نسخة احتياطية
1. Stop the application:
1. إيقاف التطبيق:
```bash
docker compose stop twenty-server twenty-front
```
2. Restore the database:
2. استعادة قاعدة البيانات:
```bash
docker exec -i twenty-postgres psql -U postgres twenty < backup_20240115.sql
```
3. Restart services:
3. إعادة تشغيل الخدمات:
```bash
docker compose up -d
```
### Backup Best Practices
### أفضل ممارسات النسخ الاحتياطي
* **Test restores regularly** — verify backups actually work
* **Store backups off-site** — use cloud storage (S3, GCS, etc.)
* **Encrypt sensitive data** — protect backups with encryption
* **Retain multiple copies** — keep daily, weekly, and monthly backups
* **اختبر عمليات الاستعادة بانتظام** — تحقق من أن النسخ الاحتياطية تعمل فعلاً
* **خزّن النسخ الاحتياطية خارج الموقع** — استخدم التخزين السحابي (S3، GCS، إلخ.)
* **شفّر البيانات الحساسة** — قم بحماية النسخ الاحتياطية بالتشفير
* **احتفِظ بنسخ متعددة** — احتفِظ بنسخ احتياطية يومية وأسبوعية وشهرية
## استكشاف الأخطاء وإصلاحها
@@ -60,61 +60,61 @@ IS_CONFIG_VARIABLES_IN_DB_ENABLED=false
3. أعد تشغيل الحاويات لتصبح التغييرات نافذة
4. ستظهر لوحة الإدارة القيم الحالية لكنها لن تتمكن من تعديلها
## Multi-Workspace Mode
## وضع تعدد مساحات العمل
By default, Twenty runs in **single-workspace mode** — ideal for most self-hosted deployments where you need one CRM instance for your organization.
افتراضيًا، تعمل Twenty في **وضع مساحة عمل واحدة** — وهو مثالي لمعظم عمليات النشر المستضافة ذاتيًا حيث تحتاج إلى مثيل واحد من نظام إدارة علاقات العملاء لمؤسستك.
### Single-Workspace Mode (Default)
### وضع مساحة العمل الواحدة (الافتراضي)
```bash
IS_MULTIWORKSPACE_ENABLED=false # default
```
* One workspace per Twenty instance
* First user automatically becomes admin with full privileges (`canImpersonate` and `canAccessFullAdminPanel`)
* New signups are disabled after the first workspace is created
* Simple URL structure: `https://your-domain.com`
* مساحة عمل واحدة لكل مثيل من Twenty
* أول مستخدم يصبح تلقائيًا مشرفًا مع صلاحيات كاملة (`canImpersonate` و`canAccessFullAdminPanel`)
* يتم تعطيل عمليات التسجيل الجديدة بعد إنشاء مساحة العمل الأولى
* بنية URL بسيطة: `https://your-domain.com`
### Enabling Multi-Workspace Mode
### تمكين وضع تعدد مساحات العمل
```bash
IS_MULTIWORKSPACE_ENABLED=true
DEFAULT_SUBDOMAIN=app # default value
```
Enable multi-workspace mode for SaaS-like deployments where multiple independent teams need their own workspaces on the same Twenty instance.
قم بتمكين وضع تعدد مساحات العمل لعمليات النشر المشابهة لـ SaaS حيث تحتاج عدة فرق مستقلة إلى مساحات عمل خاصة بها على نفس مثيل Twenty.
**Key differences from single-workspace mode:**
**الاختلافات الرئيسية مقارنة بوضع مساحة العمل الواحدة:**
* Multiple workspaces can be created on the same instance
* Each workspace gets its own subdomain (e.g., `sales.your-domain.com`, `marketing.your-domain.com`)
* Users sign up and log in at `{DEFAULT_SUBDOMAIN}.your-domain.com` (e.g., `app.your-domain.com`)
* No automatic admin privileges — first user in each workspace is a regular user
* Workspace-specific settings like subdomain and custom domain become available in workspace settings
* يمكن إنشاء مساحات عمل متعددة على نفس المثيل
* تحصل كل مساحة عمل على نطاق فرعي خاص بها (مثل: `sales.your-domain.com`، `marketing.your-domain.com`)
* يسجل المستخدمون ويقومون بتسجيل الدخول عبر `{DEFAULT_SUBDOMAIN}.your-domain.com` (مثل: `app.your-domain.com`)
* لا توجد صلاحيات مشرف تلقائية — أول مستخدم في كل مساحة عمل يكون مستخدمًا عاديًا
* إعدادات خاصة بمساحة العمل مثل النطاق الفرعي والنطاق المخصص تصبح متاحة ضمن إعدادات مساحة العمل
<Warning>
**Environment-only setting:** `IS_MULTIWORKSPACE_ENABLED` can only be configured via `.env` file and requires a restart. It cannot be changed through the admin panel.
**إعداد خاص بالبيئة فقط:** لا يمكن تكوين `IS_MULTIWORKSPACE_ENABLED` إلا عبر ملف `.env` ويتطلب إعادة تشغيل. لا يمكن تغييره عبر لوحة الإدارة.
</Warning>
### DNS Configuration for Multi-Workspace
### تكوين DNS لوضع تعدد مساحات العمل
When using multi-workspace mode, configure your DNS with a wildcard record to allow dynamic subdomain creation:
عند استخدام وضع تعدد مساحات العمل، قم بتكوين DNS لديك بسجل wildcard للسماح بإنشاء النطاقات الفرعية ديناميكيًا:
```
*.your-domain.com -> your-server-ip
```
This enables automatic subdomain routing for new workspaces without manual DNS configuration.
يُمكّن هذا توجيه النطاقات الفرعية تلقائيًا لمساحات العمل الجديدة دون تكوين DNS يدوي.
### Restricting Workspace Creation
### تقييد إنشاء مساحات العمل
In multi-workspace mode, you may want to limit who can create new workspaces:
في وضع تعدد مساحات العمل، قد ترغب في تقييد من يمكنه إنشاء مساحات عمل جديدة:
```bash
IS_WORKSPACE_CREATION_LIMITED_TO_SERVER_ADMINS=true
```
When enabled, only users with `canAccessFullAdminPanel` can create additional workspaces. Users can still create their first workspace during initial signup.
عند التمكين، يمكن فقط للمستخدمين الذين لديهم `canAccessFullAdminPanel` إنشاء مساحات عمل إضافية. لا يزال بإمكان المستخدمين إنشاء مساحة العمل الأولى الخاصة بهم أثناء التسجيل الأولي.
## تكامل Gmail و Google Calendar
@@ -133,8 +133,8 @@ When enabled, only users with `canAccessFullAdminPanel` can create additional wo
1. اذهب إلى [بيانات اعتماد](https://console.cloud.google.com/apis/credentials)
2. قم بإنشاء معرف عميل OAuth 2.0
3. أضف هذه الـ URIs لإعادة التوجيه:
* `https://{your-domain}/auth/google/redirect` (for SSO)
* `https://{your-domain}/auth/google-apis/get-access-token` (for integrations)
* `https://{your-domain}/auth/google/redirect` (لتسجيل الدخول الفردي)
* `https://{your-domain}/auth/google-apis/get-access-token` (للتكاملات)
### الإعداد في Twenty
@@ -194,13 +194,13 @@ When enabled, only users with `canAccessFullAdminPanel` can create additional wo
ستحتاج إلى إضافة URIs التالية لإعادة التوجيه إلى مشروعك:
* `https://{your-domain}/auth/microsoft/redirect` if you want to use Microsoft SSO
* `https://{your-domain}/auth/microsoft/redirect` إذا كنت تريد استخدام تسجيل الدخول الفردي في Microsoft
* `https://{your-domain}/auth/microsoft-apis/get-access-token`
### الإعداد في Twenty
1. اذهب إلى **الإعدادات → لوحة الإدارة → متغيرات التكوين**
2. Find the **Microsoft Auth** section
2. ابحث عن قسم **Microsoft Auth**
3. حدد هذه المتغيرات:
* `MESSAGING_PROVIDER_MICROSOFT_ENABLED=true`
* `CALENDAR_PROVIDER_MICROSOFT_ENABLED=true`
@@ -214,7 +214,7 @@ When enabled, only users with `canAccessFullAdminPanel` can create additional wo
**وضع بيئي فقط:** إذا كنت قد ضبطت `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`، فأضف هذه المتغيرات إلى ملف `.env` الخاص بك بدلاً من ذلك.
</Warning>
### Configure scopes
### تكوين النطاقات
[انظر الشيفرة المصدرية ذات الصلة](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/auth/utils/get-microsoft-apis-oauth-scopes.ts#L2-L9)
@@ -232,7 +232,7 @@ When enabled, only users with `canAccessFullAdminPanel` can create additional wo
أضف مستخدمي الاختبار إلى قسم "المستخدمون والمجموعات".
## Background Jobs for Calendar & Messaging
## مهام الخلفية للتقويم والمراسلة
بعد إعداد تكامل Gmail، أو Google Calendar، أو Microsoft 365، تحتاج إلى بدء وظائف الخلفية التي تقوم بمزامنة البيانات.
@@ -252,7 +252,7 @@ yarn command:prod cron:workflow:automated-cron-trigger
## تكوين البريد الإلكتروني
1. اذهب إلى **الإعدادات → لوحة الإدارة → متغيرات التكوين**
2. Find the **Email** section
2. ابحث عن قسم **Email**
3. قم بضبط إعدادات SMTP الخاصة بك:
<ArticleTabs label1="جيميل" label2="أوفيس 365" label3="Smtp4dev">
@@ -291,3 +291,47 @@ yarn command:prod cron:workflow:automated-cron-trigger
<Warning>
**وضع بيئي فقط:** إذا كنت قد ضبطت `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`، فأضف هذه المتغيرات إلى ملف `.env` الخاص بك بدلاً من ذلك.
</Warning>
## Serverless Functions
Twenty supports serverless functions for workflows and custom logic. The execution environment is configured via the `SERVERLESS_TYPE` environment variable.
<Warning>
**Security Notice:** The local serverless driver (`SERVERLESS_TYPE=LOCAL`) runs code directly on the host in a Node.js process with no sandboxing. It should only be used for trusted code in development. For production deployments handling untrusted code, we highly recommend using `SERVERLESS_TYPE=LAMBDA` or `SERVERLESS_TYPE=DISABLED`.
</Warning>
### Available Drivers
| Driver | Environment Variable | حالة الاستخدام | Security Level |
| -------- | -------------------------- | ------------------------------------- | ------------------------------- |
| Disabled | `SERVERLESS_TYPE=DISABLED` | Disable serverless functions entirely | N/A |
| Local | `SERVERLESS_TYPE=LOCAL` | Development and trusted environments | Low (no sandboxing) |
| Lambda | `SERVERLESS_TYPE=LAMBDA` | Production with untrusted code | High (hardware-level isolation) |
### Recommended Configuration
**For development:**
```bash
SERVERLESS_TYPE=LOCAL # default
```
**For production (AWS):**
```bash
SERVERLESS_TYPE=LAMBDA
SERVERLESS_LAMBDA_REGION=us-east-1
SERVERLESS_LAMBDA_ROLE=arn:aws:iam::123456789:role/your-lambda-role
SERVERLESS_LAMBDA_ACCESS_KEY_ID=your-access-key
SERVERLESS_LAMBDA_SECRET_ACCESS_KEY=your-secret-key
```
**To disable serverless functions:**
```bash
SERVERLESS_TYPE=DISABLED
```
<Note>
When using `SERVERLESS_TYPE=DISABLED`, any attempt to execute a serverless function will return an error. This is useful if you want to run Twenty without serverless function capabilities.
</Note>
@@ -4,9 +4,9 @@ title: دليل الترقية
## إرشادات عامة
**Always make sure to back up your database before starting the upgrade process** by running `docker exec -it {db_container_name_or_id} pg_dumpall -U {postgres_user} > databases_backup.sql`.
**تأكد دائماً من عمل نسخة احتياطية لقاعدة بياناتك قبل بدء عملية الترقية** عن طريق تشغيل `docker exec -it {db_container_name_or_id} pg_dumpall -U {postgres_user} > databases_backup.sql`.
To restore backup, run `cat databases_backup.sql | docker exec -i {db_container_name_or_id} psql -U {postgres_user}`.
لاستعادة النسخة الاحتياطية، قم بتشغيل `cat databases_backup.sql | docker exec -i {db_container_name_or_id} psql -U {postgres_user}`.
إذا كنت تستخدم Docker Compose، اتبع الخطوات التالية:
@@ -46,7 +46,7 @@ yarn command:prod cache:flush
لم تعد بحاجة إلى تشغيل أي أمر، الصورة الجديدة ستعتني بتشغيل جميع الترحيلات المطلوبة تلقائيًا.
### `User does not have permission` error
### خطأ: `User does not have permission`
إذا واجهت أخطاء في الأذونات في معظم الطلبات بعد الترقية، فقد تحتاج إلى مسح التخزين المؤقت لإعادة حساب أحدث الأذونات.
@@ -316,8 +316,8 @@ yarn command:prod upgrade-0.31
قم بترقية مثيل Twenty الخاص بك لاستخدام صورة v0.30.0
**Breaking change**:
To enhance performances, Twenty now requires redis cache to be configured. قمنا بتحديث [docker-compose.yml](https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/docker-compose.yml) لتعكس ذلك.
**تغيير كبير**:
لتحسين الأداء، يتطلب Twenty الآن تكوين Redis للتخزين المؤقت. قمنا بتحديث [docker-compose.yml](https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/docker-compose.yml) لتعكس ذلك.
تأكد من تحديث إعدادات التكوين الخاصة بك وتحديث المتغيرات البيئية الخاصة بك وفقًا لذلك:
```
+39 -39
View File
@@ -1,16 +1,16 @@
{
"tabs": {
"userGuide": {
"label": "User Guide",
"label": "دليل المستخدم",
"groups": {
"discoverTwenty": {
"label": "Discover Twenty",
"label": "اكتشف Twenty",
"groups": {
"gettingStartedCapabilities": {
"label": "Capabilities"
"label": "القدرات"
},
"gettingStartedHowTos": {
"label": "How-Tos"
"label": "الإرشادات"
}
}
},
@@ -18,32 +18,32 @@
"label": "نموذج البيانات",
"groups": {
"dataModelCapabilities": {
"label": "Capabilities"
"label": "القدرات"
},
"dataModelHowTos": {
"label": "How-Tos"
"label": "الإرشادات"
}
}
},
"dataMigration": {
"label": "Data Migration",
"label": "ترحيل البيانات",
"groups": {
"dataMigrationCapabilities": {
"label": "Capabilities"
"label": "القدرات"
},
"dataMigrationHowTos": {
"label": "How-Tos"
"label": "الإرشادات"
}
}
},
"calendarEmails": {
"label": "Calendar & Emails",
"label": "التقويم والبريد الإلكتروني",
"groups": {
"calendarEmailsCapabilities": {
"label": "Capabilities"
"label": "القدرات"
},
"calendarEmailsHowTos": {
"label": "How-Tos"
"label": "الإرشادات"
}
}
},
@@ -51,22 +51,22 @@
"label": "سير العمل",
"groups": {
"workflowsCapabilities": {
"label": "Capabilities"
"label": "القدرات"
},
"workflowsHowTos": {
"label": "How-Tos",
"label": "الإرشادات",
"groups": {
"crmAutomations": {
"label": "CRM Automations"
"label": "أتمتة إدارة علاقات العملاء"
},
"connectToOtherTools": {
"label": "Connect to Other Tools"
"label": "الاتصال بأدوات أخرى"
},
"advancedConfigurations": {
"label": "Advanced Configurations"
"label": "التكوينات المتقدمة"
},
"needMoreHelp": {
"label": "Need More Help"
"label": "المزيد من المساعدة"
}
}
}
@@ -76,21 +76,21 @@
"label": "الذكاء الاصطناعي",
"groups": {
"aiCapabilities": {
"label": "Capabilities"
"label": "القدرات"
},
"aiHowTos": {
"label": "How-Tos"
"label": "الإرشادات"
}
}
},
"viewsPipelines": {
"label": "Views & Pipelines",
"label": "طرق العرض والمسارات",
"groups": {
"viewsPipelinesCapabilities": {
"label": "Capabilities"
"label": "القدرات"
},
"viewsPipelinesHowTos": {
"label": "How-Tos"
"label": "الإرشادات"
}
}
},
@@ -98,21 +98,21 @@
"label": "لوحات القيادة",
"groups": {
"dashboardsCapabilities": {
"label": "Capabilities"
"label": "القدرات"
},
"dashboardsHowTos": {
"label": "How-Tos"
"label": "الإرشادات"
}
}
},
"permissionsAccess": {
"label": "Permissions & Access",
"label": "الصلاحيات والوصول",
"groups": {
"permissionsAccessCapabilities": {
"label": "Capabilities"
"label": "القدرات"
},
"permissionsAccessHowTos": {
"label": "How-Tos"
"label": "الإرشادات"
}
}
},
@@ -120,10 +120,10 @@
"label": "الفوترة",
"groups": {
"billingCapabilities": {
"label": "Capabilities"
"label": "القدرات"
},
"billingHowTos": {
"label": "How-Tos"
"label": "الإرشادات"
}
}
},
@@ -131,10 +131,10 @@
"label": "\\ا\\ل\\إ\\ع\\د\\ا\\د\\ا\\ت",
"groups": {
"settingsCapabilities": {
"label": "Capabilities"
"label": "القدرات"
},
"settingsHowTos": {
"label": "How-Tos"
"label": "الإرشادات"
}
}
}
@@ -147,26 +147,26 @@
"label": "المطورون"
},
"extend": {
"label": "Extend",
"label": "التوسيع",
"groups": {
"extendCapabilities": {
"label": "Capabilities"
"label": "القدرات"
}
}
},
"selfHost": {
"label": "Self-Host",
"label": "الاستضافة الذاتية",
"groups": {
"selfHostCapabilities": {
"label": "Capabilities"
"label": "القدرات"
}
}
},
"contribute": {
"label": "Contribute",
"label": "المساهمة",
"groups": {
"contributeCapabilities": {
"label": "Capabilities",
"label": "القدرات",
"groups": {
"frontendDevelopment": {
"label": "تطوير الواجهة الأمامية",
@@ -184,7 +184,7 @@
"label": "إدخال"
},
"navigation": {
"label": "Navigation"
"label": "التنقل"
}
}
}
@@ -51,8 +51,8 @@ image: /images/user-guide/tasks/tasks_header.png
| الخصائص | النوع | الوصف | الإعداد الافتراضي |
| ----------- | ----------- | ------------------------------------- | ----------------- |
| isAnimating | قيمة منطقية | يتحكم فيما إذا كانت علامة صحيح متحركة | خاطئ |
| اللون | string | Color of the checkmark | |
| اللون | string | لون علامة الاختيار | |
| المدة | رقم | مدة الحركة بالثواني | 0.5 ثانية |
| الحجم | رقم | The size of the checkmark | 28 بكسل |
| الحجم | رقم | حجم علامة الاختيار | 28 بكسل |
</Tab>
</Tabs>
@@ -9,7 +9,7 @@ image: /images/user-guide/objects/objects.png
قائمة بالأيقونات المستخدمة في جميع أنحاء تطبيقنا.
## Tabler Icons
## أيقونات Tabler
نستخدم أيقونات Tabler لـ React في جميع أنحاء التطبيق.
@@ -1,5 +1,5 @@
---
title: Soon Pill
title: شارة قريبًا
image: /images/user-guide/kanban-views/kanban.png
---
@@ -7,7 +7,7 @@ image: /images/user-guide/table-views/table.png
<img src="/images/user-guide/table-views/table.png" alt="رأس الصفحة" />
</Frame>
Component to visually categorize or label content.
مكوّن لتصنيف المحتوى أو وسمه بصريًا.
<Tabs>
<Tab title="استخدام">
@@ -38,20 +38,20 @@ image: /images/user-guide/views/filter.png
</Tab>
<Tab title="خصائص">
| خصائص | النوع | الوصف |
| --------- | --------------------- | -------------------------------------------------------------------------------------- |
| className | string | اسم فئة اختياري لتنسيقات إضافية |
| أيقونة | `React.ComponentType` | مكون رمز اختياري يُعرض داخل الزر |
| العنوان | string | محتوى نص الزر |
| عرض كامل | قيمة منطقية | يُحدد إذا كان الزر يجب أن يمتد ليغطي العرض الكامل للحاوية الخاصة به |
| التنوع | string | النمط المرئي للزر. Options include `primary`, `secondary`, and `tertiary` |
| الحجم | string | حجم الزر. يوجد خياران: `صغير` و `متوسط` |
| الموقع | string | موقع الزر بالنسبة لأخوته. Options include: `standalone`, `left`, `right`, and `middle` |
| accent | string | موقع الزر بالنسبة لأخوته. تشمل الخيارات: `default`، `blue`، `danger` |
| قريباً | قيمة منطقية | يشير إلى ما إذا كان الزر معلمًا "قريبًا" (مثل الميزات القادمة) |
| معطل | قيمة منطقية | يحدد إذا كان الزر معطل أم لا |
| تركيز | قيمة منطقية | يحدد إذا كان الزر في وضع التركيز |
| عند النقر | وظيفة | وظيفة رد فعل تنطلق عند نقر المستخدم على الزر |
| خصائص | النوع | الوصف |
| --------- | --------------------- | ---------------------------------------------------------------------------------- |
| className | string | اسم فئة اختياري لتنسيقات إضافية |
| أيقونة | `React.ComponentType` | مكون رمز اختياري يُعرض داخل الزر |
| العنوان | string | محتوى نص الزر |
| عرض كامل | قيمة منطقية | يُحدد إذا كان الزر يجب أن يمتد ليغطي العرض الكامل للحاوية الخاصة به |
| التنوع | string | النمط المرئي للزر. تشمل الخيارات `primary`، `secondary`، و`tertiary`. |
| الحجم | string | حجم الزر. يوجد خياران: `صغير` و `متوسط` |
| الموقع | string | موقع الزر بالنسبة لأخوته. تشمل الخيارات: `standalone`، `left`، `right`، و`middle`. |
| accent | string | موقع الزر بالنسبة لأخوته. تشمل الخيارات: `default`، `blue`، `danger` |
| قريباً | قيمة منطقية | يشير إلى ما إذا كان الزر معلمًا "قريبًا" (مثل الميزات القادمة) |
| معطل | قيمة منطقية | يحدد إذا كان الزر معطل أم لا |
| تركيز | قيمة منطقية | يحدد إذا كان الزر في وضع التركيز |
| عند النقر | وظيفة | وظيفة رد فعل تنطلق عند نقر المستخدم على الزر |
</Tab>
</Tabs>
@@ -116,13 +116,13 @@ image: /images/user-guide/views/filter.png
</Tab>
<Tab title="الخصائص">
| الخصائص | النوع | الوصف |
| --------- | --------- | ------------------------------------------------------------------------------------------ |
| التنوع | string | النمط المرئي للأزرار داخل المجموعة. Options include `primary`, `secondary`, and `tertiary` |
| الحجم | string | حجم الأزرار داخل المجموعة. Has two options: `medium` and `small` |
| accent | نص | لون تمييز الأزرار داخل المجموعة. Options include `default`, `blue` and `danger` |
| className | string | اسم فئة اختياري لتنسيقات إضافية |
| الأبناء | ReactNode | مجموعة من عناصر React تمثل الأزرار الفردية داخل المجموعة |
| الخصائص | النوع | الوصف |
| --------- | --------- | -------------------------------------------------------------------------------------- |
| التنوع | string | النمط المرئي للأزرار داخل المجموعة. تشمل الخيارات `primary`، `secondary`، و`tertiary`. |
| الحجم | string | حجم الأزرار داخل المجموعة. يوجد خياران: `medium` و`small`. |
| accent | نص | لون تمييز الأزرار داخل المجموعة. تشمل الخيارات `default`، `blue` و`danger`. |
| className | string | اسم فئة اختياري لتنسيقات إضافية |
| الأبناء | ReactNode | مجموعة من عناصر React تمثل الأزرار الفردية داخل المجموعة |
</Tab>
</Tabs>
@@ -153,17 +153,17 @@ image: /images/user-guide/views/filter.png
</Tab>
<Tab title="الخصائص">
| الخصائص | النوع | الوصف |
| ------------ | --------------------- | ---------------------------------------------------------------------------------- |
| className | string | اسم اختياري لتنسيقات إضافية |
| أيقونة | `React.ComponentType` | مكون أيقونة اختياري يظهر داخل الزر |
| العنوان | string | محتوى نص الزر |
| الحجم | string | حجم الزر. يوجد خياران: `صغير` و `متوسط` |
| الموقع | string | موقع الزر بالنسبة لأخوته. Options include: `standalone`, `left`, `middle`, `right` |
| تطبيق الظل | قيمة منطقية | يحدد إذا ما سيتم تطبيق الظلال على الزر |
| تطبيق الضباب | قيمة منطقية | يحدد ما إذا كان ينبغي تطبيق تأثير الضباب على الزر |
| معطل | قيمة منطقية | يحدد ما إذا كان الزر معطل |
| تركيز | قيمة منطقية | يحدد إذا كان الزر في وضع التركيز |
| الخصائص | النوع | الوصف |
| ------------ | --------------------- | --------------------------------------------------------------------------------- |
| className | string | اسم اختياري لتنسيقات إضافية |
| أيقونة | `React.ComponentType` | مكون أيقونة اختياري يظهر داخل الزر |
| العنوان | string | محتوى نص الزر |
| الحجم | string | حجم الزر. يوجد خياران: `صغير` و `متوسط` |
| الموقع | string | موقع الزر بالنسبة لأخوته. تشمل الخيارات: `standalone`، `left`، `middle`، `right`. |
| تطبيق الظل | قيمة منطقية | يحدد إذا ما سيتم تطبيق الظلال على الزر |
| تطبيق الضباب | قيمة منطقية | يحدد ما إذا كان ينبغي تطبيق تأثير الضباب على الزر |
| معطل | قيمة منطقية | يحدد ما إذا كان الزر معطل |
| تركيز | قيمة منطقية | يحدد إذا كان الزر في وضع التركيز |
</Tab>
</Tabs>
@@ -242,18 +242,18 @@ image: /images/user-guide/views/filter.png
</Tab>
<Tab title="الخصائص">
| الخصائص | النوع | الوصف |
| ------------ | --------------------- | -------------------------------------------------------------------------------------- |
| className | نص | اسم اختياري لتنسيقات إضافية |
| أيقونة | `React.ComponentType` | مكون أيقونة اختياري يظهر داخل الزر |
| الحجم | نص | حجم الزر. يوجد خياران: `صغير` و `متوسط` |
| الموقع | نص | موقع الزر بالنسبة لأخوته. Options include: `standalone`, `left`, `right`, and `middle` |
| تطبيق الظل | قيمة منطقية | يحدد إذا ما سيتم تطبيق الظلال على الزر |
| تطبيق الضباب | قيمة منطقية | يحدد ما إذا كان ينبغي تطبيق تأثير الضباب على الزر |
| معطل | قيمة منطقية | يحدد ما إذا كان الزر معطل |
| تركيز | قيمة منطقية | يحدد إذا كان الزر في وضع التركيز |
| عند النقر | وظيفة | وظيفة رد فعل تنطلق عند نقر المستخدم على الزر |
| فعّال | قيمة منطقية | يحدد إذا كان الزر في وضع فعّال |
| الخصائص | النوع | الوصف |
| ------------ | --------------------- | ---------------------------------------------------------------------------------- |
| className | نص | اسم اختياري لتنسيقات إضافية |
| أيقونة | `React.ComponentType` | مكون أيقونة اختياري يظهر داخل الزر |
| الحجم | نص | حجم الزر. يوجد خياران: `صغير` و `متوسط` |
| الموقع | نص | موقع الزر بالنسبة لأخوته. تشمل الخيارات: `standalone`، `left`، `right`، و`middle`. |
| تطبيق الظل | قيمة منطقية | يحدد إذا ما سيتم تطبيق الظلال على الزر |
| تطبيق الضباب | قيمة منطقية | يحدد ما إذا كان ينبغي تطبيق تأثير الضباب على الزر |
| معطل | قيمة منطقية | يحدد ما إذا كان الزر معطل |
| تركيز | قيمة منطقية | يحدد إذا كان الزر في وضع التركيز |
| عند النقر | وظيفة | وظيفة رد فعل تنطلق عند نقر المستخدم على الزر |
| فعّال | قيمة منطقية | يحدد إذا كان الزر في وضع فعّال |
</Tab>
</Tabs>
@@ -299,7 +299,7 @@ image: /images/user-guide/views/filter.png
</Tab>
</Tabs>
## Light Button
## زر خفيف
<Tabs>
<Tab title="الاستخدام">
@@ -31,14 +31,14 @@ image: /images/user-guide/tasks/tasks_header.png
</Tab>
<Tab title="المحددات">
| المحددات | النوع | الوصف |
| ------------------------ | ----------- | ------------------------------------------------------------------------------------------- |
| مختار | قيمة منطقية | يشير إلى ما إذا كان مربع الاختيار محددًا |
| indeterminate | قيمة منطقية | Indicates whether the checkbox is in an indeterminate state (neither checked nor unchecked) |
| عند التغيير | دالة | الدالة التي ترغب في تفعيلها عند تغيير حالة مربع الاختيار |
| عند تغيير الحالة المحددة | دالة | The callback function you want to trigger when the `checked` state changes |
| نموذج | نص | النمط البصري للصندوق. تتضمن الخيارات: 'أساسي'، 'ثانوي'، و 'ثالثي' |
| الحجم | نص | حجم مربع الاختيار. Has two options: `small` and `large` |
| الشكل | نص | شكل مربع الاختيار. لديه خياران: 'مربع' و 'مدور' |
| المحددات | النوع | الوصف |
| ------------------------ | ----------- | ----------------------------------------------------------------------------- |
| مختار | قيمة منطقية | يشير إلى ما إذا كان مربع الاختيار محددًا |
| غير محدد | قيمة منطقية | يشير إلى ما إذا كان مربع الاختيار في حالة غير محددة (لا هو محدد ولا غير محدد) |
| عند التغيير | دالة | الدالة التي ترغب في تفعيلها عند تغيير حالة مربع الاختيار |
| عند تغيير الحالة المحددة | دالة | الدالة التي ترغب في تفعيلها عند تغيّر حالة `checked` |
| نموذج | نص | النمط البصري للصندوق. تتضمن الخيارات: 'أساسي'، 'ثانوي'، و 'ثالثي' |
| الحجم | نص | حجم مربع الاختيار. له خياران: `small` و `large` |
| الشكل | نص | شكل مربع الاختيار. لديه خياران: 'مربع' و 'مدور' |
</Tab>
</Tabs>
@@ -21,14 +21,14 @@ image: /images/user-guide/objects/objects.png
</Tab>
<Tab title="المحددات">
| المحددات | النوع | الوصف |
| ------------ | ----------- | ------------------------------------------------------------------------------------------------- |
| صورة | نص | 3946482746 45352F31 274435483129 27442544432A3148464A |
| onUpload | دالة | The function called when a user uploads a new image. It receives the `File` object as a parameter |
| onRemove | دالة | The function called when the user clicks on the remove button |
| onAbort | دالة | The function called when a user clicks on the abort button during image upload |
| isUploading | قيمة منطقية | Indicates whether an image is currently being uploaded |
| errorMessage | نص | An optional error message to display below the image input |
| معطل | قيمة منطقية | If `true`, the entire input is disabled, and the buttons are not clickable |
| المحددات | النوع | الوصف |
| ------------ | ----------- | --------------------------------------------------------------------------------- |
| صورة | نص | 3946482746 45352F31 274435483129 27442544432A3148464A |
| onUpload | دالة | الدالة التي تُستدعى عند قيام المستخدم بتحميل صورة جديدة. تستقبل كائن `File` كوسيط |
| onRemove | دالة | الدالة التي تُستدعى عند نقر المستخدم على زر الإزالة |
| onAbort | دالة | الدالة التي تُستدعى عند نقر المستخدم على زر الإلغاء أثناء تحميل الصورة |
| isUploading | قيمة منطقية | يشير إلى ما إذا كان يتم تحميل صورة حاليًا |
| errorMessage | نص | رسالة خطأ اختيارية لعرضها أسفل حقل إدخال الصورة |
| معطل | قيمة منطقية | إذا كانت `true`، فسيكون حقل الإدخال بأكمله معطلاً، ولن تكون الأزرار قابلة للنقر |
</Tab>
</Tabs>
@@ -16,7 +16,7 @@ image: /images/user-guide/table-views/table.png
return (
<Toggle
value = {true}
onChange = {()=>console.log('On Change event')}
onChange = {()=>console.log('تم تشغيل حدث onChange')}
color="green"
toggleSize = "medium"
/>
@@ -28,8 +28,8 @@ image: /images/user-guide/table-views/table.png
<Tab title="الخصائص">
| الخصائص | النوع | الوصف | الإعداد الافتراضي |
| ----------- | ----------- | --------------------------------------------------------------------------- | ----------------- |
| القيمة | قيمة منطقية | The current state of the toggle | `خاطئ` |
| عند التغيير | دالة | Callback function triggered when the toggle state changes | |
| القيمة | قيمة منطقية | الحالة الحالية لمفتاح التبديل | `خاطئ` |
| عند التغيير | دالة | دالة الاستدعاء التي يتم تحفيزها عند تغيير حالة مفتاح التبديل | |
| اللون | string | لون التبديل عند كونه | لون أزرق |
| حجم التبديل | نص | حجم التبديل الذي يؤثر على كل من الطول والوزن. لديها خياران: `صغير` و`متوسط` | متوسط |
</Tab>
@@ -9,22 +9,22 @@ import { CardTitle } from "/snippets/card-title.mdx"
<CardGroup cols={٢}>
<Card href="/l/ar/twenty-ui/display" img="/images/user-guide/views/filter.png">
<CardTitle>Display</CardTitle>
Display components for showing information visually
<CardTitle>العرض</CardTitle>
مكونات العرض لعرض المعلومات بصريًا
</Card>
<Card href="/l/ar/twenty-ui/progress-bar" img="/images/user-guide/fields/field.png">
<CardTitle>Feedback</CardTitle>
Feedback components for user notifications
<CardTitle>التغذية الراجعة</CardTitle>
مكونات التغذية الراجعة لإبلاغ المستخدمين
</Card>
<Card href="/l/ar/twenty-ui/input" img="/images/user-guide/tips/light-bulb.png">
<CardTitle>Input</CardTitle>
Input components for user interaction
<CardTitle>الإدخال</CardTitle>
مكونات الإدخال لتفاعل المستخدم
</Card>
<Card href="/l/ar/twenty-ui/navigation" img="/images/user-guide/tasks/tasks_header.png">
<CardTitle>Navigation</CardTitle>
Navigation components for user interface
<CardTitle>التنقل</CardTitle>
مكونات التنقل لواجهة المستخدم
</Card>
</CardGroup>
@@ -1,5 +1,5 @@
---
title: Navigation
title: التنقل
image: /images/user-guide/tasks/tasks_header.png
---
@@ -1,5 +1,5 @@
---
title: Breadcrumb
title: مسار التنقّل
image: /images/user-guide/fields/field.png
---
@@ -7,7 +7,7 @@ image: /images/user-guide/fields/field.png
<img src="/images/user-guide/fields/field.png" alt="رأس الصفحة" />
</Frame>
Renders a breadcrumb navigation bar.
يعرض شريط مسار التنقّل.
<Tabs>
<Tab title="استخدام">
@@ -33,9 +33,9 @@ Renders a breadcrumb navigation bar.
</Tab>
<Tab title="المحددات">
| المحددات | النوع | الوصف |
| --------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| اسم الفئة | نص | اسم فئة اختياري لتنسيقات إضافية |
| روابط | مصفوفة | An array of objects, each representing a breadcrumb link. كل كائن يحتوي على خاصية `children` (محتوى النص للرابط) وخاصية `href` اختيارية (رابط URL للتنقل إليه عند النقر على الرابط) |
| المحددات | النوع | الوصف |
| --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| اسم الفئة | نص | اسم فئة اختياري لتنسيقات إضافية |
| روابط | مصفوفة | مصفوفة من الكائنات، يمثّل كلٌّ منها رابطًا في مسار التنقّل. كل كائن يحتوي على خاصية `children` (محتوى النص للرابط) وخاصية `href` اختيارية (رابط URL للتنقل إليه عند النقر على الرابط) |
</Tab>
</Tabs>
@@ -20,7 +20,7 @@ image: /images/user-guide/what-is-twenty/20.png
export const MyComponent = () => {
const handleLinkClick = (event) => {
console.log('Contact link clicked!', event);
console.log('تم النقر على رابط الاتصال!', event);
};
return (
@@ -34,7 +34,7 @@ image: /images/user-guide/what-is-twenty/20.png
</ContactLink>
</Router>
);
};
};},{
```
</Tab>
@@ -42,16 +42,16 @@ image: /images/user-guide/kanban-views/kanban.png
</Tab>
<Tab title="المحددات">
| المحددات | النوع | الوصف |
| -------------- | ------------- | ----------------------------------------------------------------------------------------- |
| أيقونة اليسار | مكون الأيقونة | أيقونة اختيارية تظهر قبل النص في عنصر القائمة |
| accent | نص | Specifies the accent color of the menu item. تشمل الخيارات: `افتراضي`, `خطر`, `موضع مؤقت` |
| نص | نص | المحتوى النصي لعنصر القائمة |
| أزرار الأيقونة | array | مجموعة من الكائنات التي تمثل أيقونات إضافية مرتبطة بعنصر القائمة |
| isTooltipOpen | قيمة منطقية | Controls the visibility of the tooltip associated with the menu item |
| معرف الفحص | نص | السمة data-testid لأغراض الاختبار |
| عند النقر | function | دالة الاستدعاء يتم تنشيطها عند النقر فوق عنصر القائمة |
| اسم الفئة | نص | اسم اختياري لتصميم إضافي |
| المحددات | النوع | الوصف |
| -------------- | ------------- | ---------------------------------------------------------------------------- |
| أيقونة اليسار | مكون الأيقونة | أيقونة اختيارية تظهر قبل النص في عنصر القائمة |
| accent | نص | يحدد لون الإبراز لعنصر القائمة. تشمل الخيارات: `افتراضي`, `خطر`, `موضع مؤقت` |
| نص | نص | المحتوى النصي لعنصر القائمة |
| أزرار الأيقونة | array | مجموعة من الكائنات التي تمثل أيقونات إضافية مرتبطة بعنصر القائمة |
| isTooltipOpen | قيمة منطقية | يتحكم في ظهور تلميح الأدوات المرتبط بعنصر القائمة |
| معرف الفحص | نص | السمة data-testid لأغراض الاختبار |
| عند النقر | function | دالة الاستدعاء يتم تنشيطها عند النقر فوق عنصر القائمة |
| اسم الفئة | نص | اسم اختياري لتصميم إضافي |
</Tab>
</Tabs>
@@ -90,15 +90,15 @@ image: /images/user-guide/kanban-views/kanban.png
</Tab>
<Tab title="الخصائص">
| الخصائص | النوع | الوصف |
| --------------- | ------------- | -------------------------------------------------------- |
| الأيقونة اليسرى | مكون الأيقونة | أيقونة اختيارية إذا ظهرت قبل النص في عنصر القائمة |
| نص | نص | محتوى النص لعنصر القائمة |
| firstHotKey | string | أول اختصار لوحة مفاتيح مرتبط بالأمر |
| secondHotKey | string | The second keyboard shortcut associated with the command |
| isSelected | قيمة منطقية | يشير إلى ما إذا كان عنصر القائمة محددا أو مميزا |
| عند النقر | دالة | دالة الاستدعاء يتم تنشيطها عند النقر فوق عنصر القائمة |
| اسم الفئة | نص | اسم اختياري لإضافة التنسيق |
| الخصائص | النوع | الوصف |
| --------------- | ------------- | ----------------------------------------------------- |
| الأيقونة اليسرى | مكون الأيقونة | أيقونة اختيارية إذا ظهرت قبل النص في عنصر القائمة |
| نص | نص | محتوى النص لعنصر القائمة |
| firstHotKey | string | أول اختصار لوحة مفاتيح مرتبط بالأمر |
| secondHotKey | string | اختصار لوحة المفاتيح الثاني المرتبط بالأمر |
| isSelected | قيمة منطقية | يشير إلى ما إذا كان عنصر القائمة محددا أو مميزا |
| عند النقر | دالة | دالة الاستدعاء يتم تنشيطها عند النقر فوق عنصر القائمة |
| اسم الفئة | نص | اسم اختياري لإضافة التنسيق |
</Tab>
</Tabs>
@@ -135,16 +135,16 @@ image: /images/user-guide/kanban-views/kanban.png
</Tab>
<Tab title="الخصائص">
| الخصائص | النوع | الوصف |
| --------------- | ------------- | -------------------------------------------------------------------------------- |
| الأيقونة اليسرى | مكون الأيقونة | أيقونة اختيارية تظهر قبل النص في عنصر القائمة |
| accent | نص | لون العنصر لهجة القائمة. It can either be `default`, `placeholder`, and `danger` |
| أزرار الأيقونات | array | مصفوفة الكائنات التي تمثل أزرار الأيقونات الإضافية المرتبطة بعنصر القائمة |
| isTooltipOpen | قيمة منطقية | Controls the visibility of the tooltip associated with the menu item |
| عند_النقر | دالة | وظيفة استدعاء ليتم تشغيلها عند النقر فوق الرابط |
| نص | نص | محتوى النص لعنصر القائمة |
| isDragDisabled | قيمة منطقية | يشير إلى ما إذا كان تم تعطيل السحب |
| اسم الفئة | نص | اسم اختياري لإضافة التنسيق |
| الخصائص | النوع | الوصف |
| --------------- | ------------- | ------------------------------------------------------------------------------------- |
| الأيقونة اليسرى | مكون الأيقونة | أيقونة اختيارية تظهر قبل النص في عنصر القائمة |
| accent | نص | لون العنصر لهجة القائمة. يمكن أن يكون إحدى القيم: `default`، `placeholder`، و`danger` |
| أزرار الأيقونات | array | مصفوفة الكائنات التي تمثل أزرار الأيقونات الإضافية المرتبطة بعنصر القائمة |
| isTooltipOpen | قيمة منطقية | يتحكم في ظهور تلميح الأدوات المرتبط بعنصر القائمة |
| عند_النقر | دالة | وظيفة استدعاء ليتم تشغيلها عند النقر فوق الرابط |
| نص | نص | محتوى النص لعنصر القائمة |
| isDragDisabled | قيمة منطقية | يشير إلى ما إذا كان تم تعطيل السحب |
| اسم الفئة | نص | اسم اختياري لإضافة التنسيق |
</Tab>
</Tabs>
@@ -183,7 +183,7 @@ image: /images/user-guide/kanban-views/kanban.png
</Tab>
</Tabs>
### Multi Select Avatar
### التحديد المتعدد للصورة الرمزية
عنصر قائمة متعدد الخيارات مع صورة رمزية، ومربع اختيار للتحديد، ومحتوى نصي.
@@ -221,7 +221,7 @@ image: /images/user-guide/kanban-views/kanban.png
### التنقل
A menu item featuring an optional left icon, textual content, and a right-chevron icon.
عنصر قائمة يتضمن أيقونة يسارية اختيارية، محتوى نصي، وأيقونة سهم إلى اليمين.
<Tabs>
<Tab title="الاستخدام">
@@ -299,9 +299,9 @@ A menu item featuring an optional left icon, textual content, and a right-chevro
</Tab>
</Tabs>
### Select Avatar
### اختيار الصورة الرمزية
A selectable menu item with an avatar, featuring optional left content (avatar and text) and an indicator (check icon) for the selected state.
عنصر قائمة قابل للتحديد مع صورة رمزية، يتضمن محتوى يسارياً اختيارياً (صورة رمزية ونصاً) ومؤشراً (أيقونة التحقق) لحالة التحديد.
<Tabs>
<Tab title="الاستخدام">
@@ -310,16 +310,16 @@ A selectable menu item with an avatar, featuring optional left content (avatar a
export const MyComponent = () => {
const imageUrl =
"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAYABgAAD/4QCMRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABgAAAAAQAAAGAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABSgAwAEAAAAAQAAABQAAAAA/8AAEQgAFAAUAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMACwgICggHCwoJCg0MCw0RHBIRDw8RIhkaFBwpJCsqKCQnJy0yQDctMD0wJyc4TDk9Q0VISUgrNk9VTkZUQEdIRf/bAEMBDA0NEQ8RIRISIUUuJy5FRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRf/dAAQAAv/aAAwDAQACEQMRAD8Ava1q728otYY98joSCTgZrnbXWdTtrhrfVZXWLafmcAEkdgR/hVltQku9Q8+OIEBcGOT+ID0PY1ka1KH2u8ToqnPLbmIqG7u6LtbQ7RXBRec4Uck9eKXcPWsKDWVnhWSL5kYcFelSf2m3901POh8jP//QoyIAnTuKpXsY82NsksUyWPU5q/L9z8RVK++/F/uCsVsaEURwgA4HtT9x9TUcf3KfUGh//9k=";
"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAYABgAAD/4QCMRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABgAAAAAQAAAGAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABSgAwAEAAAAAQAAABQAAAAA/8AAEQgAFAAUAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6OnqvLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMACwgICggHCwoJCg0MCw0RHBIRDw8RIhkaFBwpJCsqKCQnJy0yQDctMD0wJyc4TDk9Q0VISUgrNk9VTkZUQEdIRf/bAEMBDA0NEQ8RIRISIUUuJy5FRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRf/dAAQAAv/aAAwDAQACEQMRAD8Ava1q728otYY98joSCTgZrnbXWdTtrhrfVZXWLafmcAEkdgR/hVltQku9Q8+OIEBcGOT+ID0PY1ka1KH2u8ToqnPLbmIqG7u6LtbQ7RXBRec4Uck9eKXcPWsKDWVnhWSL5kYcFelSf2m3901POh8jP//QoyIAnTuKpXsY82NsksUyWPU5q/L9z8RVK++/F/uCsVsaEURwgA4HtT9x9TUcf3KfUGh//9k=";
const handleSelection = () => {
console.log("Menu item selected");
console.log("تم تحديد عنصر القائمة");
};
return (
<MenuItemSelectAvatar
avatar={<img src={imageUrl} alt="Avatar" />}
text="First Option"
avatar={<img src={imageUrl} alt="الصورة الرمزية" />}
text="الخيار الأول"
selected={true}
disabled={false}
hovered={false}
@@ -349,7 +349,7 @@ A selectable menu item with an avatar, featuring optional left content (avatar a
### اختيار اللون
A selectable menu item with a color sample for scenarios where you want users to choose a color from a menu.
عنصر قائمة قابل للتحديد يتضمن عينة لون للسيناريوهات التي تريد فيها من المستخدمين اختيار لون من القائمة.
<Tabs>
<Tab title="الاستخدام">
@@ -383,7 +383,7 @@ A selectable menu item with a color sample for scenarios where you want users to
| المحدد | قيمة منطقية | يشير إلى ما إذا كان عنصر القائمة محددًا (مفحوص) |
| تعطيل | قيمة منطقية | يشير إلى ما إذا كان عنصر القائمة معطلاً |
| معلق عليه | قيمة منطقية | يشير إلى ما إذا كان يتم التحويم حاليًا على عنصر القائمة |
| البديل | نص | The variant of the color sample. يمكن أن يكون إما `افتراضي` أو `خط أنابيب` |
| البديل | نص | المتغير لعينة اللون. يمكن أن يكون إما `افتراضي` أو `خط أنابيب` |
| عند_النقر | دالة | دالة الاستدعاء التي يتم تحفيزها عند النقر على عنصر القائمة |
| اسم الفئة | نص | اسم اختياري للتنسيق الإضافي. |
</Tab>
@@ -33,7 +33,7 @@ image: /images/user-guide/emails/emails_header.png
| المحددات | النوع | الوصف | الإعداد الافتراضي |
| ---------------- | ----------- | ------------------------------------------------------------------------------- | ----------------- |
| المدة | رقم | إجمالي مدة الرسوم المتحركة لشريط التقدم بالميلي ثانية | 3 |
| التأخير | رقم | The delay in starting the progress bar animation in milliseconds | 0 |
| التأخير | رقم | التأخير في بدء الرسوم المتحركة لشريط التقدم بالميلي ثانية | 0 |
| التخفيف | نص | وظيفة التخفيف للرسوم المتحركة لشريط التقدم | easeInOut |
| ارتفاع الشريط | رقم | ارتفاع الشريط بالبكسل | 24 |
| لون الشريط | نص | لون الشريط | gray80 |
@@ -1,34 +1,34 @@
---
title: AI Agents
description: Integrate AI capabilities directly into your automation workflows.
title: وكلاء الذكاء الاصطناعي
description: ادمج قدرات الذكاء الاصطناعي مباشرةً في سير العمل المؤتمت لديك.
---
<Note>
This feature is in development and will be available in beta soon.
هذه الميزة قيد التطوير حالياً وستكون متاحة في النسخة التجريبية قريباً.
</Note>
## نظرة عامة
Integrate AI capabilities directly into your automation workflows for intelligent data processing and decision-making.
ادمج قدرات الذكاء الاصطناعي مباشرةً في سير العمل المؤتمت لديك لمعالجة البيانات بذكاء واتخاذ القرارات.
## Capabilities
## القدرات
| Feature | الوصف |
| ------------------- | ------------------------------------------------ |
| **AI actions** | Add AI-powered steps to any workflow |
| **Data enrichment** | Automatically enhance records with external data |
| **Classification** | Categorize records based on content analysis |
| **Summarization** | Generate summaries from text fields |
| **Custom prompts** | Define exactly how AI processes your data |
| الميزة | الوصف |
| ---------------------------- | -------------------------------------------------- |
| **إجراءات الذكاء الاصطناعي** | أضِف خطوات مدعومة بالذكاء الاصطناعي إلى أي سير عمل |
| **إثراء البيانات** | تحسين السجلات تلقائيًا ببيانات خارجية |
| **التصنيف** | تصنيف السجلات استنادًا إلى تحليل المحتوى |
| **التلخيص** | إنشاء ملخصات من حقول النص |
| **مطالبات مخصصة** | حدِّد بدقة كيف يعالج الذكاء الاصطناعي بياناتك |
## Use Cases
## حالات الاستخدام
* **Lead scoring**: Automatically score and prioritize inbound leads
* **Data cleanup**: Standardize company names and contact information
* **Email drafts**: Generate follow-up emails based on meeting notes
* **Record routing**: Assign records to the right team member based on content
* **تقييم العملاء المحتملين**: تقييم العملاء المحتملين الواردين تلقائيًا وتحديد أولوياتهم
* **تنظيف البيانات**: توحيد أسماء الشركات ومعلومات الاتصال
* **مسودات البريد الإلكتروني**: إنشاء رسائل متابعة عبر البريد الإلكتروني استنادًا إلى ملاحظات الاجتماعات
* **توجيه السجلات**: إسناد السجلات إلى عضو الفريق المناسب بناءً على المحتوى
## Related
## ذات صلة
* [Workflows Overview](/l/ar/user-guide/workflows/overview) — automation basics
* [AI Permissions](/l/ar/user-guide/ai/capabilities/permissions-access-control) — access control for AI agents
* [نظرة عامة على سير العمل](/l/ar/user-guide/workflows/overview) — أساسيات الأتمتة
* [أذونات الذكاء الاصطناعي](/l/ar/user-guide/ai/capabilities/permissions-access-control) — التحكم في الوصول لوكلاء الذكاء الاصطناعي
@@ -1,41 +1,41 @@
---
title: AI Chatbot
description: An intelligent assistant that helps you interact with your CRM data using natural language.
title: روبوت محادثة بالذكاء الاصطناعي
description: مساعد ذكي يساعدك على التفاعل مع بيانات إدارة علاقات العملاء باستخدام اللغة الطبيعية.
---
<Note>
This feature is in development and will be available in beta soon.
هذه الميزة قيد التطوير حالياً وستكون متاحة في النسخة التجريبية قريباً.
</Note>
## نظرة عامة
An intelligent assistant that helps you interact with your CRM data using natural language.
مساعد ذكي يساعدك على التفاعل مع بيانات إدارة علاقات العملاء باستخدام اللغة الطبيعية.
## Capabilities
## القدرات
| Feature | الوصف |
| ---------------------------- | ------------------------------------------------------------------------- |
| **Natural language queries** | Ask questions in plain English instead of building filters |
| **Full data access** | Query records, relationships, and metrics across your workspace |
| **Page context** | Reference "this company" or "this opportunity" based on your current view |
| **Conversational** | Follow-up questions maintain context from previous queries |
| الميزة | الوصف |
| ----------------------------- | ----------------------------------------------------------------- |
| **استعلامات باللغة الطبيعية** | اطرح أسئلة باللغة الإنجليزية البسيطة بدلاً من إنشاء عوامل تصفية |
| **وصول كامل إلى البيانات** | استعلم عن السجلات والعلاقات والمقاييس عبر مساحة عملك |
| **سياق الصفحة** | الإشارة إلى "هذه الشركة" أو "هذه الفرصة" استناداً إلى عرضك الحالي |
| **حواري** | تحافظ الأسئلة اللاحقة على السياق من الاستعلامات السابقة |
## Example Interactions
## أمثلة على التفاعلات
### Finding Records
### العثور على السجلات
* "Show me all opportunities over $50,000"
* "Find contacts I haven't emailed in 2 weeks"
* "List companies in the healthcare industry"
* "اعرض لي كل الفرص التي تزيد عن $50,000"
* "ابحث عن جهات الاتصال التي لم أرسل لها بريد إلكتروني منذ أسبوعين"
* "اسرد الشركات في قطاع الرعاية الصحية"
### Getting Insights
### الحصول على رؤى
* "What's my total pipeline value?"
* "How many deals closed last month?"
* "Which stage has the most stuck opportunities?"
* "ما القيمة الإجمالية لمسار المبيعات لدي?"
* "كم عدد الصفقات التي أبرمت الشهر الماضي?"
* "أي مرحلة تضم أكبر عدد من الفرص العالقة?"
### Using Page Context
### استخدام سياق الصفحة
* "Summarize my interactions with this person" (on a contact page)
* "What opportunities are linked to this company?" (on a company page)
* "When was this deal last updated?" (on an opportunity page)
* "لخص تفاعلاتي مع هذا الشخص" (على صفحة جهة اتصال)
* "ما الفرص المرتبطة بهذه الشركة?" (على صفحة شركة)
* "متى جرى آخر تحديث لهذه الصفقة?" (على صفحة فرصة)
@@ -1,22 +1,22 @@
---
title: Billing FAQ
description: Frequently asked questions about Twenty pricing and billing.
title: الأسئلة الشائعة حول الفوترة
description: الأسئلة الشائعة حول تسعير Twenty والفوترة.
---
## التسعير
<AccordionGroup>
<Accordion title="هل يمكنني استخدام Twenty مجانًا أثناء الاستضافة الذاتية؟">
نعم، يمكنك استخدام Twenty مجانًا أثناء الاستضافة الذاتية. You will get access to everything included in the Pro (Cloud) plan, except the support from our core-team. الدعم متاح عبر مجتمعنا في Discord.
نعم، يمكنك استخدام Twenty مجانًا أثناء الاستضافة الذاتية. ستحصل على إمكانية الوصول إلى كل ما هو مضمّن في خطة Pro (السحابة)، باستثناء الدعم من فريقنا الأساسي. الدعم متاح عبر مجتمعنا في Discord.
If you want to self-host and need the Premium features (SSO and row-level permissions), you can choose the paid Organization (Self-Hosted) license. This also includes support from the Twenty team and removes the requirement to publish custom code as open-source before distributing.
إذا كنت تريد الاستضافة الذاتية وتحتاج إلى الميزات المتميزة (SSO وأذونات على مستوى السجل)، فيمكنك اختيار ترخيص Organization (الاستضافة الذاتية) المدفوع. يشمل ذلك أيضًا دعمًا من فريق Twenty ويلغي شرط نشر الشيفرة المخصصة كمصدر مفتوح قبل التوزيع.
</Accordion>
<Accordion title="What are the Premium features?">
Premium features are only available on the Organization plans (Cloud or Self-Hosted):
<Accordion title="ما هي الميزات المتميزة؟">
لا تتوفر الميزات المتميزة إلا في خطط Organization (السحابة أو الاستضافة الذاتية):
* **SSO integration**: Single Sign-On with your identity provider
* **Row-level permissions**: Fine-grained access control at the record level
* **تكامل SSO**: تسجيل الدخول الأحادي مع موفر الهوية لديك
* **أذونات على مستوى السجل**: تحكم دقيق في الوصول على مستوى السجل
</Accordion>
<Accordion title="هل تقدمون مقاعد مجانية للمستخدمين العارضين فقط؟">
@@ -43,18 +43,18 @@ description: Frequently asked questions about Twenty pricing and billing.
ستجد ذلك ضمن `الإعدادات → الفوترة`.
</Accordion>
<Accordion title="How many workflow credits do we have?">
The number of credits depends on your billing cycle, not your plan:
<Accordion title="كم عدد أرصدة سير العمل لدينا؟">
يعتمد عدد الأرصدة على دورة الفوترة لديك، وليس على خطتك:
* **Monthly subscriptions**: 5 million credits per month
* **Yearly subscriptions**: 50 million credits per year
* **الاشتراكات الشهرية**: 5 ملايين رصيد شهريًا
* **الاشتراكات السنوية**: 50 مليون رصيد سنويًا
</Accordion>
<Accordion title="كيف يعمل استهلاك رصيد سير العمل؟">
يستهلك كل إجراء سير عمل الرصيد بناءً على تعقيده.
* **العمليات الداخلية الأساسية** (مثل البحث والتحديث وإنشاء السجلات) تستهلك عدد قليل من الأرصدة
* **More complex operations** like code nodes and requests to external services consume more credits
* **عمليات أكثر تعقيدًا** مثل عقد الشيفرة والطلبات إلى الخدمات الخارجية تستهلك مزيدًا من الأرصدة
* **طلبات الذكاء الاصطناعي** (قريبًا!) ستستهلك أيضًا المزيد من الأرصدة بناءً على الاستخدام
يتم خصم الأرصدة فورًا عند تنفيذ سير العمل. يمكنك متابعة استخدامك في **الإعدادات → الفوترة** لمتابعة الاستهلاك والأرصدة المتبقية.
@@ -47,15 +47,15 @@ description: فهم ميزات تكامل البريد الإلكتروني في
## سلوك مزامنة البريد الإلكتروني
### Sync Rate
### معدل المزامنة
Twenty imports emails at approximately **400 messages per minute**. This rate is currently limited by Gmail API rate limiting (and applies similarly to other providers).
يقوم Twenty باستيراد رسائل البريد الإلكتروني بمعدل يقارب **400 رسالة في الدقيقة**. يُقيَّد هذا المعدل حاليًا بواسطة تقييد المعدل في Gmail API (وينطبق بالمثل على الموفّرين الآخرين).
For reference:
للمرجع:
* 1,000 emails → ~2.5 minutes
* 10,000 emails → ~25 minutes
* 50,000 emails → ~2 hours
* 1,000 رسالة بريد إلكتروني → ~2.5 دقيقة
* 10,000 رسالة بريد إلكتروني → ~25 دقيقة
* 50,000 رسالة بريد إلكتروني → ~ساعتين
### ما الذي يتم مزامنته
@@ -70,12 +70,12 @@ For reference:
* **البريد الجماعي**: يتم استبعاد قوائم التوزيع والرسائل البريدية الجماعية
* **المجلدات المستبعدة**: يتم استبعاد المجلدات التي اخترت عدم مزامنتها (تم تكوينها تحت الإعدادات → الحسابات → البريد الإلكتروني)
### Selective Folder Sync
### مزامنة المجلدات الانتقائية
تحكم بما تم مزامنته من مجلدات البريد الإلكتروني مع Twenty:
1. Go to **Settings → Accounts** and select your connected email account
2. Configure folders under the Email section
1. انتقل إلى **الإعدادات → الحسابات** ثم اختر حساب البريد الإلكتروني المتصل
2. قم بإعداد المجلدات ضمن قسم البريد الإلكتروني
3. اختر مجلدات معينة لتضمينها أو استبعادها (البريد الوارد، المرسل، الأرشيف، المجلدات المخصصة)
## استكشاف مشكلات مزامنة البريد الإلكتروني
@@ -25,7 +25,7 @@ description: اربط عدة حسابات بريد إلكتروني لمستخد
* **عرض البريد الإلكتروني**: اختر ما يمكن لزملائك رؤيته
* **الإنشاء التلقائي لجهات الاتصال**: تمكين/تعطيل لكل صندوق بريد
* **Folder selection**: Choose which folders to sync
* **اختيار المجلدات**: اختر المجلدات التي تريد مزامنتها
## كيف تظهر رسائل البريد الإلكتروني
@@ -68,11 +68,11 @@ image: /images/user-guide/emails/emails_header.png
<Note>When enabled, contacts are automatically linked to their Company records based on their email domain. If the company doesn't exist yet, Twenty creates it for you.</Note>
### Control which emails get synced with Message Folder Selection
### التحكم بالرسائل التي تتم مزامنتها من خلال اختيار مجلد الرسائل
تحكم بما تم مزامنته من مجلدات البريد الإلكتروني مع Twenty:
1. Go to **Settings → Accounts** and select your connected email account
1. انتقل إلى **الإعدادات → الحسابات** ثم حدِّد حساب بريدك الإلكتروني المتصل.
2. اختر المجلدات التي تريد مزامنتها:
* **البريد الوارد**: رسائل البريد الأولية الواردة
* **بريد مرسل**: رسائل البريد الصادرة التي قمت بإرسالها
@@ -121,7 +121,7 @@ image: /images/user-guide/emails/emails_header.png
**التحديثات كل 5 دقائق**: تتم مزامنة البيانات البريدية والتقويمية تلقائيًا كل 5 دقائق بعد الاستيراد الأولي.
<Note>
**Initial sync timing**: Calendar sync completes quickly (usually within minutes), while email sync takes longer for large mailboxes. Twenty imports emails at approximately **400 messages per minute** (limited by Gmail API rate limiting), so a mailbox with 10,000 emails takes about 25 minutes. Don't worry if you see contacts from calendar events appearing before your email contacts; this is normal behavior.
**توقيت المزامنة الأولية**: يكتمل تزامن التقويم بسرعة (عادةً خلال دقائق)، بينما تستغرق مزامنة البريد الإلكتروني وقتاً أطول لصناديق البريد الكبيرة. يقوم Twenty باستيراد رسائل البريد الإلكتروني بمعدل يقارب **400 رسالة في الدقيقة** (محدود بتقييد المعدل من Gmail API)، لذا فإن صندوق بريد يحتوي على 10,000 رسالة يستغرق حوالي 25 دقيقة. Don't worry if you see contacts from calendar events appearing before your email contacts; this is normal behavior.
</Note>
## الخطوات التالية
@@ -0,0 +1,275 @@
---
title: Chart Settings
description: Configure your charts to display data exactly how you need it.
---
import { ChartIcon } from '/snippets/chart-icon.mdx';
## Accessing Chart Settings
1. Click the **Edit** button in the top-right corner of your dashboard
<img src="/images/user-guide/dashboard/dashboard-edit.png" alt="Edit mode" />
2. The dashboard enters edit mode
3. Click on any widget to select it
4. The settings panel opens on the right
Settings are organized into sections:
* **Data**: What data to pull and how to filter it
* **X axis**: How to group and sort categories (bar/line charts)
* **Y axis**: What to measure and how to display it (bar/line charts)
* **Style**: Colors, labels, and visual options
<Note>
Some settings only appear when other settings are configured. For example, **Date granularity** only appears when you select a date field.
</Note>
---
## Data Settings
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="database" />Source </span>
Choose which object to pull data from.
1. Click **Source**
2. Select an object (Opportunities, People, Companies, etc.)
All your standard and custom objects are available. Changing the source resets other settings since field options depend on the selected object.
<img src="/images/user-guide/dashboard/dashboard-chart-settings-source.png" alt="المصدر" />
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="filter" />Filter </span>
Limit which records are included in the chart.
1. انقر على **تصفية**
2. The filter builder opens
3. Click **+ Add filter**
4. Select a field, condition, and value
5. Add more filters as needed
Filters work the same as in table views. Use them to focus on specific segments of your data.
**Example**: Filter opportunities where Stage equals "Won" to show only closed deals.
<img src="/images/user-guide/dashboard/dashboard-chart-settings-filters.png" alt="تصفية" />
<Tip>
For date fields, try **Is relative** to create dynamic filters like "Past 7 days" or "This month" that automatically update.
</Tip>
<Tip>
Advanced filters are supported—add multiple filter rules and combine them with **And** or **Or** logic.
</Tip>
---
## X Axis Settings
These settings control the horizontal axis of bar and line charts—typically how your data is grouped into categories.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="axis-x" />Data on display </span>
Select the field to group your data by. This determines the categories shown on the X axis.
**Example**: Select "Stage" to see data grouped by pipeline stage, or "Created date" to see data over time.
<img src="/images/user-guide/dashboard/dashboard-chart-settings-x-data-on-display.png" alt="البيانات المعروضة" />
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="calendar" />Date granularity </span>
When grouping by a date field, choose the time period for grouping.
| الخيار | Groups data by | Example output |
| ------------------- | -------------------- | --------------------------------------------- |
| **Day** | Each calendar day | Jan 1, Jan 2, Jan 3... |
| **Week** | Calendar weeks | Week 1, Week 2, Week 3... |
| **Month** | Calendar months | January, February, March... |
| **Quarter** | Fiscal quarters | Q1, Q2, Q3, Q4 |
| **Year** | Calendar years | 2023, 2024, 2025 |
| **Day of week** | Weekday (aggregated) | Monday, Tuesday... (all Mondays combined) |
| **Month of year** | Month (aggregated) | January, February... (all Januaries combined) |
| **Quarter of year** | Quarter (aggregated) | Q1, Q2, Q3, Q4 (all Q1s combined) |
The "of week/year" options aggregate across all time. Use **Day of week** to see which weekday typically gets the most deals. Use **Month** to see trends month by month.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="arrows-sort" />Sort by </span>
Control the order of categories on the X axis.
* **Position** Uses the order defined in your Select field settings
* **Alphabetical** A to Z (or chronological for dates)
* **By value** Ordered by the metric (highest or lowest first)
* **Manual** Drag to set your own order
<img src="/images/user-guide/dashboard/dashboard-chart-settings-x-sort.png" alt="الترتيب حسب" />
**Tip**: For pipeline stages, use **Position** to show stages in your sales process order (Lead → Qualified → Proposal → Won).
<Note>
The options shown depend on your field type. Select fields have all options; date and text fields show fewer.
</Note>
<Tip>
With **Manual** sorting, drag categories to create a custom order—perfect for highlighting specific segments or telling a story with your data.
</Tip>
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="eye-off" />Omit zero values </span>
Hide categories that have zero or no data.
* **On**: Categories with no records are hidden
* **Off**: All categories are shown, even if empty
Use this to clean up charts with sparse data.
---
## Y Axis Settings
These settings control what you're measuring and how it's displayed.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="axis-y" />Data on display </span>
Select the field and operation to calculate your metric.
* **Counts** Count all, Count empty, Count not empty, Count unique values
* **Math** Sum, Average, Min, Max (number fields)
* **Percentages** Percent empty, Percent not empty
Boolean fields add Count true/false. Aggregate charts with date fields show Earliest/Latest.
**Example**: Select "Amount" with Sum to see total deal value per category, or Count all to see number of deals.
<img src="/images/user-guide/dashboard/dashboard-chart-settings-y-data-on-display.png" alt="البيانات المعروضة" />
<Note>
The options shown depend on your field and chart type. If you don't see an expected operation, check your field type.
</Note>
### النسبة
For Select, Multi-select, or Boolean fields, you can calculate the percentage of a specific value.
1. Select a Select, Multi-select, or Boolean field
2. Enable **Ratio**
3. Choose the option to measure
**Example**: Show "Won" deals as a percentage of all opportunities. If you have 10 Won out of 50 total, the chart shows 20%.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="filters" />Group by </span>
Add a second dimension to create multiple series (multiple bars or lines).
1. Set your X axis field first
2. Click **Group by**
3. Select a second field
**Example**: Group deals by Stage (X axis) AND by Owner (Group by) to see each person's pipeline breakdown side by side.
<img src="/images/user-guide/dashboard/dashboard-chart-settings-y-group-by.png" alt="المجموعة حسب" />
When Group by is set, you'll see multiple colors in your chart and a legend appears.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="calendar" />Date granularity </span>
When Group by is a date field, choose the time period (same options as X axis).
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="arrows-sort" />Sort by </span>
When **Group by** is set, control the order of grouped series (e.g., which owner's bar appears first within each category).
Same options as X axis sorting—Position, Alphabetical, and Manual—except **value-based sorting is not available** for secondary grouping.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="chart-bar-popular" />Cumulative </span>
Show running totals instead of individual values.
* **Off**: Each bar/point shows its own value
* **On**: Each bar/point shows the sum of all previous values plus its own
**Example**: January = 10, February = 15
* Cumulative off: Shows 10 and 15
* Cumulative on: Shows 10 and 25 (10 + 15)
Use cumulative to track progress toward a goal over time.
<img src="/images/user-guide/dashboard/dashboard-chart-settings-y-cumulative.png" alt="تراكمي" />
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="math-min" />Min range / <ChartIcon icon="math-max" />Max range </span>
Set fixed minimum and maximum values for the Y axis.
* Leave blank for automatic scaling
* Enter a number to fix the boundary
**When to use:**
* Set Min to 0 for accurate visual comparisons
* Set both for consistent scales across multiple charts
* Focus on a specific value range by setting both
---
## Style Settings
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="color-swatch" />Colors </span>
Set the color scheme for your chart. Choose from a variety of color palettes.
<Note>
When grouping by a Select field, the chart automatically uses the colors defined for each option in your field settings.
</Note>
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="gizmo" />Axis name </span>
Choose which axis labels to show: **None**, **X axis**, **Y axis**, or **Both** (bar and line charts only).
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="stack-2" />Stacked bars / Stacked lines </span>
When Group by is set, choose how multiple series are displayed.
* **Off (Grouped)**: Series appear side by side. Use when comparing exact values between groups.
* **On (Stacked)**: Series stack on top of each other. Use when showing composition—how parts make up a whole.
**Example**: Deals by stage, grouped by owner
* Grouped: See each owner's exact numbers side by side
* Stacked: See total deals per stage, with each owner's contribution stacked
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="badge-2k" />Data labels </span>
Show values directly on chart elements (bars, points, slices).
* **On**: Values appear on the chart
* **Off**: No values shown (cleaner look)
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="text-caption" />Legend </span>
Show or hide the legend (only appears when Group by is set).
* **On**: Legend shows what each color represents
* **Off**: No legend displayed
<Tip>
**Hover** over a legend item to highlight that group. **Click** to temporarily hide it from the chart.
</Tip>
---
## Chart-Specific Notes
### مخططات دائرية
* <span style={{ display: 'inline-flex', verticalAlign: 'middle' }}><ChartIcon icon="chart-pie" size={16} /></span> **Each slice represents** Define how slices are grouped
* <span style={{ display: 'inline-flex', verticalAlign: 'middle' }}><ChartIcon icon="eye-off" size={16} /></span> **Hide empty category** Remove zero-value slices
* <span style={{ display: 'inline-flex', verticalAlign: 'middle' }}><ChartIcon icon="number-123" size={16} /></span> **Show value in center** Display the aggregate value (sum, average, count, etc.)
### Aggregate charts
* <span style={{ display: 'inline-flex', verticalAlign: 'middle' }}><ChartIcon icon="caret-left" size={16} /></span> **Prefix** Add text before the number (e.g., `$`)
* <span style={{ display: 'inline-flex', verticalAlign: 'middle' }}><ChartIcon icon="caret-right" size={16} /></span> **Suffix** Add text after the number (e.g., `%`)
@@ -10,7 +10,10 @@ description: أنشئ ونظّم لوحات المعلومات باستخدام
## إنشاء لوحة معلومات
1. انتقل إلى **لوحات المعلومات** في شريط التنقل
2. انقر **+ لوحة معلومات جديدة**
2. انقر **+ سجل جديد**
<img src="/images/user-guide/dashboard/dashboard-create-new.png" alt="Create a new dashboard" />
3. امنح لوحة المعلومات اسمًا
4. ابدأ بإضافة علامات تبويب وعناصر واجهة مستخدم
@@ -20,15 +23,28 @@ description: أنشئ ونظّم لوحات المعلومات باستخدام
### إنشاء علامات تبويب
1. في وضع التحرير، انقر **+ إضافة علامة تبويب**
1. In edit mode, click **+** in the tab bar, side panel will open on the right
2. قم بتسمية علامة التبويب (مثل: "نظرة عامة على خط المبيعات"، "أداء الفريق")
3. أضف عناصر واجهة مستخدم إلى علامة التبويب
### Reordering Tabs
1. In edit mode, click and hold on the tab you want to move
2. Drag and drop to the new position
3. You can also click on the tab and use the command menu to move the tab to left or right
### Deleting Tabs
1. In edit mode, click on the tab you want to delete
2. Click the **Delete** button in the command menu
### تكرار علامات التبويب
1. انقر على علامة التبويب التي تريد تكرارها
2. انقر على زر **تكرار** في اللوحة الجانبية
<img src="/images/user-guide/dashboard/dashboard-tabs.png" alt="Dashboard tab" />
## تخطيط لوحة المعلومات
### ترتيب عناصر واجهة المستخدم
@@ -39,10 +55,12 @@ description: أنشئ ونظّم لوحات المعلومات باستخدام
### تكرار لوحة معلومات
1. اخرج من وضع التحرير (وضع العرض فقط)
1. Select the dashboard you want to duplicate
2. افتح شريط الأوامر باستخدام **Cmd + K** (أو **Ctrl + K** على Windows)
3. اختر **تكرار لوحة المعلومات**
<img src="/images/user-guide/dashboard/dashboard-duplicate.png" alt="Duplicate a dashboard" />
### أفضل الممارسات
* **التسلسل المنطقي**: رتّب من النظرة العامة إلى التفاصيل
@@ -3,14 +3,20 @@ title: الأدوات
description: استكشف أنواع الأدوات وخيارات التصوّر في Twenty.
---
import { ChartIcon } from '/snippets/chart-icon.mdx';
## الأدوات المتاحة
يوفّر Twenty أنواعًا متعددة من الأدوات لتصوُّر بيانات إدارة علاقات العملاء (CRM).
### مخططات الأعمدة
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="chart-bar-popular" />Bar Charts</span>
اعرض البيانات كأعمدة أفقية أو عمودية.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-bar-chart.png" alt="Bar chart" />
</Frame>
**الأفضل لـ:**
* مقارنة القيم عبر الفئات
@@ -24,13 +30,17 @@ description: استكشف أنواع الأدوات وخيارات التصوّ
* جهات الاتصال المضافة شهريًا
<Note>
**حدود العرض**: يمكن لمخططات الأعمدة عرض حد أقصى يبلغ 100 عمود (أفقي) أو 50 عمودًا (عموديًا). إذا ظهرت لك رسالة التحذير "بيانات غير معروضة: الحد الأقصى X عمودًا لكل مخطط"، فأضِف عوامل تصفية لتضييق نطاق بياناتك أو غيّر أسلوب التجميع (على سبيل المثال، اجعل التجميع حسب الأسبوع بدلًا من الأيام).
**Display limits**: Bar charts can show a maximum of 100 bars, and 50 groups per bar when using Group By. إذا ظهرت لك رسالة التحذير "بيانات غير معروضة: الحد الأقصى X عمودًا لكل مخطط"، فأضِف عوامل تصفية لتضييق نطاق بياناتك أو غيّر أسلوب التجميع (على سبيل المثال، اجعل التجميع حسب الأسبوع بدلًا من الأيام).
</Note>
### مخططات دائرية
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="chart-pie" />Pie Charts</span>
اعرض نسب الأجزاء من الكل.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-pie-chart.png" alt="Pie chart" />
</Frame>
**الأفضل لـ:**
* إظهار التركيب أو التوزيع
@@ -43,10 +53,14 @@ description: استكشف أنواع الأدوات وخيارات التصوّ
* تفصيل جهات الاتصال حسب الصناعة
* تركيب مسار المبيعات حسب المالك
### مخططات خطية
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="chart-line" />Line Charts</span>
اعرض الاتجاهات مع مرور الوقت.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-line-chart.png" alt="Line chart" />
</Frame>
**الأفضل لـ:**
* تتبّع التغيّرات مع مرور الوقت
@@ -59,10 +73,14 @@ description: استكشف أنواع الأدوات وخيارات التصوّ
* نمو الإيرادات على مدى الأرباع السنوية
* مستويات النشاط مع مرور الوقت
### مقاييس رقمية
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="sum" />Aggregate Charts</span>
اعرض القيم الأساسية المفردة بشكل بارز.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-aggregate-chart.png" alt="Aggregate chart" />
</Frame>
**الأفضل لـ:**
* إبراز مؤشرات الأداء الرئيسية
@@ -80,10 +98,14 @@ description: استكشف أنواع الأدوات وخيارات التصوّ
* **النسبة**: في حقول التحديد، احسب النِّسب بين القيم. اذهب إلى **البيانات المعروضة** → اختر حقلك → فعِّل خيار **النسبة**.
* **بادئة ولاحقة**: أضف نصًا مخصصًا قبل الرقم أو بعده (على سبيل المثال، "$" كبادئة أو "%" كلاحقة) لتحسين سهولة القراءة.
### iFrames
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="frame" />iFrames</span>
ضمّن الأدوات والمحتوى الخارجي مباشرةً في لوحة المعلومات الخاصة بك.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-iframe.png" alt="iFrame" />
</Frame>
**الأفضل لـ:**
* عرض تقارير أو لوحات معلومات خارجية
@@ -96,34 +118,30 @@ description: استكشف أنواع الأدوات وخيارات التصوّ
* مقاييس من أداة الاتصال الهاتفي لديك
* محتوى مباشر من أداة تسلسل المبيعات لديك
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="align-box-left-top" />Rich Text</span>
Add formatted text and content directly to your dashboard.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-rich-text.png" alt="Rich text" />
</Frame>
**الأفضل لـ:**
* Adding context or instructions
* Dashboard descriptions
* Notes and annotations
**Features:**
* Rich text formatting (bold, italic, lists, etc.)
* Image and file uploads
* Markdown-style editing
<Note>
**قريبًا**: مخططات القياس والجداول غير متاحة بعد ولكنها على خريطة الطريق لدينا.
</Note>
## تكوين الأدوات
### مصدر البيانات
1. حدّد الكائن المراد تصوّره (الفرص، الأشخاص، إلخ).
2. اختر المقياس لعرضه (العدد، المجموع، المتوسّط)
3. طبّق عوامل تصفية للتركيز على بيانات محددة
### التجميع
تجميع البيانات حسب:
* الحقول (المرحلة، المالك، الصناعة)
* الفترات الزمنية (اليوم، الأسبوع، الشهر، الربع)
* شرائح مخصصة
### التنسيق
خصّص مخططاتك باستخدام:
* الألوان والسمات
* التسميات ووسيلة الإيضاح
* الحجم والتموضع
### تكرار الأدوات
1. انقر على الأداة
@@ -31,10 +31,6 @@ description: أسئلة شائعة حول لوحات القيادة في Twenty.
البنية: لوحة القيادة → علامات التبويب → عناصر واجهة المستخدم
</Accordion>
<Accordion title="لماذا أرى تحذير 'بيانات غير معروضة' على مخطط الأعمدة الخاص بي؟">
لمخططات الأعمدة حدود عرض: 100 عمود للمخططات الأفقية، و50 للعمودية. إذا تجاوزت بياناتك ذلك، فأضِف عوامل تصفية لحصر النتائج أو غيّر أسلوب التجميع (على سبيل المثال، التجميع حسب الأسبوع بدلًا من اليوم).
</Accordion>
<Accordion title="هل يمكنني تصفية لوحة القيادة بالكامل دفعة واحدة؟">
عوامل التصفية على مستوى لوحة القيادة غير متاحة بعد، لكن هذه الميزة مدرَجة على خارطة الطريق لدينا. حاليًا، تحتاج إلى تطبيق عوامل التصفية على كل عنصر واجهة مستخدم على حدة.
</Accordion>
@@ -0,0 +1,67 @@
---
title: Widget FAQ
description: Common questions and error messages explained.
---
<AccordionGroup>
<Accordion title="How do I show percentages instead of counts?">
Three options:
* **Percent empty/not empty**: Under Data on display, select Percent empty or Percent not empty
* **Ratio**: For Select or Checkbox fields, enable Ratio to show a specific option as a percentage of all records
* **Suffix**: For aggregate charts, add `%` as a Suffix in Style settings
</Accordion>
<Accordion title="What's the difference between grouped and stacked bars?">
When using **Group by**, you can display series two ways:
* **Grouped**: Bars side by side—best for comparing exact values
* **Stacked**: Bars on top of each other—best for showing composition
Toggle **Stacked** in Style settings to switch.
</Accordion>
<Accordion title="Why can't I see Sum or Average options?">
Available operations depend on **field type**:
* **Number fields**: Sum, Average, Min, Max
* **Date fields**: Earliest, Latest (aggregate charts only)
* **Checkbox fields**: Count true, Count false
If you don't see an option, check that you've selected a compatible field type.
</Accordion>
<Accordion title="Why are some settings grayed out or missing?">
Many settings only appear when prerequisites are met:
* **Date granularity**: Select a date field first
* **Group by, Legend, Stacked**: Set Source first
* **Legend, Stacked toggles**: Set Group by first
If a setting is missing, configure its prerequisite first.
</Accordion>
<Accordion title="What does 'No data' mean?">
The chart found no records matching your configuration.
**To fix:** Remove or adjust filters, verify you selected the correct Source object, or check that records exist for your date range.
</Accordion>
<Accordion title="What does 'Invalid configuration' mean?">
A required setting is missing or incompatible.
**To fix:** Ensure Source is set, Data on display is configured, and any required grouping fields are selected.
</Accordion>
<Accordion title="What does 'Undisplayed data' mean?">
Your data exceeds display limits (100 bars, 100 data points, or 100 slices).
**To fix:** Add filters to narrow your data, or change date granularity from Day to Week or Month.
</Accordion>
<Accordion title="Why is one axis showing no data?">
The selected field has no values for the records in your filter, or the field type doesn't match the expected data.
**To fix:** Try a different field, or check that records have values for the selected field.
</Accordion>
</AccordionGroup>
@@ -9,7 +9,7 @@ image: /images/user-guide/reporting/pie-chart.png
</Frame>
<Note>
Dashboards are currently in beta. Activate them under **Settings → Updates → Early Access**.
لوحات المعلومات حاليًا في الإصدار التجريبي. قم بتفعيلها ضمن **الإعدادات → التحديثات → الوصول المبكر**.
</Note>
## فهم لوحات المعلومات
@@ -40,8 +40,9 @@ image: /images/user-guide/reporting/pie-chart.png
* مخططات الأعمدة
* مخططات دائرية
* مخططات خطية
* مقاييس رقمية
* Aggregate charts
* iFrames
* Rich text
<Note>
**القيود الحالية**:
@@ -80,4 +81,5 @@ image: /images/user-guide/reporting/pie-chart.png
## الخطوات التالية
* [الأدوات والتصورات](/l/ar/user-guide/dashboards/capabilities/widgets)
* [Chart settings reference](/l/ar/user-guide/dashboards/capabilities/chart-settings)
* [الأسئلة الشائعة حول لوحات المعلومات](/l/ar/user-guide/dashboards/how-tos/dashboards-faq)
@@ -1,76 +1,76 @@
---
title: Error Handling & Validation
description: Review and fix import errors directly in the UI before confirming.
title: التعامل مع الأخطاء والتحقّق
description: راجع وأصلِح أخطاء الاستيراد مباشرةً في واجهة المستخدم قبل التأكيد.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## Pre-Import Validation
## التحقّق قبل الاستيراد
After uploading your file and mapping fields, Twenty validates your data **before** importing. This allows you to catch and fix errors without affecting your existing data.
بعد رفع ملفك وتعيين الحقول، تتحقّق Twenty من بياناتك **قبل** الاستيراد. يتيح لك ذلك اكتشاف الأخطاء وإصلاحها من دون التأثير في بياناتك الحالية.
## كيف يعمل
1. **Upload** your CSV file
2. **Map** your columns to Twenty fields
3. **Review** the potential errors highlighted in yellow
4. **Fix errors** directly in the UI
5. **Confirm** the import
1. **ارفع** ملف CSV الخاص بك
2. **طابِق** أعمدتك مع حقول Twenty
3. **راجِع** الأخطاء المحتملة المميّزة باللون الأصفر
4. **أصلِح الأخطاء** مباشرةً في واجهة المستخدم
5. **أكِّد** عملية الاستيراد
<VimeoEmbed videoId="1145273857" title="Video demonstration" />
<VimeoEmbed videoId="1145273857" title="عرض توضيحي بالفيديو" />
## Error Display
## عرض الأخطاء
Rows with issues are highlighted in **yellow**. You can:
يتم تمييز الصفوف التي تحتوي على مشكلات باللون **الأصفر**. يمكنك:
* **Edit the cell directly** to fix the error
* **Remove the row** to skip it entirely
* **حرِّر الخلية مباشرةً** لإصلاح الخطأ
* **أزل الصف** لتجاوزه بالكامل
This inline editing saves time—no need to go back to your spreadsheet, fix errors, and re-upload.
يوفّر هذا التحرير المضمَّن الوقت—لا حاجة للعودة إلى جدول البيانات، وإصلاح الأخطاء، وإعادة الرفع.
## Common Error Types
## أنواع الأخطاء الشائعة
### Duplicate Values
### قيم مكرّرة
**Cause**: A unique field (email, domain) already exists in Twenty or appears twice in your file.
**السبب**: حقل فريد (البريد الإلكتروني، النطاق) موجود مسبقًا في Twenty أو يظهر مرتين في ملفك.
**Fix**:
**الإصلاح**:
* Edit the duplicate value in the import UI
* Remove one of the duplicate rows
* حرِّر القيمة المكرّرة في واجهة مستخدم الاستيراد
* أزل أحد الصفوف المكرّرة
See [Uniqueness Constraints](/l/ar/user-guide/data-migration/capabilities/uniqueness-constraints) for more details on how uniqueness is enforced.
راجع [قيود التفرّد](/l/ar/user-guide/data-migration/capabilities/uniqueness-constraints) لمزيد من التفاصيل حول كيفية فرض التفرّد.
### Invalid Format
### تنسيق غير صالح
**Cause**: Data doesn't match the expected format (e.g., invalid email, wrong date format).
**السبب**: لا تتطابق البيانات مع التنسيق المتوقع (مثل: بريد إلكتروني غير صالح، تنسيق تاريخ غير صحيح).
**Fix**: Edit the cell to use the correct format.
**الإصلاح**: حرِّر الخلية لاستخدام التنسيق الصحيح.
See [Field Mapping](/l/ar/user-guide/data-migration/capabilities/field-mapping) for the expected format of each field type.
راجع [تعيين الحقول](/l/ar/user-guide/data-migration/capabilities/field-mapping) لمعرفة التنسيق المتوقع لكل نوع من الحقول.
### Missing Required Fields
### حقول مطلوبة مفقودة
**Cause**: A required field is empty.
**السبب**: حقل مطلوب فارغ.
**Fix**: Enter a value in the required field or remove the row.
**الإصلاح**: أدخِل قيمة في الحقل المطلوب أو أزل الصف.
### Relation Not Found
### العلاقة غير موجودة
**Cause**: The referenced record doesn't exist (e.g., a Company domain that wasn't imported).
**السبب**: السجل المشار إليه غير موجود (مثل: نطاق شركة لم يتم استيراده).
**Fix**:
**الإصلاح**:
* Import the parent records first
* Or correct the reference value
* استورِد سجلات الأصل أولًا
* أو صحِّح قيمة المرجع
See [Import Relations](/l/ar/user-guide/data-migration/capabilities/import-relations) for the correct import order and how to link records.
راجع [استيراد العلاقات](/l/ar/user-guide/data-migration/capabilities/import-relations) لمعرفة ترتيب الاستيراد الصحيح وكيفية ربط السجلات.
## Tips for Fewer Errors
## نصائح لتقليل الأخطاء
1. **Download the template** to see expected format prior to importing your file
2. **Clean your data** in the spreadsheet first
3. **Import files in correct order** to import relations (Companies → People → Opportunities)
4. **Test with small batches** before full import
5. **Check for duplicates** before uploading
6. **Limit the size of your file to 10,000 records** per file
1. **نزّل القالب** للاطلاع على التنسيق المتوقع قبل استيراد ملفك
2. **نظِّف بياناتك** في جدول البيانات أولًا
3. **استورِد الملفات بالترتيب الصحيح** لاستيراد العلاقات (الشركات → الأشخاص → الفرص)
4. **اختبر بدُفعات صغيرة** قبل الاستيراد الكامل
5. **تحقّق من التكرارات** قبل الرفع
6. **حدِّد حجم ملفك إلى 10,000 سجل** لكل ملف
@@ -1,176 +1,176 @@
---
title: Import Data via API
description: When and how to use Twenty's APIs for large-scale data imports.
title: استيراد البيانات عبر واجهة API
description: متى وكيف تستخدم واجهات API الخاصة بـ Twenty لاستيراد البيانات على نطاق واسع.
---
## نظرة عامة
Twenty provides both **GraphQL** and **REST APIs** for programmatic data import. Use the API when CSV import isn't practical for your data volume or when you need automated, recurring imports.
توفّر Twenty كلًا من **GraphQL** و**واجهات REST API** لاستيراد البيانات برمجيًا. استخدم واجهة API عندما لا يكون استيراد CSV عمليًا لحجم بياناتك أو عندما تحتاج إلى عمليات استيراد مؤتمتة ومتكررة.
## When to Use API Import
## متى تستخدم الاستيراد عبر API
| Scenario | Recommended Method |
| ---------------------------------- | ----------------------------- |
| Under 10,000 records | CSV Import |
| 10,000 - 50,000 records | CSV Import (split into files) |
| **50,000+ records** | **API Import** |
| One-time migration | Either (based on volume) |
| **Recurring imports** | **API Import** |
| **Real-time sync** | **API Import** |
| **Integration with other systems** | **API Import** |
| السيناريو | الطريقة الموصى بها |
| ----------------------------- | ---------------------------- |
| أقل من 10,000 سجل | استيراد CSV |
| 10,000 - 50,000 سجل | استيراد CSV (قسّم إلى ملفات) |
| **أكثر من 50,000 سجل** | **استيراد API** |
| ترحيل لمرة واحدة | أيّ منهما (حسب الحجم) |
| **عمليات استيراد متكررة** | **استيراد API** |
| **مزامنة في الوقت الحقيقي** | **استيراد API** |
| **التكامل مع الأنظمة الأخرى** | **استيراد API** |
<Note>For datasets in the hundreds of thousands, the API is significantly faster and more reliable than multiple CSV imports.</Note>
<Note>بالنسبة لمجموعات البيانات التي تبلغ مئات الآلاف، تكون واجهة API أسرع بكثير وأكثر موثوقية من عمليات استيراد CSV المتعددة.</Note>
## API Rate Limits
## حدود معدل API
Twenty enforces rate limits to ensure system stability:
تفرض Twenty حدودًا للمعدل لضمان استقرار النظام:
| Limit | القيمة |
| -------------------------- | --------------------- |
| **Requests per minute** | 100 |
| **Records per batch call** | 60 |
| **Maximum throughput** | ~6,000 records/minute |
| الحد | القيمة |
| ---------------------------- | ---------------- |
| **الطلبات في الدقيقة** | 100 |
| **السجلات لكل استدعاء دفعي** | 60 |
| **الحد الأقصى للإنتاجية** | ~6,000 سجل/دقيقة |
<Warning>
**Plan your import around these limits.**
**خطّط لعملية الاستيراد وفق هذه الحدود.**
For 100,000 records at maximum throughput, expect approximately 17 minutes of import time. Add buffer time for error handling and retries.
بالنسبة إلى 100,000 سجل عند أقصى إنتاجية، توقّع نحو 17 دقيقة من وقت الاستيراد. أضِف وقتًا احتياطيًا لمعالجة الأخطاء وإعادة المحاولة.
</Warning>
## البدء
### Step 1: Get Your API Key
### الخطوة 1: احصل على مفتاح API الخاص بك
1. Go to **Settings → Developers**
2. Click **+ Create API key**
3. Give your key a descriptive name
4. Copy the API key immediately (it won't be shown again)
5. Store it securely
1. انتقل إلى **الإعدادات → المطوّرون**
2. انقر **+ إنشاء مفتاح API**
3. امنح مفتاحك اسمًا وصفيًا
4. انسخ مفتاح API فورًا (لن يُعرَض مرة أخرى)
5. احفظه في مكان آمن
<Warning>
**Keep your API key secret.**
**أبقِ مفتاح API سريًا.**
Anyone with your API key can access and modify your workspace data. Never commit it to code repositories or share it publicly.
يمكن لأي شخص لديه مفتاح API الخاص بك الوصول إلى بيانات مساحة العمل الخاصة بك وتعديلها. لا تقم أبدًا بإيداعه في مستودعات الكود أو مشاركته علنًا.
</Warning>
### Step 2: Choose Your API
### الخطوة 2: اختر واجهة API الخاصة بك
Twenty supports two API types:
تدعم Twenty نوعين من واجهات API:
| واجهة برمجة التطبيقات | Best For | التوثيق |
| --------------------- | ----------------------------------------------------------- | ------------------------------------------------ |
| **GraphQL** | Flexible queries, fetching related data, complex operations | [API Docs](/l/ar/developers/extend/capabilities/apis) |
| **REST** | Simple CRUD operations, familiar REST patterns | [API Docs](/l/ar/developers/extend/capabilities/apis) |
| واجهة برمجة التطبيقات | الأفضل لـ | التوثيق |
| --------------------- | ------------------------------------------------------ | ------------------------------------------------- |
| **GraphQL** | استعلامات مرنة، وجلب البيانات المرتبطة، وعمليات معقّدة | [وثائق API](/l/ar/developers/extend/capabilities/apis) |
| **REST** | عمليات CRUD بسيطة، وأنماط REST مألوفة | [وثائق API](/l/ar/developers/extend/capabilities/apis) |
Both APIs support:
كلتا واجهتي API تدعمان:
* Creating, reading, updating, and deleting records
* **Batch operations** — create or update up to 60 records per call
* إنشاء السجلات وقراءتها وتحديثها وحذفها
* **عمليات الدُفعات** — إنشاء أو تحديث ما يصل إلى 60 سجلًا لكل استدعاء
**For imports, use batch operations** to maximize throughput within rate limits.
**لعمليات الاستيراد، استخدم عمليات الدُفعات** لتعظيم الإنتاجية ضمن حدود المعدل.
### Step 3: Plan Your Import Order
### الخطوة 3: خطّط لترتيب الاستيراد
Just like CSV imports, **order matters** for relations:
تمامًا مثل عمليات استيراد CSV، فإن **الترتيب مهم** للعلاقات:
1. **Companies** first (no dependencies)
2. **People** second (can link to Companies)
3. **Opportunities** third (can link to Companies and People)
4. **Tasks/Notes** (can link to any of the above)
5. **Custom objects** (following their dependencies)
1. **الشركات** أولًا (من دون تبعيات)
2. **الأشخاص** ثانيًا (يمكن ربطهم بالشركات)
3. **الفرص** ثالثًا (يمكن ربطها بالشركات والأشخاص)
4. **المهام/الملاحظات** (يمكن ربطها بأي مما سبق)
5. **الكائنات المخصّصة** (وفقًا لتبعياتها)
## أفضل الممارسات
### Batch Your Requests
### اجمع طلباتك في دُفعات
* Don't send records one at a time
* Group up to **60 records per API call**
* This maximizes throughput within rate limits
* لا ترسل السجلات واحدًا تلو الآخر
* اجمع ما يصل إلى **60 سجلًا لكل استدعاء API**
* هذا يُعظّم الإنتاجية ضمن حدود المعدل
### Handle Rate Limits
### التعامل مع حدود المعدل
* Implement delays between requests (600ms minimum for sustained imports)
* Use exponential backoff when you hit limits
* Monitor for 429 (Too Many Requests) responses
* طبّق فواصل زمنية بين الطلبات (600 مللي ثانية كحد أدنى لعمليات الاستيراد المستمرة)
* استخدم التراجع الأسي عند بلوغ الحدود
* راقِب الاستجابات 429 (طلبات كثيرة جدًا)
### Validate Data First
### تحقّق من البيانات أولًا
* Clean and validate your data before importing
* Check required fields are populated
* Verify formats match Twenty's requirements (see [Field Mapping](/l/ar/user-guide/data-migration/capabilities/field-mapping))
* نظّف بياناتك وتحقّق منها قبل الاستيراد
* تحقّق من تعبئة الحقول المطلوبة
* تحقّق من توافق التنسيقات مع متطلبات Twenty (راجع [تعيين الحقول](/l/ar/user-guide/data-migration/capabilities/field-mapping))
### Log Everything
### سجّل كل شيء
* Log every record imported (including IDs)
* Log errors with full context
* This helps debug issues and verify completion
* سجّل كل سجل تم استيراده (بما في ذلك المعرّفات)
* سجّل الأخطاء مع السياق الكامل
* يساعد ذلك في تصحيح المشكلات والتحقق من الإكمال
### Test First
### اختبر أولًا
* Test with a small batch (10-20 records)
* Verify data appears correctly in Twenty
* Then run the full import
* اختبر بدفعة صغيرة (10-20 سجلًا)
* تحقّق من ظهور البيانات بشكل صحيح في Twenty
* ثم نفّذ عملية الاستيراد الكاملة
### Upsert to Avoid Duplicates
### استخدم upsert لتجنّب التكرارات
The GraphQL API supports **batch upsert** — update if the record exists, create if not. This prevents duplicates when re-running imports.
واجهة GraphQL API تدعم **upsert على دفعات** — حدِّث إذا كان السجل موجودًا، وأنشئ إذا لم يكن كذلك. يمنع هذا التكرارات عند إعادة تشغيل عمليات الاستيراد.
## Finding Object and Field Names
## العثور على أسماء الكائنات والحقول
To see available objects and fields:
للاطلاع على الكائنات والحقول المتاحة:
1. Go to **Settings → API and Webhooks**
2. Browse the **Metadata API**
3. View all standard and custom objects with their fields
1. انتقل إلى **الإعدادات → API وخطافات الويب**
2. استعرض **واجهة API للبيانات الوصفية**
3. اعرض جميع الكائنات القياسية والمخصّصة مع حقولها
The documentation shows all standard and custom objects, their fields, and the expected data types.
تُظهر الوثائق جميع الكائنات القياسية والمخصّصة وحقولها وأنواع البيانات المتوقعة.
## Professional Services
## الخدمات الاحترافية
For complex API migrations, our partners can help:
بالنسبة لعمليات ترحيل API المعقّدة، يمكن لشركائنا تقديم المساعدة:
| Service | What's Included |
| ----------------------- | ---------------------------------- |
| **Data Model Design** | design your optimal data structure |
| **Migration Scripts** | write and run the import scripts |
| **Data Transformation** | handle complex mapping and cleanup |
| **Validation & QA** | verify the migration is complete |
| الخدمة | ما الذي يتضمّنه |
| ------------------------ | ------------------------------------- |
| **تصميم نموذج البيانات** | تصميم الهيكل الأمثل لبياناتك |
| **برامج نصية للترحيل** | كتابة وتشغيل البرامج النصية للاستيراد |
| **تحويل البيانات** | التعامل مع التعيين المعقّد والتنظيف |
| **التحقق وضمان الجودة** | التحقق من اكتمال عملية الترحيل |
**Best for:**
**الأفضل لـ:**
* Migrations of 100,000+ records
* Complex data transformations
* Tight timelines
* Teams without developer resources
* عمليات ترحيل لأكثر من 100,000 سجل
* تحويلات بيانات معقّدة
* جداول زمنية ضيّقة
* الفرق التي تفتقر إلى موارد المطورين
Contact us at [contact@twenty.com](mailto:contact@twenty.com) or explore our [Implementation Services](/l/ar/user-guide/getting-started/capabilities/implementation-services).
تواصل معنا عبر [contact@twenty.com](mailto:contact@twenty.com) أو استكشف [خدمات التنفيذ](/l/ar/user-guide/getting-started/capabilities/implementation-services).
## FAQ
## الأسئلة الشائعة
<AccordionGroup>
<Accordion title="What's the difference between GraphQL and REST?">
GraphQL lets you request exactly the data you need in a single query and is better for complex operations. REST uses standard HTTP methods (GET, POST, PUT, DELETE) and may be more familiar if you've worked with traditional APIs.
<Accordion title="ما الفرق بين GraphQL وREST؟">
يتيح لك GraphQL طلب البيانات التي تحتاجها بدقة ضمن استعلام واحد، وهو أفضل للعمليات المعقّدة. يعتمد REST على طرق HTTP القياسية (GET وPOST وPUT وDELETE)، وقد يكون أكثر ألفة إذا سبق لك العمل مع واجهات API التقليدية.
</Accordion>
<Accordion title="Can I update existing records via API?">
نعم! Use update mutations (GraphQL) or PUT/PATCH requests (REST) with the record's `id`.
<Accordion title="هل يمكنني تحديث السجلات الموجودة عبر API؟">
نعم! استخدم تحديثات mutations في GraphQL أو طلبات PUT/PATCH في REST مع `id` الخاص بالسجل.
</Accordion>
<Accordion title="How do I handle duplicates?">
Query for existing records first using unique identifiers (email, domain). Update if exists, create if not.
<Accordion title="كيف أتعامل مع التكرارات؟">
استعلم أولًا عن السجلات الموجودة باستخدام معرّفات فريدة (البريد الإلكتروني، النطاق). حدِّث إذا كان موجودًا، وأنشئ إذا لم يكن كذلك.
</Accordion>
<Accordion title="Can I delete records via API?">
Yes, use delete mutations (GraphQL) or DELETE requests (REST).
<Accordion title="هل يمكنني حذف السجلات عبر API؟">
نعم، استخدم delete mutations في GraphQL أو طلبات DELETE في REST.
</Accordion>
<Accordion title="Is there a Python or Node.js SDK?">
Not currently, but both APIs work with any HTTP client in any language.
<Accordion title="هل يوجد SDK لـ Python أو Node.js؟">
لا يتوفر ذلك في الوقت الحالي، لكن كلتا واجهتي API تعملان مع أي عميل HTTP بأي لغة.
</Accordion>
</AccordionGroup>
## API Documentation
## وثائق API
For full implementation details, code examples, and schema reference:
للحصول على تفاصيل التنفيذ الكاملة وأمثلة الشيفرة ومرجع المخطط (schema):
* [API Documentation](/l/ar/developers/extend/capabilities/apis)
* [وثائق API](/l/ar/developers/extend/capabilities/apis)
@@ -1,11 +1,11 @@
---
title: كائنات
description: Learn about standard and custom objects in Twenty.
description: تعرّف على الكائنات القياسية والمخصصة في Twenty.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## Standard Objects
## الكائنات القياسية
الكائنات القياسية هي كيانات مُعرّفة مسبقًا في مساحة العمل الخاصة بك لمساعدتك في البدء. هي جزء من نموذج بيانات مشترك يمكن الوصول إليه بواسطة جميع مستخدمي Twenty. يمكنك استخدامها كما هي أو تخصيصها أو تعطيلها.
@@ -25,11 +25,11 @@ import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
### الملاحظات
The `Notes` object stores free-form notes that can be attached to People, Companies, Opportunities, and other records. Use notes to capture meeting summaries, important details, or any contextual information.
يخزّن كائن `Notes` ملاحظات حرة يمكن إرفاقها بالأشخاص والشركات والفرص وسجلات أخرى. استخدم الملاحظات لالتقاط ملخصات الاجتماعات والتفاصيل المهمة أو أي معلومات سياقية.
### المهام
The `Tasks` object stores to-dos and action items. Tasks can be linked to People, Companies, Opportunities, and other records. Track due dates, assignees, and completion status to stay on top of your follow-ups.
يخزّن كائن `Tasks` المهام المطلوب إنجازها وبنود العمل. يمكن ربط المهام بالأشخاص والشركات والفرص وسجلات أخرى. تتبّع تواريخ الاستحقاق والمكلّفين وحالة الإكمال للبقاء على اطّلاع بمتابعاتك.
## كائنات مخصصة
@@ -37,55 +37,55 @@ The `Tasks` object stores to-dos and action items. Tasks can be linked to People
<img src="/images/user-guide/objects/custom-objects.png" style={{width:'100%'}} />
### Creating a New Custom Object
### إنشاء كائن مخصص جديد
لإنشاء كائن مخصص جديد:
1. اذهب إلى الإعدادات في الشريط الجانبي الأيسر.
2. تحت قسم مساحة العمل، انتقل إلى نموذج البيانات. هنا ستتمكن من رؤية نظرة عامة على جميع الكائنات القياسية والمخصصة الحالية (النشطة والمعطلة).
<VimeoEmbed videoId="926288174" title="Video demonstration" />
<VimeoEmbed videoId="926288174" title="عرض توضيحي بالفيديو" />
3. انقر على "+ كائن جديد" في الأعلى. أدخل الاسم (مفرد وجمع)، اختر أيقونة، أضف وصفًا للكائن المخصص واضغط حفظ (في الزاوية العليا اليمنى). باستخدام القائمة كمثال للكائن المخصص، سيكون المفرد هو "قائمة" والجمع "قوائم" مع الوصف كمثل "قوائم قام المضيفون بإنشائها لعرض ممتلكاتهم."
4. Your custom object is now created and will appear in your sidebar. You can start adding records to it right away.
4. تم الآن إنشاء الكائن المخصص الخاص بك وسيظهر في الشريط الجانبي لديك. يمكنك البدء في إضافة السجلات إليه فورًا.
## Managing Objects
## إدارة الكائنات
### Deactivating Objects
### إلغاء تنشيط الكائنات
If you don't need a standard or custom object:
إذا لم تكن بحاجة إلى كائن قياسي أو مخصص:
1. Go to Settings → Data Model
2. Find the object you want to deactivate
3. Click the toggle to deactivate it
4. The object will be hidden from your workspace but data is preserved
1. انتقل إلى الإعدادات → نموذج البيانات
2. اعثر على الكائن الذي تريد إلغاء تنشيطه
3. انقر زر التبديل لإلغاء تنشيطه
4. سيتم إخفاء الكائن من مساحة العمل لديك ولكن سيتم الاحتفاظ بالبيانات
### Reactivating Objects
### إعادة تنشيط الكائنات
To bring back a deactivated object:
لإعادة كائن تم إلغاء تنشيطه:
1. Go to Settings → Data Model
2. Look for deactivated objects (they'll be grayed out)
3. Click the toggle to reactivate it
4. The object and all its data will be restored
1. انتقل إلى الإعدادات → نموذج البيانات
2. ابحث عن الكائنات التي تم إلغاء تنشيطها (ستظهر باللون الرمادي)
3. انقر زر التبديل لإعادة تنشيطه
4. سيتم استعادة الكائن وجميع بياناته
## أفضل الممارسات
### When to Create Custom Objects
### متى يجب إنشاء كائنات مخصصة
* **Unique business entities**: Things specific to your industry or process
* **Complex relationships**: When you need to track connections between multiple entities
* **Scalable data**: When you might have many instances of something
* **كيانات عمل فريدة**: أمور خاصة بمجالك أو بعملياتك
* **علاقات معقّدة**: عندما تحتاج إلى تتبّع الروابط بين عدة كيانات
* **بيانات قابلة للتوسّع**: عندما قد يكون لديك العديد من المثيلات لشيء ما
### When to Use Fields Instead
### متى تستخدم الحقول بدلًا من ذلك
* **Simple attributes**: Properties that describe existing objects
* **Categories or labels**: Ways to classify existing records
* **Single values**: Information that doesn't need its own lifecycle
* **سمات بسيطة**: خصائص تصف الكائنات الموجودة
* **فئات أو تسميات**: طرق لتصنيف السجلات الموجودة
* **قيم مفردة**: معلومات لا تحتاج إلى دورة حياة خاصة بها
### Object Naming
### تسمية الكائنات
* **Use clear, descriptive names**: Make it obvious what the object represents
* **Follow conventions**: Use singular for the object name, plural for the collection
* **Consider your team**: Choose names everyone will understand
* **استخدم أسماء واضحة ووصفية**: اجعل ما يمثّله الكائن واضحًا
* **اتّبع الاصطلاحات**: استخدم المفرد لاسم الكائن، والجمع للمجموعة
* **ضع فريقك في الاعتبار**: اختر أسماء يفهمها الجميع
@@ -1,51 +1,51 @@
---
title: Create Custom Objects
description: Step-by-step guide to creating custom objects in Twenty.
title: إنشاء كائنات مخصصة
description: دليل خطوة بخطوة لإنشاء كائنات مخصصة في Twenty.
---
Custom objects let you store information unique to your business that standard objects don't cover. For example: Projects, Products, Tickets, or Listings.
تتيح لك الكائنات المخصصة تخزين معلومات فريدة لعملك لا تغطيها الكائنات القياسية. على سبيل المثال: المشاريع، المنتجات، التذاكر، أو القوائم.
<Note>
**Not sure if you need an object or a field?** See [Understanding Your Data Model](/l/ar/user-guide/data-model/overview) for guidance.
**لست متأكدًا مما إذا كنت بحاجة إلى كائن أم حقل؟** اطّلع على [فهم نموذج البيانات لديك](/l/ar/user-guide/data-model/overview) للحصول على إرشادات.
</Note>
## Steps
## الخطوات
1. Go to **Settings → Data Model**
2. Click **+ New object**
3. Fill in:
* **Singular name** (e.g., "Listing")
* **Plural name** (e.g., "Listings")
* **Icon**
* **Description** (optional)
1. اذهب إلى **الإعدادات → نموذج البيانات**
2. انقر **+ كائن جديد**
3. املأ ما يلي:
* **الاسم المفرد** (مثل: "Listing")
* **الاسم بصيغة الجمع** (مثل: "Listings")
* **أيقونة**
* **الوصف** (اختياري)
4. انقر على **حفظ**
Your object appears in the sidebar immediately.
يظهر كائنك في الشريط الجانبي فورًا.
## Next: Add Fields
## التالي: إضافة الحقول
New objects start with basic fields. Add custom fields to capture the data you need:
تبدأ الكائنات الجديدة بحقول أساسية. أضف حقولًا مخصصة لالتقاط البيانات التي تحتاج إليها:
1. In **Settings → Data Model**, select your object
2. Click **+ Add Field**
3. Choose a field type, configure, and save
1. في **الإعدادات → نموذج البيانات**، حدّد كائنك
2. انقر **+ إضافة حقل**
3. اختر نوع الحقل، قم بإعداده، ثم احفظ
See [How to Create Custom Fields](/l/ar/user-guide/data-model/how-tos/create-custom-fields) for details on field types and configuration.
اطّلع على [كيفية إنشاء حقول مخصصة](/l/ar/user-guide/data-model/how-tos/create-custom-fields) للحصول على تفاصيل حول أنواع الحقول والإعداد.
## Connecting to Other Objects
## الاتصال بكائنات أخرى
To link your object to People, Companies, or other objects, create a relation field. See [How to Create Relation Fields](/l/ar/user-guide/data-model/how-tos/create-relation-fields).
لربط كائنك بالأشخاص والشركات أو كائنات أخرى، أنشئ حقل علاقة. اطّلع على [كيفية إنشاء حقول العلاقات](/l/ar/user-guide/data-model/how-tos/create-relation-fields).
## Deactivating an Object
## إلغاء تنشيط كائن
If you no longer need an object:
إذا لم تعد بحاجة إلى كائن:
1. Go to **Settings → Data Model**
2. Toggle the object off
1. اذهب إلى **الإعدادات → نموذج البيانات**
2. بدّل الكائن إلى وضع الإيقاف
The object is hidden but data is preserved. You can reactivate or permanently delete later.
سيتم إخفاء الكائن ولكن سيتم الاحتفاظ بالبيانات. يمكنك إعادة تنشيطه أو حذفه نهائيًا لاحقًا.
## Related
## ذات صلة
* [Objects](/l/ar/user-guide/data-model/capabilities/objects) — standard vs custom objects
* [Data Model FAQ](/l/ar/user-guide/data-model/how-tos/data-model-faq) — common questions
* [الكائنات](/l/ar/user-guide/data-model/capabilities/objects) — الكائنات القياسية مقابل الكائنات المخصصة
* [الأسئلة الشائعة حول نموذج البيانات](/l/ar/user-guide/data-model/how-tos/data-model-faq) — أسئلة شائعة
@@ -1,29 +1,29 @@
---
title: الأسئلة المتكررة حول نموذج البيانات
description: Frequently asked questions about Twenty's data model.
description: الأسئلة الشائعة حول نموذج بيانات Twenty.
---
## إدارة الكائنات
<AccordionGroup>
<Accordion title="Can I delete a custom object?">
Yes, custom objects can be deleted. You can also deactivate them first, which hides the object and its data from the interface while preserving the data.
<Accordion title="هل يمكنني حذف كائن مخصص؟">
نعم، يمكن حذف الكائنات المخصصة. يمكنك أيضًا إلغاء تنشيطها أولًا، مما يخفي الكائن وبياناته من الواجهة مع الاحتفاظ بالبيانات.
</Accordion>
<Accordion title="هل يمكنني حذف الكائنات القياسية (الأشخاص، الشركات، إلخ)؟">
No, standard objects cannot be deleted. You can only deactivate them, which hides them from the interface but preserves the data.
لا، لا يمكن حذف الكائنات القياسية. يمكنك فقط إلغاء تنشيطها، مما يخفيها من الواجهة مع الاحتفاظ بالبيانات.
</Accordion>
<Accordion title="How many custom objects can I create?">
You can create as many custom objects and fields as you need — the price doesn't change.
<Accordion title="كم عدد الكائنات المخصصة التي يمكنني إنشاؤها؟">
يمكنك إنشاء ما تشاء من الكائنات والحقول المخصصة — لن يتغير السعر.
</Accordion>
<Accordion title="Can I rename a standard object?">
You can rename the label of standard objects (People, Companies, Opportunities), but not their API names. The API names are fixed for consistency across all Twenty workspaces.
<Accordion title="هل يمكنني إعادة تسمية كائن قياسي؟">
يمكنك تغيير تسمية الكائنات القياسية (People وCompanies وOpportunities)، لكن لا يمكنك تغيير أسماء API الخاصة بها. أسماء API ثابتة لضمان الاتساق عبر جميع مساحات عمل Twenty.
</Accordion>
<Accordion title="Can I change an object's icon?">
Yes, you can change the icon for both standard and custom objects in **Settings → Data Model**.
<Accordion title="هل يمكنني تغيير أيقونة الكائن؟">
نعم، يمكنك تغيير الأيقونة لكلٍ من الكائنات القياسية والمخصصة ضمن **الإعدادات → نموذج البيانات**.
</Accordion>
<Accordion title="هل يمكنني إعادة ترتيب الكائنات في شريط التنقل الأيسر؟">
@@ -38,8 +38,8 @@ description: Frequently asked questions about Twenty's data model.
## قدرات الحقول
<AccordionGroup>
<Accordion title="Can I change a field type after creation?">
No, field types cannot be changed after creation. If you need a different type, create a new field with the correct type, migrate your data, then deactivate the old field.
<Accordion title="هل يمكنني تغيير نوع الحقل بعد إنشائه؟">
لا، لا يمكن تغيير أنواع الحقول بعد إنشائها. إذا كنت بحاجة إلى نوع مختلف، فأنشئ حقلًا جديدًا بالنوع الصحيح، وانقل بياناتك، ثم عطّل الحقل القديم.
</Accordion>
<Accordion title="لماذا أحتاج إلى أسماء مفردة وجمع مختلفة؟">
@@ -55,21 +55,21 @@ description: Frequently asked questions about Twenty's data model.
بعض أسماء الحقول مثل `Type` أو `Application` محجوزة لاستخدام النظام. اختر أسماء بديلة مثل `Category` أو `Classification` بدلاً من ذلك.
</Accordion>
<Accordion title="What happens when I deactivate a field?">
* The field is hidden from the interface
* Existing data is preserved
* You can still access the field via API
* Existing relations remain but you can't create new ones
* You can reactivate the field later
<Accordion title="ماذا يحدث عند إلغاء تنشيط حقل؟">
* يتم إخفاء الحقل من الواجهة
* تظل البيانات محفوظة
* لا يزال بإمكانك الوصول إلى الحقل عبر API
* تظل العلاقات الحالية موجودة، ولكن لا يمكنك إنشاء علاقات جديدة
* يمكنك إعادة تنشيط الحقل لاحقًا
</Accordion>
<Accordion title="Can I make a field required?">
Currently, you cannot make custom fields required. All fields accept empty values. You can use workflows to enforce required fields by sending alerts or blocking actions when fields are empty.
<Accordion title="هل يمكنني جعل الحقل إلزاميًا؟">
حاليًا، لا يمكنك جعل الحقول المخصصة إلزامية. جميع الحقول تقبل القيم الفارغة. يمكنك استخدام سير العمل لفرض الحقول الإلزامية عبر إرسال التنبيهات أو حظر الإجراءات عندما تكون الحقول فارغة.
</Accordion>
<Accordion title="What's the difference between unique and required?">
* **Unique**: No two records can have the same value in this field
* **Required**: The field must have a value (not currently supported for custom fields)
<Accordion title="ما الفرق بين الفريد والإلزامي؟">
* **فريد**: يجب ألّا تتكرر القيمة نفسها في هذا الحقل عبر السجلات
* **إلزامي**: يجب أن يحتوي الحقل على قيمة (غير مدعوم حاليًا للحقول المخصصة)
</Accordion>
<Accordion title="هل يمكنني إنشاء حقول صيغة؟">
@@ -81,44 +81,44 @@ description: Frequently asked questions about Twenty's data model.
</Accordion>
<Accordion title="هل يمكنني إعادة ترتيب الحقول داخل الكائنات؟">
سيكون إعادة ترتيب الحقول متاحًا مع التخطيطات المخصصة في **الربع الرابع من عام 2025**. Currently, fields appear in alphabetical order.
سيكون إعادة ترتيب الحقول متاحًا مع التخطيطات المخصصة في **الربع الرابع من عام 2025**. حاليًا، تظهر الحقول بترتيب أبجدي.
</Accordion>
</AccordionGroup>
## العلاقات
<AccordionGroup>
<Accordion title="Can I have a relation pointing to the same object?">
نعم! Self-referencing relations are supported and recommended for use cases like account hierarchies. For example, create a relation from Companies to Companies to track parent/child accounts.
<Accordion title="هل يمكنني إنشاء علاقة تشير إلى الكائن نفسه؟">
نعم! العلاقات ذاتية الإشارة مدعومة ومُوصى بها لحالات الاستخدام مثل التسلسلات الهرمية للحسابات. على سبيل المثال، أنشئ علاقة من Companies إلى Companies لتتبع حسابات الأصل/الفرع.
</Accordion>
<Accordion title="هل يمكنني إنشاء علاقات عديدة-إلى-عدة؟">
Many-to-many relationships are coming in **H1 2026**. Currently, create an intermediate object with two one-to-many relationships as a workaround.
العلاقات عديدة-إلى-عديدة قادمة في **النصف الأول من عام 2026**. حاليًا، أنشئ كائنًا وسيطًا مع علاقتين واحد-إلى-عديد كحل بديل.
For example, to link People and Projects (many-to-many), create a "Project Assignments" object with:
على سبيل المثال، لربط People وProjects (عديد-إلى-عديد)، أنشئ كائنًا باسم "Project Assignments" يحتوي على:
* A relation to People (many assignments → one person)
* A relation to Projects (many assignments → one project)
* علاقة إلى People (عديد من التعيينات → شخص واحد)
* علاقة إلى Projects (عديد من التعيينات → مشروع واحد)
</Accordion>
<Accordion title="What are relations to multiple object types (Morph relationships)?">
These allow one object to relate to multiple different object types through a single field. For example, Notes can be attached to People AND Companies AND Opportunities simultaneously.
<Accordion title="ما هي العلاقات إلى أنواع كائنات متعددة (علاقات Morph)؟">
تتيح هذه أن يرتبط كائن واحد بأنواع كائنات متعددة مختلفة عبر حقل واحد. على سبيل المثال، يمكن إرفاق Notes بـ People وCompanies وOpportunities في الوقت نفسه.
Each Note links to one Person, one Company, and one Opportunity at the same time.
يرتبط كل Note بشخص واحد وشركة واحدة وفرصة واحدة في الوقت نفسه.
Learn more in [Relation Fields](/l/ar/user-guide/data-model/capabilities/relation-fields).
اعرف المزيد في [حقول العلاقات](/l/ar/user-guide/data-model/capabilities/relation-fields).
</Accordion>
<Accordion title="Can I have multiple relations between the same objects?">
Yes, you can create multiple relations between the same two objects. For example, a Company could have both a "Primary Contact" and "Billing Contact" relation to People.
<Accordion title="هل يمكنني إنشاء علاقات متعددة بين الكائنات نفسها؟">
نعم، يمكنك إنشاء علاقات متعددة بين الكائنين نفسيهما. على سبيل المثال، يمكن أن يكون لدى Company علاقتا "Primary Contact" و"Billing Contact" مع People.
</Accordion>
<Accordion title="What happens to relations when I delete a record?">
When you delete a record, the relation link is removed from the related records. The related records themselves are not deleted.
<Accordion title="ماذا يحدث للعلاقات عند حذف سجل؟">
عند حذف سجل، تتم إزالة رابط العلاقة من السجلات المرتبطة. السجلات المرتبطة نفسها لا تُحذف.
</Accordion>
<Accordion title="Can I create circular relations?">
While technically possible, circular relations (A → B → C → A) should be avoided as they can cause confusion and potential performance issues.
<Accordion title="هل يمكنني إنشاء علاقات دائرية؟">
على الرغم من أنها ممكنة تقنيًا، يجب تجنّب العلاقات الدائرية (A → B → C → A) لأنها قد تسبب التباسًا ومشكلات محتملة في الأداء.
</Accordion>
</AccordionGroup>
@@ -126,7 +126,7 @@ description: Frequently asked questions about Twenty's data model.
<AccordionGroup>
<Accordion title="أين يمكنني رؤية وتعديل نموذج البيانات الخاص بي؟">
Go to **Settings → Data Model** to view and edit all your objects and fields.
انتقل إلى **الإعدادات → نموذج البيانات** لعرض جميع الكائنات والحقول الخاصة بك وتحريرها.
</Accordion>
<Accordion title="لماذا لا أستطيع رؤية نموذج البيانات تحت الإعدادات؟">
@@ -134,22 +134,22 @@ description: Frequently asked questions about Twenty's data model.
</Accordion>
</AccordionGroup>
## Data Management
## إدارة البيانات
<AccordionGroup>
<Accordion title="Is there a limit to how many records I can have?">
There's no hard limit on record counts. However, very large datasets may impact performance in some views. Use filters and views to manage large datasets effectively.
<Accordion title="هل هناك حد لعدد السجلات التي يمكنني امتلاكها؟">
لا يوجد حد صارم لعدد السجلات. ومع ذلك، قد تؤثر مجموعات البيانات الكبيرة جدًا في الأداء في بعض طرق العرض. استخدم عوامل التصفية وطرق العرض لإدارة مجموعات البيانات الكبيرة بفعالية.
</Accordion>
<Accordion title="Can I import data into custom objects?">
Yes, you can import CSV data into any object, including custom objects. The import process supports field mapping for custom fields. See [How to Prepare Your CSV Files](/l/ar/user-guide/data-migration/how-tos/prepare-your-csv-files).
<Accordion title="هل يمكنني استيراد بيانات إلى الكائنات المخصصة؟">
نعم، يمكنك استيراد بيانات CSV إلى أي كائن، بما في ذلك الكائنات المخصصة. تدعم عملية الاستيراد تعيين الحقول للحقول المخصصة. اطّلع على [كيفية إعداد ملفات CSV الخاصة بك](/l/ar/user-guide/data-migration/how-tos/prepare-your-csv-files).
</Accordion>
<Accordion title="Can I export my data model configuration?">
Currently, there's no built-in export for data model configuration. Contact support if you need to migrate your data model between workspaces.
<Accordion title="هل يمكنني تصدير تكوين نموذج البيانات الخاص بي؟">
حاليًا، لا يوجد تصدير مدمج لتكوين نموذج البيانات. تواصل مع الدعم إذا كنت بحاجة إلى نقل نموذج البيانات بين مساحات العمل.
</Accordion>
</AccordionGroup>
## هل تحتاج إلى المزيد من المساعدة؟
Check our [Implementation Services](/l/ar/user-guide/getting-started/capabilities/implementation-services) for help with complex data model design.
اطّلع على [خدمات التنفيذ](/l/ar/user-guide/getting-started/capabilities/implementation-services) للحصول على مساعدة في تصميم نموذج بيانات معقّد.
@@ -123,58 +123,58 @@ image: /images/user-guide/fields/custom_data_model.png
ابدأ بالحقول. انتقل إلى كائنات جديدة فقط عندما تشعر بالقيود:
* Too many fields on one object
* Repeated records that should be separate
* Relationships that don't fit neatly
* عدد كبير جدًا من الحقول في كائن واحد
* سجلات مكررة يجب أن تكون منفصلة
* علاقات لا تتلاءم بسلاسة
## Special Note on People, Companies, and Opportunities
## ملاحظة خاصة على الأشخاص، والشركات، والفرص
<Warning>
**Email and calendar sync only works with People, Companies, and Opportunities.**
**تعمل مزامنة البريد الإلكتروني والتقويم فقط مع الأشخاص والشركات والفرص.**
These are the only objects where you can access synchronized emails and meetings from your mailbox/calendar. We recommend using them as much as possible.
هذه هي الكائنات الوحيدة التي يمكنك من خلالها الوصول إلى رسائل البريد الإلكتروني والاجتماعات المتزامنة من علبة البريد/التقويم لديك. نوصي باستخدامها قدر الإمكان.
</Warning>
**Best practices:**
**أفضل الممارسات:**
* If you need categories of People, use fields (not new objects)
* Example: Use a `Person Type` field with values "Prospect" and "Partner" instead of creating separate objects
* Create different **views** to filter: one showing partners, another showing prospects
* إذا كنت بحاجة إلى تصنيفات للأشخاص، فاستخدم الحقول (وليس كائنات جديدة)
* مثال: استخدم حقل `Person Type` بقيم "عميل محتمل" و"شريك" بدلاً من إنشاء كائنات منفصلة
* أنشئ **عروضًا** مختلفة من أجل التصفية: أحدها يعرض الشركاء، وآخر يعرض العملاء المحتملين
**It's okay to have fields that don't apply to every record.** For example, a `Referral Link` field on People that only applies when `Person Type = Partner`. Hide this field from views where it's not relevant.
**لا بأس بوجود حقول لا تنطبق على كل سجل.** على سبيل المثال، حقل `Referral Link` على الأشخاص ينطبق فقط عندما يكون `Person Type = Partner`. أخفِ هذا الحقل من العروض التي لا تكون ذات صلة.
## Questions to Guide Your Choice
## أسئلة لتوجيه اختيارك
اسأل نفسك:
<Check>Is this just a property of something I already have, or does it need its own properties?</Check>
<Check>Will I ever need to track multiple of these per record, without knowing how many?</Check>
<Check>Does this concept connect to several different objects, not just one?</Check>
<Check>Will it have its own lifecycle (stages, start/end dates)?</Check>
<Check>هل هذه مجرد خاصية لشيء لدي بالفعل، أم أنها تحتاج إلى خصائص خاصة بها؟</Check>
<Check>هل سأحتاج يومًا إلى تتبّع عدة منها لكل سجل، دون معرفة عددها؟</Check>
<Check>هل يرتبط هذا المفهوم بعدة كائنات مختلفة، وليس بواحد فقط؟</Check>
<Check>هل ستكون له دورة حياة خاصة به (مراحل، تواريخ بدء/انتهاء)؟</Check>
If the answer is "yes" to one or more, it's probably time for a new object.
إذا كانت الإجابة "نعم" على واحد أو أكثر، فربما حان الوقت لإنشاء كائن جديد.
## Accessing Your Data Model
## الوصول إلى نموذج البيانات الخاص بك
1. Go to **Settings** in the left sidebar
2. Click **Data Model**
3. View all your objects (standard and custom)
4. Click any object to see and edit its fields
1. انتقل إلى **الإعدادات** في الشريط الجانبي الأيسر
2. انقر على **نموذج البيانات**
3. اعرض جميع كائناتك (القياسية والمخصصة)
4. انقر على أي كائن لعرض حقوله وتحريرها
<Note>
**Don't see Data Model in Settings?**
**لا ترى نموذج البيانات ضمن الإعدادات؟**
Access to the data model is usually restricted to administrators. Contact your workspace admin if you need access.
يكون الوصول إلى نموذج البيانات عادةً مقصورًا على المسؤولين. تواصل مع مشرف مساحة العمل إذا كنت بحاجة إلى الوصول.
</Note>
## الخطوات التالية
Once you've planned your data model:
بعد أن تخطّط لنموذج البيانات الخاص بك:
* [How to Create Custom Objects](/l/ar/user-guide/data-model/how-tos/create-custom-objects)
* [How to Create Custom Fields](/l/ar/user-guide/data-model/how-tos/create-custom-fields)
* [How to Create Relation Fields](/l/ar/user-guide/data-model/how-tos/create-relation-fields)
* [كيفية إنشاء كائنات مخصصة](/l/ar/user-guide/data-model/how-tos/create-custom-objects)
* [كيفية إنشاء حقول مخصصة](/l/ar/user-guide/data-model/how-tos/create-custom-fields)
* [كيفية إنشاء حقول العلاقات](/l/ar/user-guide/data-model/how-tos/create-relation-fields)
## هل تحتاج إلى مساعدة؟
Our team can help you design and create the data model you need. Discover our [Implementation Services](/l/ar/user-guide/getting-started/capabilities/implementation-services).
يمكن لفريقنا مساعدتك في تصميم وإنشاء نموذج البيانات الذي تحتاجه. اكتشف [خدمات التنفيذ الخاصة بنا](/l/ar/user-guide/getting-started/capabilities/implementation-services).
@@ -1,9 +1,9 @@
---
title: Configure Your Workspace
description: كل شركة تعمل بطريقة مختلفة. Start with these 3 steps to shape Twenty around your needs.
title: تهيئة مساحة عملك
description: كل شركة تعمل بطريقة مختلفة. ابدأ بهذه الخطوات الثلاث لتكييف Twenty وفق احتياجاتك.
---
<Note>**Quick Win**: Start with connecting your mailbox. يوفر لك ذلك قيمة فورية ويساعد فريقك على رؤية Twenty أثناء العمل من خلال البيانات الحقيقية. You can do so under Settings → Accounts.</Note>
<Note>**إنجاز سريع**: ابدأ بربط صندوق بريدك. يوفر لك ذلك قيمة فورية ويساعد فريقك على رؤية Twenty أثناء العمل من خلال البيانات الحقيقية. يمكنك القيام بذلك من خلال الإعدادات → الحسابات.</Note>
## 1. تخصيص نموذج البيانات الخاص بك
@@ -11,13 +11,13 @@ description: كل شركة تعمل بطريقة مختلفة. Start with these
قم بإنشاء كائنات وحقول من أي نوع، بما في ذلك العلاقات بين كائناتك المختلفة. يمكنك القيام بذلك من خلال الإعدادات ← نموذج البيانات.
إليك بعض النصائح:
* **You are not limited in the number of custom fields nor custom objects**. Adding custom objects and fields will not lead to upgrading your plan.
* **People, Companies and Opportunities are the three objects from where you can access the emails and meetings synchronized from your mailbox and calendar**. ننصح باستخدام هذه الخيارات بقدر الإمكان، مع إضافة الحقول لفرز سجلاتك عند الضرورة. إليك مثالاً:
* **لست مقيداً بعدد الحقول المخصصة ولا بعدد الكائنات المخصصة**. لن يؤدي إضافة الكائنات والحقول المخصصة إلى ترقية خطتك.
* **الأشخاص والشركات والفرص هي الكائنات الثلاثة التي يمكنك من خلالها الوصول إلى رسائل البريد الإلكتروني والاجتماعات المتزامنة من صندوق بريدك وتقويمك**. ننصح باستخدام هذه الخيارات بقدر الإمكان، مع إضافة الحقول لفرز سجلاتك عند الضرورة. إليك مثالاً:
* من الأفضل استخدام كائن الأشخاص لعملائك وشركائك، وإنشاء حقل باسم `نوع الشخص` بدلاً من إنشاء كائن مخصص للشريك. لأنه لن يكون بإمكانك الوصول إلى رسائل البريد الإلكتروني المتبادلة مع هذا الشخص من سجلات الشريك.
* قم بإنشاء وجهات نظر مختلفة في الأشخاص، واحدة لعرض الشركاء وأخرى لعرض العملاء المحتملين.
* لا يمكن أن يكون لشخصين نفس عنوان البريد الإلكتروني. لا يمكن أن يكون لشركتين نفس النطاق.
* يمكنك تعطيل الحقول والكائنات القياسية التي لا ترغب في استخدامها.
* You can hide fields from views: don't be afraid of creating fields, you won't have to display all of them.
* يمكنك إخفاء الحقول من العروض: لا تتردد في إنشاء حقول؛ فلن تضطر إلى عرضها جميعاً.
اقرأ [هذه المقالة](/l/ar/user-guide/data-model/overview) لتعلم كيفية تصميم نموذج بياناتك.
@@ -34,7 +34,7 @@ description: كل شركة تعمل بطريقة مختلفة. Start with these
* الحفاظ على تاريخ الاتصالات واضحًا لفريقك
**تستخدم مقدم خدمة آخر؟**
يمكنك إضافة بريد آخر عبر SMTP أو تقويم آخر عبر CalDAV. Go to **Settings → Accounts** to configure.
يمكنك إضافة بريد آخر عبر SMTP أو تقويم آخر عبر CalDAV. اذهب إلى **الإعدادات → الحسابات** لإجراء التهيئة.
### استيراد البيانات عبر csv
@@ -44,14 +44,14 @@ description: كل شركة تعمل بطريقة مختلفة. Start with these
* قم بتنزيل الملف النموذجي لفهم التنسيق المتوقع
* حدد كل ملف بـ 10 آلاف سجل
* Remove duplicate emails for People or duplicate domains for Companies
* أزل عناوين البريد الإلكتروني المكررة للأشخاص أو النطاقات المكررة للشركات
* راجع وقم بإصلاح الأخطاء (المميزة باللون الأصفر) قبل الاستيراد
اقرأ [هذه المقالة](/l/ar/user-guide/data-migration/overview) لمعرفة المزيد حول استيراد البيانات.
## ٣. قم بإنشاء منظر العرض الأول الخاص بك
Creating different views is key to make the data actionable for your team.
إنشاء عروض مختلفة هو المفتاح لجعل البيانات عملية لفريقك.
إليك كيفية المتابعة:
* **إضافة أو إخفاء الأعمدة**
@@ -1,13 +1,13 @@
---
title: الصلاحيات
description: Control access to objects, fields, and settings with role-based permissions.
description: تحكّم في الوصول إلى الكائنات والحقول والإعدادات باستخدام أذونات مستندة إلى الأدوار.
image: /images/user-guide/permissions/permissions.png
---
نظام أذونات Twenty يمكنك من التحكم في الوصول إلى ثلاثة مجالات رئيسية:
* **الكائنات والحقول**: التحكم بمن يمكنه عرض أو تعديل أو حذف السجلات والحقول الفردية
* **Settings**: Manage access to workspace configuration and administrative functions
* **الإعدادات**: إدارة الوصول إلى تكوين مساحة العمل والوظائف الإدارية
* **الإجراءات**: التحكم في الإجراءات العامة لمساحة العمل مثل استيراد البيانات أو إرسال رسائل البريد الإلكتروني
## إنشاء دور
@@ -17,8 +17,8 @@ image: /images/user-guide/permissions/permissions.png
1. اذهب إلى **الإعدادات → الأدوار**
2. تحت **كل الأدوار**، انقر على **+ إنشاء دور**
3. أدخل اسم الدور
4. In the default **Permissions** tab, [configure permissions](#customize-permissions)
5. Click **Save** to finish
4. في علامة التبويب الافتراضية **الأذونات**، [كوّن الأذونات](#customize-permissions)
5. انقر على **حفظ** للإنهاء
## حذف دور
@@ -30,7 +30,7 @@ image: /images/user-guide/permissions/permissions.png
4. انقر على **تأكيد** في النافذة المنبثقة
<Note>
If a role is deleted, any workspace member assigned to it will be automatically reassigned to the default role. All except the **Admin** role can be deleted. يجب دائمًا أن يكون هناك عضو واحد على الأقل معين على دور **المشرف**.
إذا تم حذف دور ما، فسيُعاد تعيين أي عضو في مساحة العمل مُعيَّن إلى ذلك الدور تلقائيًا إلى الدور الافتراضي. يمكن حذف جميع الأدوار باستثناء دور **المشرف**. يجب دائمًا أن يكون هناك عضو واحد على الأقل معين على دور **المشرف**.
</Note>
## تخصيص الأدوار للأعضاء
@@ -58,82 +58,82 @@ image: /images/user-guide/permissions/permissions.png
4. سيتم تعيين أعضاء مساحة العمل الجدد هذا الدور عند انضمامهم
<Note>
You can only assign roles to existing workspace members. لدعوة أعضاء جدد، استخدم [إدارة الأعضاء](/l/ar/user-guide/settings/capabilities/member-management).
يمكنك فقط تعيين الأدوار لأعضاء مساحة العمل الحاليين. لدعوة أعضاء جدد، استخدم [إدارة الأعضاء](/l/ar/user-guide/settings/capabilities/member-management).
</Note>
## تخصيص الأذونات
Permissions determine what each role can access or modify within your workspace, including workspace objects records, settings, and actions.
تحدد الأذونات ما يمكن لكل دور الوصول إليه أو تعديله ضمن مساحة عملك، بما في ذلك سجلات كائنات مساحة العمل، والإعدادات، والإجراءات.
### Object Permissions
### أذونات الكائنات
The **Objects** section controls what this role can do with records across your workspace.
يحدّد قسم **الكائنات** ما يمكن لهذا الدور فعله بالسجلات في مساحة عملك.
#### Set Default Permissions (All Objects)
#### تعيين الأذونات الافتراضية (جميع الكائنات)
First, configure the baseline permissions that apply to **all objects** by default:
أولًا، كوّن أذونات الأساس التي تنطبق افتراضيًا على **جميع الكائنات**:
| Permission | الوصف |
| --------------------------------- | -------------------------------------- |
| **عرض السجلات في جميع العناصر** | View records in lists and detail pages |
| **تحرير السجلات في جميع العناصر** | Modify existing records |
| **حذف السجلات من جميع العناصر** | Soft-delete records (can be restored) |
| **إتلاف السجلات في جميع العناصر** | Permanently delete records |
| الإذن | الوصف |
| --------------------------------- | -------------------------------------------- |
| **عرض السجلات في جميع العناصر** | عرض السجلات في القوائم وصفحات التفاصيل |
| **تحرير السجلات في جميع العناصر** | تعديل السجلات الموجودة |
| **حذف السجلات من جميع العناصر** | حذف السجلات حذفًا غير نهائي (يمكن استعادتها) |
| **إتلاف السجلات في جميع العناصر** | حذف السجلات نهائيًا |
Select or unselect based on what should be the default behavior for this role.
حدّد أو أزل التحديد استنادًا إلى ما ينبغي أن يكون السلوك الافتراضي لهذا الدور.
<Note>
**Example — Intern role**: An intern should be able to see all objects but not edit them by default. Enable "See Records on All Objects" but leave "Edit Records on All Objects" unchecked.
**مثال — دور المتدرب**: ينبغي للمتدرب أن يتمكن من رؤية جميع الكائنات ولكن دون تحريرها افتراضيًا. فعّل "عرض السجلات على جميع الكائنات" لكن اترك "تحرير السجلات على جميع الكائنات" غير محددة.
</Note>
#### Add Object-Level Exceptions
#### إضافة استثناءات على مستوى الكائن
After setting defaults, use the **Object-Level** sub-section to add rules that override the defaults for specific objects.
بعد تعيين القيم الافتراضية، استخدم القسم الفرعي **على مستوى الكائن** لإضافة قواعد تتجاوز القيم الافتراضية لكائنات محددة.
Click **+ Add rule** and select an object to create an exception.
انقر على **+ إضافة قاعدة** ثم اختر كائنًا لإنشاء استثناء.
**Example rules for an Intern role:**
**أمثلة على قواعد لدور المتدرب:**
| Rule | Effect |
| ------------------------------------- | ------------------------------------------------------ |
| Opportunities → disable "See Records" | Intern cannot see the Opportunities object at all |
| People → enable "Edit Records" | Intern can edit People records (but not other objects) |
| قاعدة | النتيجة |
| ------------------------------- | ----------------------------------------------------------- |
| الفرص → تعطيل "عرض السجلات" | لا يمكن للمتدرب رؤية كائن الفرص إطلاقًا |
| الأشخاص → تفعيل "تحرير السجلات" | يمكن للمتدرب تحرير سجلات الأشخاص (ولكن ليس الكائنات الأخرى) |
### Field Permissions
### أذونات الحقول
Within each object-level rule, you can go further and configure **field-level permissions** to control access to specific fields.
داخل كل قاعدة على مستوى الكائن، يمكنك المتابعة أبعد من ذلك وتكوين **أذونات على مستوى الحقل** للتحكم في الوصول إلى حقول محددة.
| Permission | الوصف |
| -------------- | -------------------------- |
| **See Field** | View the field value |
| **Edit Field** | Modify the field value |
| **No Access** | Field is completely hidden |
| الإذن | الوصف |
| --------------- | ------------------ |
| **عرض الحقل** | عرض قيمة الحقل |
| **تحرير الحقل** | تعديل قيمة الحقل |
| **لا وصول** | الحقل مخفي بالكامل |
**Example — Restrict sensitive fields:**
**مثال — تقييد الحقول الحساسة:**
For the Intern role with People edit access, you might want to restrict certain fields:
بالنسبة لدور المتدرب الذي لديه إمكانية تحرير الأشخاص، قد ترغب في تقييد حقول معينة:
* People → Email → **See Field** only (cannot edit)
* People → Address → **No Access** (completely hidden)
* الأشخاص → البريد الإلكتروني → **عرض الحقل** فقط (لا يمكن التحرير)
* الأشخاص → العنوان → **لا وصول** (مخفي بالكامل)
This allows the intern to edit most People fields while protecting sensitive information.
يسمح هذا للمتدرب بتحرير معظم حقول الأشخاص مع حماية المعلومات الحساسة.
### How Permission Inheritance Works
### كيفية عمل توريث الأذونات
Permissions cascade from general to specific:
تتدرج الأذونات من العام إلى المحدّد:
1. **All Objects** → sets the baseline for all objects
2. **Object-Level rules** → override the baseline for specific objects
3. **Field-Level rules** → override the object setting for specific fields
1. **جميع الكائنات** → يحدّد الأساس لجميع الكائنات
2. **قواعد على مستوى الكائن** → تتجاوز الأساس لكائنات محددة
3. **قواعد على مستوى الحقل** → تتجاوز إعداد الكائن لحقول محددة
More specific settings always take precedence.
الإعدادات الأكثر تحديدًا لها الأسبقية دائمًا.
### إدارة تجاوزات الأذونات
To override inherited permissions:
لتجاوز الأذونات الموروثة:
1. انقر على **X** لإزالة القاعدة الموروثة
2. Select the specific permissions you want
2. حدّد الأذونات المحددة التي تريدها
3. انقر على أيقونة **تراجع** البرتقالية (السهم الدائري) للتراجع عن التغييرات
عند الانتهاء، انقر على **إنهاء**، ثم **حفظ** عند العودة إلى صفحة الدور.
@@ -146,7 +146,7 @@ To override inherited permissions:
* أو تمكين أذونات محددة (مثل توليد مفتاح API، تفضيلات مساحة العمل، تعيين الأدوار، تكوين نموذج البيانات، إعدادات الأمان، وإدارة الحركات)
<Note>
**Current limitation**: Access to workflow management is currently required to manually trigger workflows. This behavior may change in future releases.
**قيد حالي**: يلزم الحصول على حق الوصول إلى إدارة سير العمل لبدء تشغيل عمليات سير العمل يدويًا. قد يتغير هذا السلوك في الإصدارات المستقبلية.
</Note>
### أذونات الإجراءات في مساحة العمل
@@ -156,43 +156,43 @@ To override inherited permissions:
* تبديل **الوصول الكامل للتطبيق** لمنح الأذونات الكاملة
* أو تمكين الإجراءات الفردية مثل **إرسال البريد الإلكتروني**، **استيراد CSV**، و**تصدير CSV**
## Assigning Roles to API Keys and AI Agents
## تعيين الأدوار لمفاتيح API ووكلاء الذكاء الاصطناعي
Beyond workspace members, roles can also be assigned to **API Keys** and **AI Agents**. This is particularly helpful for teams who want to control exactly "who" can do what in their workspace—including automated processes and integrations.
إضافةً إلى أعضاء مساحة العمل، يمكن أيضًا تعيين الأدوار إلى **مفاتيح API** و**وكلاء الذكاء الاصطناعي**. يساعد هذا بشكل خاص الفرق التي تريد التحكم بدقة في "من" يمكنه فعل ماذا في مساحة عملها—بما في ذلك العمليات المؤتمتة والتكاملات.
### Why Assign Roles to API Keys and AI Agents?
### لماذا نعيّن الأدوار لمفاتيح API ووكلاء الذكاء الاصطناعي؟
* **Security**: Limit what automated processes can access or modify
* **Compliance**: Ensure integrations only touch the data they need
* **Control**: Prevent accidental data changes from misconfigured automations
* **Auditability**: Track which actions were performed by which integration or agent
* **الأمان**: حدّد ما يمكن للعمليات المؤتمتة الوصول إليه أو تعديله
* **الامتثال**: تأكد من أن التكاملات لا تتعامل إلا مع البيانات التي تحتاجها
* **التحكم**: منع تغييرات البيانات العرضية الناتجة عن أتمتة مُعدّة بشكل غير صحيح
* **قابلية التدقيق**: تتبّع الإجراءات التي نفّذها كل تكامل أو وكيل
### Assign a Role to an API Key
### تعيين دور لمفتاح API
1. اذهب إلى **الإعدادات → الأدوار**
2. انقر على الدور الذي ترغب في تعيينه
3. افتح علامة التبويب **التعيين**
4. Under **API Keys**, click **+ Assign to API key**
5. Select the API key from the list
4. ضمن **مفاتيح API**، انقر على **+ تعيين إلى مفتاح API**
5. اختر مفتاح API من القائمة
6. أكد التعيين
The API key will now inherit all permissions defined by that role. Any API calls made with this key will be restricted accordingly.
سيرث مفتاح API الآن جميع الأذونات المحددة بواسطة ذلك الدور. سيتم تقييد أي استدعاءات API تُجرى بهذا المفتاح وفقًا لذلك.
<Note>
API keys without an assigned role use default permissions. For tighter security, always assign a specific role to production API keys.
تستخدم مفاتيح API التي لم يُعيَّن لها دور الأذونات الافتراضية. لأمانٍ أشد، عيّن دائمًا دورًا محددًا لمفاتيح API في بيئة الإنتاج.
</Note>
### Assign a Role to an AI Agent
### تعيين دور لوكيل ذكاء اصطناعي
1. اذهب إلى **الإعدادات → الأدوار**
2. انقر على الدور الذي ترغب في تعيينه
3. افتح علامة التبويب **التعيين**
4. Under **AI Agents**, click **+ Assign to AI agent**
5. Select the AI agent from the list
4. ضمن **وكلاء الذكاء الاصطناعي**، انقر على **+ تعيين إلى وكيل ذكاء اصطناعي**
5. اختر وكيل الذكاء الاصطناعي من القائمة
6. أكد التعيين
The AI agent will only be able to access data and perform actions allowed by its assigned role.
سيتمكن وكيل الذكاء الاصطناعي فقط من الوصول إلى البيانات وتنفيذ الإجراءات المسموح بها من قِبل دوره المعيّن.
<Note>
For AI agents running within workflows, this ensures the agent cannot access or modify data outside its intended scope—even if the workflow has broader permissions.
بالنسبة لوكلاء الذكاء الاصطناعي الذين يعملون ضمن سير العمل، يضمن ذلك أن الوكيل لا يمكنه الوصول إلى البيانات أو تعديلها خارج نطاقه المقصود—حتى إذا كان سير العمل يمتلك أذونات أوسع.
</Note>
@@ -1,125 +1,125 @@
---
title: SSO Configuration
description: Configure Single Sign-On for secure enterprise authentication.
title: تكوين SSO
description: قم بتكوين تسجيل الدخول الأحادي لضمان مصادقة مؤسسية آمنة.
---
## About SSO
## نبذة عن SSO
Single Sign-On (SSO) allows your team members to log into Twenty using your organization's identity provider. This provides:
يتيح تسجيل الدخول الأحادي (SSO) لأعضاء فريقك تسجيل الدخول إلى Twenty باستخدام موفّر الهوية الخاص بمؤسستك. يوفّر هذا ما يلي:
* **Centralized access control**: Manage access from one place
* **Enhanced security**: Leverage your existing security policies
* **Better user experience**: One set of credentials for all tools
* **التحكم المركزي في الوصول**: إدارة الوصول من مكان واحد
* **أمان معزَّز**: الاستفادة من سياسات الأمان الحالية لديك
* **تجربة مستخدم أفضل**: مجموعة بيانات اعتماد واحدة لجميع الأدوات
## Supported Providers
## الموفّرون المدعومون
Twenty supports SSO with:
تدعم Twenty SSO مع:
* **SAML 2.0**: Works with most enterprise identity providers
* **Google Workspace**: For organizations using Google
* **Microsoft Entra ID**: (formerly Azure AD) For Microsoft environments
* **SAML 2.0**: يعمل مع معظم موفّري الهوية للمؤسسات
* **Google Workspace**: للمؤسسات التي تستخدم Google
* **Microsoft Entra ID**: (سابقًا Azure AD) لبيئات Microsoft
## Setting Up SSO
## إعداد SSO
### Prerequisites
### المتطلبات الأساسية
* Organization plan (cloud and self-hosted workspaces)
* Admin access to your identity provider
* Admin access to Twenty workspace
* خطة المؤسسة (مساحات العمل السحابية والمستضافة ذاتيًا)
* وصول المسؤول إلى موفّر الهوية لديك
* وصول المسؤول إلى مساحة عمل Twenty
<Note>
**For self-hosting users willing to set up SSO**, reach out to contact@twenty.com
**للمستخدمين الذين يستضيفون ذاتيًا والراغبين في إعداد SSO**، تواصلوا عبر contact@twenty.com
</Note>
### Configuration Steps
### خطوات التكوين
#### 1. Access SSO Settings
#### 1. الوصول إلى إعدادات SSO
1. Go to **Settings → Security**
2. Find the **SSO Configuration** section
3. Click **Configure SSO**
1. اذهب إلى **الإعدادات → الأمان**
2. ابحث عن قسم **تكوين SSO**
3. انقر **Configure SSO**
#### 2) Choose Your Provider
#### 2) اختر موفّر الخدمة
Select your identity provider from the list or choose "Custom SAML" for other providers.
حدّد موفّر الهوية من القائمة أو اختر "Custom SAML" للموفّرين الآخرين.
#### ٣. Configure Your Identity Provider
#### ٣. قم بتكوين موفّر الهوية الخاص بك
You'll need to configure your identity provider with:
ستحتاج إلى تكوين موفّر الهوية لديك بما يلي:
* **Entity ID**: Provided by Twenty
* **ACS URL**: The callback URL for authentication
* **Certificate**: For secure communication
* **Entity ID**: يوفّره Twenty
* **ACS URL**: عنوان URL لمعاودة الاتصال للمصادقة
* **Certificate**: للتواصل الآمن
#### 4. Enter Provider Details in Twenty
#### 4. أدخل تفاصيل الموفّر في Twenty
* **SSO URL**: Login URL from your provider
* **Entity ID**: Your provider's identifier
* **Certificate**: X.509 certificate from your provider
* **SSO URL**: عنوان URL لتسجيل الدخول من موفّرك
* **Entity ID**: معرّف موفّرك
* **Certificate**: شهادة X.509 من موفّرك
#### 5. Test and Enable
#### 5. اختبر وفعّل
1. Click **Test Configuration** to verify setup
2. Enable SSO when testing is successful
3. Configure user provisioning preferences
1. انقر **Test Configuration** للتحقق من الإعداد
2. فعّل SSO عند نجاح الاختبار
3. قم بتكوين تفضيلات تزويد المستخدمين
## User Provisioning
## تزويد المستخدمين
### Just-in-Time (JIT) Provisioning
### التزويد الفوري (JIT)
* Users are created automatically on first login
* Assigned default role automatically
* No manual user creation needed
* يتم إنشاء المستخدمين تلقائيًا عند أول تسجيل دخول
* تعيين الدور الافتراضي لهم تلقائيًا
* لا حاجة لإنشاء المستخدمين يدويًا
### Manual Provisioning
### التزويد اليدوي
* Invite users before they can log in
* Pre-assign specific roles
* More control over who can access
* ادعُ المستخدمين قبل أن يتمكنوا من تسجيل الدخول
* تعيين أدوار محددة مسبقًا
* مزيد من التحكم بمن يمكنه الوصول
## Managing SSO Users
## إدارة مستخدمي SSO
### Role Assignment
### تعيين الأدوار
SSO users can be assigned roles like regular users:
يمكن تعيين أدوار لمستخدمي SSO مثل المستخدمين العاديين:
1. انتقل إلى **الإعدادات → الأعضاء**
2. Find the user
3. Change their role as needed
2. اعثر على المستخدم
3. غيّر دورهم حسب الحاجة
### Access Revocation
### سحب الوصول
To remove access for SSO users:
لإزالة الوصول لمستخدمي SSO:
* Remove them from your identity provider, or
* Remove them from the Twenty workspace
* أزِلهم من موفّر الهوية لديك، أو
* أزِلهم من مساحة عمل Twenty
## أفضل الممارسات
### Security
### الأمان
* **Require SSO**: Disable password login for SSO users
* **Regular audits**: Review access periodically
* **Strong IdP policies**: Enforce MFA at the identity provider
* **فرض استخدام SSO**: تعطيل تسجيل الدخول بكلمة المرور لمستخدمي SSO
* **عمليات تدقيق منتظمة**: مراجعة الوصول دوريًا
* **سياسات IdP قوية**: فرض المصادقة متعددة العوامل لدى موفّر الهوية
### User Management
### إدارة المستخدمين
* **Clear naming**: Use consistent naming from your directory
* **Group mapping**: Map IdP groups to Twenty roles (if available)
* **Offboarding process**: Include Twenty in your deprovisioning workflow
* **تسمية واضحة**: استخدم تسمية متسقة من الدليل لديك
* **مطابقة المجموعات**: طابق مجموعات IdP مع أدوار Twenty (إن وُجدت)
* **عملية إنهاء الخدمة**: ضمّن Twenty في سير عمل إلغاء التزويد
## استكشاف الأخطاء وإصلاحها
### Common Issues
### المشكلات الشائعة
* **Certificate errors**: Ensure certificate hasn't expired
* **URL mismatches**: Verify ACS URL matches exactly
* **User not found**: Check JIT provisioning settings
* **أخطاء الشهادة**: تأكد من أن الشهادة لم تنتهِ صلاحيتها
* **عدم تطابق عناوين URL**: تحقّق من تطابق ACS URL تمامًا
* **المستخدم غير موجود**: تحقّق من إعدادات التزويد الفوري (JIT)
### الحصول على المساعدة
If you encounter issues, contact support with:
إذا واجهت مشكلات، تواصل مع الدعم وقدّم ما يلي:
* Error messages received
* Identity provider being used
* Configuration details (without sensitive data)
* رسائل الخطأ المستلمة
* موفّر الهوية المستخدم
* تفاصيل التكوين (من دون بيانات حساسة)
@@ -1,36 +1,36 @@
---
title: Domain Settings
description: Configure workspace domain, approved access domains, and public domains.
title: إعدادات النطاق
description: قم بتكوين نطاق مساحة العمل، ونطاقات الوصول المعتمدة، والنطاقات العامة.
---
Configure domain settings under **Settings → Domains**.
قم بتكوين إعدادات النطاق ضمن **الإعدادات → النطاقات**.
## نطاق مساحة العمل
Edit your subdomain name or set a custom domain for your workspace.
قم بتعديل اسم النطاق الفرعي الخاص بك أو عيّن نطاقًا مخصصًا لمساحة العمل.
### تخصيص النطاق
1. Click **Customize Domain**
2. Edit your subdomain (e.g., `yourcompany.twenty.com`)
3. Or set up a custom domain (e.g., `crm.yourcompany.com`)
1. انقر **تخصيص النطاق**
2. عدّل نطاقك الفرعي (مثل: `yourcompany.twenty.com`)
3. أو قم بإعداد نطاق مخصص (مثل: `crm.yourcompany.com`)
For custom domains, you'll need to configure DNS settings with your domain provider.
بالنسبة للنطاقات المخصصة، ستحتاج إلى تكوين إعدادات DNS مع مزود النطاق الخاص بك.
## النطاقات المعتمدة
Anyone with an email address at these domains is allowed to sign up for this workspace automatically.
يُسمح لأي شخص لديه عنوان بريد إلكتروني ضمن هذه النطاقات بالتسجيل تلقائيًا في مساحة العمل هذه.
### إضافة نطاق وصول معتمد
1. Click **Add Approved Access Domain**
2. Enter your company domain (e.g., `yourcompany.com`)
1. انقر **إضافة نطاق وصول معتمد**
2. أدخل نطاق شركتك (مثل: `yourcompany.com`)
3. حفظ
Once configured, anyone with an email address at that domain can join your workspace without needing a direct invitation.
بعد الإعداد، يمكن لأي شخص لديه عنوان بريد إلكتروني ضمن ذلك النطاق الانضمام إلى مساحة العمل الخاصة بك دون الحاجة إلى دعوة مباشرة.
<Note>
This is useful for allowing your entire team to self-register while keeping the workspace restricted to your organization.
هذا مفيد للسماح لفريقك بالكامل بالتسجيل الذاتي مع إبقاء مساحة العمل مقصورة على مؤسستك.
</Note>
## النطاقات العامة
@@ -39,9 +39,9 @@ Once configured, anyone with an email address at that domain can join your works
### إضافة نطاق عام
1. Click **Add Public Domain**
2. Enter the domain you want to use
3. Configure DNS settings as instructed
4. Verify the domain
1. انقر **إضافة نطاق عام**
2. أدخل النطاق الذي تريد استخدامه
3. قم بتكوين إعدادات DNS وفق التعليمات
4. تحقق من النطاق
SSL certificates are automatically provisioned for public domains.
يتم توفير شهادات SSL تلقائيًا للنطاقات العامة.
@@ -1,36 +1,36 @@
---
title: Updates Settings
description: Enable Early Access features in Twenty.
title: إعدادات التحديثات
description: فعِّل ميزات الوصول المبكر في Twenty.
---
## About Updates Settings
## حول إعدادات التحديثات
The Updates section allows you to enable Early Access features before they're generally available.
يتيح لك قسم التحديثات تمكين ميزات الوصول المبكر قبل أن تصبح متاحة للجميع.
## Early Access Features
## ميزات الوصول المبكر
Early Access features are capabilities that are still being tested before general availability.
ميزات الوصول المبكر هي إمكانات لا تزال قيد الاختبار قبل الإتاحة العامة.
**Currently in Early Access:**
**حاليًا في الوصول المبكر:**
* **Dashboards** — Visual reporting and analytics
* **لوحات المعلومات** — التقارير المرئية والتحليلات
### How to Enable Early Access Features
### كيفية تمكين ميزات الوصول المبكر
1. Go to **Settings → Updates**
2. Navigate to the **Early Access** section
3. Find the feature you want to enable
4. Toggle it on
5. The feature will be available immediately
1. اذهب إلى **الإعدادات → التحديثات**
2. انتقل إلى قسم **الوصول المبكر**
3. ابحث عن الميزة التي تريد تمكينها
4. قم بتفعيلها
5. ستصبح الميزة متاحة على الفور
<Note>
Early Access features may change based on user feedback. Your input helps us improve Twenty!
قد تتغير ميزات الوصول المبكر بناءً على ملاحظات المستخدمين. تساعد ملاحظاتك على تحسين Twenty!
</Note>
## Feature Feedback
## ملاحظات حول الميزات
Your feedback helps improve Twenty:
تساعد ملاحظاتك على تحسين Twenty:
* Report issues with Early Access features
* Share how you're using new features
* Suggest improvements via the community Discord
* أبلغ عن المشكلات المتعلقة بميزات الوصول المبكر
* شارك كيفية استخدامك للميزات الجديدة
* اقترح تحسينات عبر مجتمع Discord
@@ -151,19 +151,19 @@ image: /images/user-guide/setup/settings.png
</Accordion>
</AccordionGroup>
## Early Access Features
## ميزات الوصول المبكر
<AccordionGroup>
<Accordion title="What are Early Access features?">
Early Access features are capabilities being tested before general release. Currently, only **Dashboards** are in Early Access. They may change based on user feedback.
<Accordion title="ما هي ميزات الوصول المبكر؟">
ميزات الوصول المبكر هي إمكانات يُجرى اختبارها قبل الإصدار العام. حاليًا، توجد **لوحات المعلومات** فقط ضمن الوصول المبكر. قد تتغير بناءً على ملاحظات المستخدمين.
</Accordion>
<Accordion title="Are Early Access features safe to use?">
Early Access features are functional but may change based on user feedback. They are safe to use but may evolve before general availability.
<Accordion title="هل ميزات الوصول المبكر آمنة للاستخدام؟">
ميزات الوصول المبكر تعمل لكنها قد تتغير بناءً على ملاحظات المستخدمين. هي آمنة للاستخدام، لكنها قد تتطور قبل الإصدار العام.
</Accordion>
<Accordion title="How do I enable Early Access features?">
1. Go to **Settings → Updates → Early Access**
<Accordion title="كيف أمكّن ميزات الوصول المبكر؟">
1. اذهب إلى **الإعدادات → التحديثات → الوصول المبكر**
2. ابحث عن الميزة التي تريدها
3. قم بتفعيلها
4. تصبح الميزة متاحة على الفور
@@ -1,78 +1,78 @@
---
title: Filters & Sorting
description: Filter and sort records to find exactly what you need.
title: التصفية والفرز
description: قم بتصفية السجلات وفرزها للعثور على ما تحتاج إليه بالضبط.
---
## Filtering Data
## تصفية البيانات
Filters help you focus on specific records by showing only those that match your criteria.
تساعدك عوامل التصفية على التركيز على سجلات محددة من خلال إظهار ما يطابق معاييرك فقط.
### Adding a Filter
### إضافة عامل تصفية
1. Click the **Filter** button in the toolbar
2. Select the field to filter by
3. Choose the operator (equals, contains, etc.)
4. Enter the filter value
5. Click **Apply**
1. انقر على زر **تصفية** في شريط الأدوات
2. اختر الحقل الذي تريد التصفية حسبه
3. اختر العامل (يساوي، يحتوي، إلخ)
4. أدخل قيمة التصفية
5. انقر على **تطبيق**
### Filter Operators
### عوامل التصفية
| Field Type | Available Operators |
| ----------- | -------------------------------------------------- |
| نص | Equals, Contains, Starts with, Ends with, Is empty |
| رقم | Equals, Greater than, Less than, Between, Is empty |
| تاريخ | Equals, Before, After, Between, Is empty |
| اختيار | Equals, Is any of, Is empty |
| مربع اختيار | Is true, Is false |
| علاقة | Equals, Is empty |
| نوع الحقل | العوامل المتاحة |
| ----------- | ------------------------------------- |
| نص | يساوي، يحتوي، يبدأ بـ، ينتهي بـ، فارغ |
| رقم | يساوي، أكبر من، أصغر من، بين، فارغ |
| تاريخ | يساوي، قبل، بعد، بين، فارغ |
| اختيار | يساوي، أي من، فارغ |
| مربع اختيار | صحيح، خطأ |
| علاقة | يساوي، فارغ |
### Multiple Filters
### عوامل تصفية متعددة
Combine multiple filters to narrow down results:
اجمع بين عدة عوامل تصفية لتضييق نطاق النتائج:
* All filters are applied with AND logic
* Each additional filter further restricts results
* تُطبَّق جميع عوامل التصفية بمنطق AND
* كل عامل تصفية إضافي يقيِّد النتائج أكثر
### Removing Filters
### إزالة عوامل التصفية
* Click the **X** on individual filter chips
* Click **Clear all** to remove all filters
* انقر على **X** الموجودة على كل شارة تصفية
* انقر على **مسح الكل** لإزالة جميع عوامل التصفية
## Sorting Data
## فرز البيانات
Sorting determines the order records appear.
يحدّد الفرز ترتيب ظهور السجلات.
### Adding a Sort
### إضافة فرز
1. Click the **Sort** button in the toolbar
2. Select the field to sort by
3. Choose ascending (A-Z, 0-9) or descending (Z-A, 9-0)
4. Click **Apply**
1. انقر على زر **فرز** في شريط الأدوات
2. اختر الحقل المراد الفرز بحسبه
3. اختر تصاعديًا (A-Z, 0-9) أو تنازليًا (Z-A, 9-0)
4. انقر على **تطبيق**
### Multiple Sorts
### عمليات فرز متعددة
Add multiple sort levels:
أضف مستويات فرز متعددة:
* First sort is primary
* Subsequent sorts apply within groups of equal values
* الفرز الأول أساسي
* تُطبَّق عمليات الفرز اللاحقة ضمن مجموعات القيم المتساوية
### Quick Column Sorting
### فرز الأعمدة السريع
Click any column header to sort:
انقر على أي عنوان عمود للفرز:
* First click: Ascending
* Second click: Descending
* Third click: Remove sort
* النقرة الأولى: تصاعدي
* النقرة الثانية: تنازلي
* النقرة الثالثة: إزالة الفرز
## Saving Filter and Sort Settings
## حفظ إعدادات التصفية والفرز
Filters and sorts are saved with the view:
تُحفَظ عوامل التصفية وعمليات الفرز مع طريقة العرض:
1. Configure your filters and sorts
2. Click **Save** to update the current view
3. Or click **Save as new view** to create a variant
1. قم بتهيئة عوامل التصفية وعمليات الفرز
2. انقر على **حفظ** لتحديث طريقة العرض الحالية
3. أو انقر على **حفظ كطريقة عرض جديدة** لإنشاء نسخة بديلة
## Related
## ذات صلة
* [Table Views](/l/ar/user-guide/views-pipelines/capabilities/table-views) — group by feature
* [Views Overview](/l/ar/user-guide/views-pipelines/overview) — building and managing views
* [عروض الجدول](/l/ar/user-guide/views-pipelines/capabilities/table-views) — ميزة التجميع بحسب
* [نظرة عامة على طرق العرض](/l/ar/user-guide/views-pipelines/overview) — إنشاء طرق العرض وإدارتها
@@ -1,80 +1,80 @@
---
title: Create a Kanban View for Projects
description: Track projects through stages using a visual board.
title: إنشاء عرض كانبان للمشاريع
description: تتبّع المشاريع عبر المراحل باستخدام لوحة مرئية.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
Use a Kanban view to visualize your projects (or any object with stages) as cards moving through columns.
استخدم عرض كانبان لتمثيل مشاريعك بصريًا (أو أي كائن ذي مراحل) كبطاقات تتحرك عبر الأعمدة.
<VimeoEmbed videoId="927888627" title="Video demonstration" />
<VimeoEmbed videoId="927888627" title="عرض توضيحي بالفيديو" />
## Prerequisites
## المتطلبات الأساسية
Your object needs a **Select field** to use as columns (e.g., Status, Stage, Phase).
يحتاج الكائن الخاص بك إلى **حقل Select** لاستخدامه كأعمدة (مثل: الحالة، المرحلة، الطور).
If you don't have one:
إذا لم يكن لديك واحد:
1. Go to **Settings → Data Model**
2. Select your object
3. Add a Select field with your stage options
1. اذهب إلى **الإعدادات → نموذج البيانات**
2. اختر الكائن الخاص بك
3. أضف حقل Select مع خيارات المراحل لديك
## Steps
## الخطوات
1. Navigate to your object (e.g., Projects, Tasks)
2. Click the view dropdown → **+ Add view**
3. Name your view (e.g., "Project Board")
4. Click **Create**
5. Click **Options** and select **Kanban** as the layout
6. The view uses your Select field for columns automatically
1. انتقل إلى الكائن الخاص بك (مثل: المشاريع، المهام)
2. انقر على القائمة المنسدلة لطريقة العرض → **+ إضافة طريقة عرض**
3. قم بتسمية العرض (مثال: "لوحة المشروع")
4. انقر على **إنشاء**
5. انقر على **الخيارات** واختر **كانبان** كتخطيط
6. يستخدم العرض حقل Select الخاص بك للأعمدة تلقائيًا
7. انقر على **حفظ**
## Configure Your Board
## تهيئة لوحتك
### Show Key Fields on Cards
### إظهار الحقول الرئيسية على البطاقات
1. Click **Options → Fields**
2. Find fields in the "Hidden Fields" section
3. Click the **eye icon** to display them on cards
4. Drag to reorder
1. انقر على **الخيارات → الحقول**
2. ابحث عن الحقول في قسم "الحقول المخفية"
3. انقر على **أيقونة العين** لعرضها على البطاقات
4. اسحب لإعادة الترتيب
<img src="/images/user-guide/kanban-views/filter.png" style={{width:'100%'}} />
### Enable Compact View
### تمكين العرض المضغوط
For a high-level overview:
للحصول على نظرة عامة عالية المستوى:
1. Click **Options**
2. Turn on **Compact view**
1. انقر على **الخيارات**
2. فعِّل **العرض المضغوط**
Cards show only the record name.
تعرض البطاقات اسم السجل فقط.
<img src="/images/user-guide/kanban-views/compact-view.png" style={{width:'100%'}} />
### Add Aggregations
### إضافة عمليات التجميع
Show counts or totals at the top of each column:
اعرض الأعداد أو الإجماليات أعلى كل عمود:
1. Click the number next to a column name
2. Select an aggregation (Count, Sum, etc.)
3. Choose a field if needed
1. انقر على الرقم بجوار اسم العمود
2. حدّد عملية التجميع (Count، Sum، إلخ)
3. اختر حقلاً إذا لزم الأمر
## Moving Cards
## نقل البطاقات
Drag and drop cards between columns to update their status.
اسحب وأفلِت البطاقات بين الأعمدة لتحديث حالتها.
<VimeoEmbed videoId="927888627" title="Video demonstration" />
<VimeoEmbed videoId="927888627" title="عرض توضيحي بالفيديو" />
## Example: Task Board
## مثال: لوحة المهام
| Column (Status) | Cards |
| --------------- | ----------------- |
| **To Do** | New tasks |
| **In Progress** | Active work |
| **Review** | Awaiting approval |
| **Done** | Completed |
| العمود (الحالة) | البطاقات |
| --------------- | ------------------ |
| **للتنفيذ** | مهام جديدة |
| **قيد التقدم** | عمل نشط |
| **مراجعة** | في انتظار الموافقة |
| **تم** | مكتمل |
## Related
## ذات صلة
* [Kanban Views](/l/ar/user-guide/views-pipelines/capabilities/kanban-views) — aggregations, compact view, stages
* [How to Set Up a Sales Pipeline](/l/ar/user-guide/views-pipelines/how-tos/set-up-a-sales-pipeline) — Kanban for Opportunities
* [عروض كانبان](/l/ar/user-guide/views-pipelines/capabilities/kanban-views) — عمليات التجميع، العرض المضغوط، المراحل
* [كيفية إعداد مسار مبيعات](/l/ar/user-guide/views-pipelines/how-tos/set-up-a-sales-pipeline) — كانبان للفرص
@@ -116,6 +116,29 @@ image: /images/user-guide/workflows/workflow.png
* الموضوع: متابعة لمحادثتنا
* المحتوى: الإشارة إلى تفاصيل الاجتماع من المشغّل
## Email Attachments
You can attach files to emails sent from workflows. The attachment is a static file that you upload when configuring the workflow.
### How to Add an Attachment
1. In the **Send Email** action, click on the **Attachments** button
2. Click to upload a file from your computer
3. The file will be attached to all emails sent by this action
### الاستخدامات الشائعة
| حالة الاستخدام | Example File |
| ------------------------ | ----------------------------- |
| **Welcome emails** | Company brochure (PDF) |
| **Onboarding sequences** | Getting started guide |
| **Sales follow-ups** | Product catalog or price list |
| **Event confirmations** | Event details or agenda |
<Note>
Attachments are static—the same file is sent to all recipients. For dynamic documents (like personalized quotes), generate and attach files using a [Serverless Function](/l/ar/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty).
</Note>
## أفضل الممارسات
### محتوى البريد الإلكتروني
@@ -139,10 +162,6 @@ image: /images/user-guide/workflows/workflow.png
* راجِع عمليات تشغيل سير العمل بحثاً عن رسائل الخطأ
* اختبر باستخدام عنوان بريدك الإلكتروني أولاً
<Note>
**قريباً**: ستكون مرفقات البريد الإلكتروني متاحة في الربع الأول من 2026.
</Note>
## ذات صلة
* [مشغلات سير العمل](/l/ar/user-guide/workflows/capabilities/workflow-triggers)
@@ -1,176 +1,176 @@
---
title: Use Iterator
description: Loop through arrays of records to perform actions on each item.
title: استخدم المكرّر
description: قم بالتكرار عبر مصفوفات السجلات لتنفيذ إجراءات على كل عنصر.
image: /images/user-guide/workflows/workflow.png
---
Iterator lets you loop through an array of records and perform actions on each one. It's essential for workflows that need to process multiple records returned by Search Records or received via webhooks.
يتيح لك المكرّر التكرار عبر مصفوفة من السجلات وتنفيذ إجراءات على كلٍ منها. وهو ضروري لتدفّقات العمل التي تحتاج إلى معالجة سجلات متعددة أُرجعت بواسطة Search Records أو استُلِمت عبر ربط الويب.
## When to Use Iterator
## متى تستخدم المكرّر
| Scenario | مثال |
| -------------------------- | ---------------------------------------------- |
| **Process search results** | Send email to each person found |
| **Handle webhook arrays** | Create records for each item in order |
| **Bulk updates** | Update multiple records with calculated values |
| **Notifications** | Alert multiple people about an event |
| السيناريو | مثال |
| -------------------------------- | --------------------------------------------- |
| **معالجة نتائج البحث** | إرسال بريد إلكتروني إلى كل شخص تم العثور عليه |
| **التعامل مع مصفوفات ربط الويب** | إنشاء سجلات لكل عنصر بالتسلسل |
| **التحديثات الدفعيّة** | تحديث عدة سجلات بقيم محسوبة |
| **إشعارات** | تنبيه عدة أشخاص بخصوص حدثٍ ما |
## Understanding Iterator
## فهم المكرّر
Iterator expects an **array** as input. It then:
يتوقع المكرّر إدخالاً عبارة عن **مصفوفة**. ثم يقوم بما يلي:
1. Takes the first item from the array
2. Runs all actions inside the iterator with that item
3. Moves to the next item
4. Repeats until all items are processed
1. يأخذ أول عنصر من المصفوفة
2. يشغّل جميع الإجراءات داخل المكرّر باستخدام ذلك العنصر
3. ينتقل إلى العنصر التالي
4. يكرّر حتى تتم معالجة جميع العناصر
## Basic Setup
## الإعداد الأساسي
### Example: Email Everyone in Search Results
### مثال: إرسال بريد إلكتروني للجميع ضمن نتائج البحث
**Goal**: Find all contacts in a specific company and send each one a personalized email.
**الهدف**: العثور على جميع جهات الاتصال في شركة محددة وإرسال بريد إلكتروني مخصص لكلٍ منهم.
### Step 1: Search for Records
### الخطوة 1: البحث عن سجلات
1. Add **Search Records** action
2. Object: **People**
3. Filter: Company equals "Acme Inc"
4. This returns an array of people
1. أضف إجراء **Search Records**
2. الكائن: **People**
3. عامل التصفية: Company يساوي "Acme Inc"
4. يُرجِع هذا مصفوفة من الأشخاص
### Step 2: Check Results Exist
### الخطوة 2: التحقق من وجود نتائج
1. Add **Filter** action
2. Condition: `{{searchRecords.length}}` is greater than 0
3. This prevents Iterator errors on empty results
1. أضف إجراء **Filter**
2. الشرط: `{{searchRecords.length}}` أكبر من 0
3. يمنع هذا أخطاء المكرّر عند كون النتائج فارغة
### Step 3: Add Iterator
### الخطوة 3: إضافة Iterator
1. Add **Iterator** action
2. Array input: Select `{{searchRecords}}`
3. This creates a loop
1. أضف إجراء **Iterator**
2. مدخل المصفوفة: اختر `{{searchRecords}}`
3. هذا ينشئ حلقة تكرار
### Step 4: Add Actions Inside Iterator
### الخطوة 4: إضافة إجراءات داخل المكرّر
Actions placed after Iterator run for each item:
الإجراءات الموضوعة بعد Iterator تُشغَّل لكل عنصر:
1. Add **Send Email** action (inside iterator)
2. To: `{{iterator.currentItem.email}}`
3. Subject: Hello `{{iterator.currentItem.firstName}}`!
4. Body: Personalized message using current item fields
1. أضف إجراء **Send Email** (داخل المكرّر)
2. إلى: `{{iterator.currentItem.email}}`
3. الموضوع: مرحباً `{{iterator.currentItem.firstName}}`!
4. المتن: رسالة مخصّصة باستخدام حقول العنصر الحالي
### النتيجة
If Search Records returns 5 people, the Iterator:
إذا أعاد Search Records 5 أشخاص، فسيقوم المكرّر بما يلي:
* Sends email to person 1
* Sends email to person 2
* ... continues for all 5
* يرسل بريداً إلكترونياً إلى الشخص 1
* يرسل بريداً إلكترونياً إلى الشخص 2
* ... يستمر لكل الأشخاص الخمسة
## Accessing Current Item Data
## الوصول إلى بيانات العنصر الحالي
Inside Iterator, use `{{iterator.currentItem}}` to access the current record:
داخل المكرّر، استخدم `{{iterator.currentItem}}` للوصول إلى السجل الحالي:
| Variable | الوصف |
| --------------------------------------- | ----------------------------------- |
| `{{iterator.currentItem}}` | The entire current record object |
| `{{iterator.currentItem.id}}` | Record ID |
| `{{iterator.currentItem.email}}` | Email field |
| `{{iterator.currentItem.company.name}}` | Related company name |
| `{{iterator.index}}` | Current position in array (0-based) |
| المتغيّر | الوصف |
| --------------------------------------- | -------------------------------------- |
| `{{iterator.currentItem}}` | كائن السجل الحالي بالكامل |
| `{{iterator.currentItem.id}}` | معرّف السجل |
| `{{iterator.currentItem.email}}` | حقل البريد الإلكتروني |
| `{{iterator.currentItem.company.name}}` | اسم الشركة المرتبطة |
| `{{iterator.index}}` | الموضع الحالي في المصفوفة (بدءاً من 0) |
## Common Patterns
## أنماط شائعة
### Update Multiple Records
### تحديث عدة سجلات
**Goal**: Mark all overdue tasks as "Late"
**الهدف**: وضع علامة "متأخر" على جميع المهام المتأخرة عن موعدها
```
1. Search Records (Tasks, Due Date < Today, Status ≠ Completed)
2. Filter (length > 0)
1. Search Records (المهام، تاريخ الاستحقاق < اليوم، الحالة ≠ مكتمل)
2. عامل تصفية (length > 0)
3. Iterator (searchRecords)
└── Update Record
- Object: Tasks
- Record: {{iterator.currentItem.id}}
- Status: Late
└── تحديث سجل
- الكائن: المهام
- السجل: {{iterator.currentItem.id}}
- الحالة: متأخر
```
### Create Records from Array
### إنشاء سجلات من مصفوفة
**Goal**: Webhook receives order with multiple items, create a record for each
**الهدف**: يتلقى الويبهوك طلباً يتضمن عدة عناصر، وإنشاء سجل لكل عنصر
```
1. Webhook Trigger (receives items array)
2. Filter (items.length > 0)
1. مشغّل الويبهوك (يتلقى مصفوفة العناصر)
2. عامل تصفية (items.length > 0)
3. Iterator (trigger.body.items)
└── Create Record
- Object: Order Items
- Name: {{iterator.currentItem.name}}
- Quantity: {{iterator.currentItem.qty}}
- Related Order: {{trigger.body.orderId}}
└── إنشاء سجل
- الكائن: عناصر الطلب
- الاسم: {{iterator.currentItem.name}}
- الكمية: {{iterator.currentItem.qty}}
- الطلب المرتبط: {{trigger.body.orderId}}
```
### Conditional Processing Inside Loop
### معالجة مشروطة داخل الحلقة
**Goal**: Only send email to contacts with valid emails
**الهدف**: إرسال بريد إلكتروني فقط لجهات الاتصال ذات العناوين الصالحة
```
1. Search Records (People)
1. Search Records (الأشخاص)
2. Iterator (searchRecords)
└── Filter (currentItem.email is not empty)
└── Send Email
- To: {{iterator.currentItem.email}}
└── عامل تصفية (currentItem.email غير فارغ)
└── إرسال بريد إلكتروني
- إلى: {{iterator.currentItem.email}}
```
## استكشاف الأخطاء وإصلاحها
### "Iterator expects an array"
### "المكرّر يتوقع مصفوفة"
**Cause**: You passed a single record instead of an array.
**السبب**: مرّرت سجلاً مفرداً بدلاً من مصفوفة.
**Fix**: Make sure you're passing the result of Search Records or an array field, not a single record.
**الإصلاح**: تأكّد من أنك تمرّر ناتج Search Records أو حقلاً من نوع مصفوفة، وليس سجلاً مفرداً.
```
✅ Correct: {{searchRecords}}
❌ Wrong: {{searchRecords[0]}}
```
### Iterator Doesn't Run
### المكرّر لا يعمل
**Cause**: The array is empty.
**السبب**: المصفوفة فارغة.
**Fix**: Add a Filter before Iterator to check array length:
**الإصلاح**: أضف عامل تصفية قبل Iterator للتحقق من طول المصفوفة:
```
Filter: {{searchRecords.length}} > 0
```
### Actions Run Too Many Times
### الإجراءات تُشغَّل مرات كثيرة جداً
**Cause**: Search Records returned more records than expected.
**السبب**: أعاد Search Records سجلات أكثر مما هو متوقّع.
**Fix**:
**الإصلاح**:
* Add more specific filters to Search Records
* Set a limit on Search Records (max 200)
* Add Filter inside Iterator for additional conditions
* أضف عوامل تصفية أكثر تحديداً إلى Search Records
* عيّن حداً في Search Records (بحد أقصى 200)
* أضف عامل تصفية داخل المكرّر لشروط إضافية
## Performance Considerations
## اعتبارات الأداء
* **Credit usage**: Each iteration consumes credits for its actions
* **Time**: Large arrays take longer to process
* **Limits**: Consider batching very large operations
* **Rate limits**: External API calls may hit rate limits with many iterations
* **استخدام الأرصدة**: كل دورة تستهلك أرصدة لإجراءاتها
* **الوقت**: تستغرق المصفوفات الكبيرة وقتاً أطول للمعالجة
* **القيود**: فكّر في تنفيذ العمليات الكبيرة جداً على دفعات
* **قيود المعدّل**: قد تصل استدعاءات واجهات برمجة التطبيقات الخارجية إلى حدود المعدّل مع كثرة التكرارات
## أفضل الممارسات
1. **Always check array length** before Iterator to avoid errors
2. **Add filters inside loops** when not all items need processing
3. **Rename your Iterator step** to describe what it's looping through
4. **Test with small arrays** before processing large datasets
5. **Monitor workflow runs** to ensure iterations complete as expected
1. **تحقق دائماً من طول المصفوفة** قبل Iterator لتجنّب الأخطاء
2. **أضف عوامل تصفية داخل الحلقات** عندما لا تحتاج جميع العناصر إلى معالجة
3. **أعد تسمية خطوة Iterator** لوصف ما تقوم بالتكرار عليه
4. **اختبر باستخدام مصفوفات صغيرة** قبل معالجة مجموعات بيانات كبيرة
5. **راقب تشغيلات سير العمل** لضمان اكتمال التكرارات كما هو متوقّع
## Related
## ذات صلة
* [Workflow Actions](/l/ar/user-guide/workflows/capabilities/workflow-actions)
* [How to Use Branches](/l/ar/user-guide/workflows/capabilities/use-branches-in-workflows)
* [Workflows FAQ](/l/ar/user-guide/workflows/how-tos/need-more-help/workflows-faq)
* [إجراءات سير العمل](/l/ar/user-guide/workflows/capabilities/workflow-actions)
* [كيفية استخدام التفرعات](/l/ar/user-guide/workflows/capabilities/use-branches-in-workflows)
* [الأسئلة الشائعة حول سير العمل](/l/ar/user-guide/workflows/how-tos/need-more-help/workflows-faq)
@@ -1,26 +1,26 @@
---
title: رصيد سير العمل
description: Understand workflow credit consumption and management.
description: فهم استهلاك أرصدة سير العمل وإدارتها.
---
Workflow credits power your automations in Twenty. فهم كيفية عملها يساعدك على تحسين التكاليف وإدارة ميزانية الأتمتة بفعالية.
أرصدة سير العمل تدعم عمليات الأتمتة لديك في Twenty. فهم كيفية عملها يساعدك على تحسين التكاليف وإدارة ميزانية الأتمتة بفعالية.
## Credit Allocation
## تخصيص الأرصدة
Workflow credits are allocated based on your billing cycle, not your plan tier:
تخصص أرصدة سير العمل بناء على دورة الفوترة لديك، وليس على مستوى خطتك:
| Billing Cycle | Credits |
| ------------------------ | --------------------------- |
| **Monthly subscription** | 5 million credits per month |
| **Yearly subscription** | 50 million credits per year |
| دورة الفوترة | الأرصدة |
| --------------- | ---------------------- |
| **اشتراك شهري** | 5 ملايين رصيد في الشهر |
| **اشتراك سنوي** | 50 مليون رصيد في السنة |
<Note>
5 million monthly credits are generous for standard automations. Most teams won't exceed this limit with typical workflow usage. Additional credits are primarily needed for advanced Code actions and AI-powered workflows.
تعد 5 ملايين رصيد في الشهر سخية لعمليات الأتمتة القياسية. لن تتجاوز معظم الفرق هذا الحد مع استخدام سير العمل النموذجي. تكون الحاجة إلى أرصدة إضافية أساسًا لإجراءات Code المتقدمة ولعمليات سير العمل المدعومة بالذكاء الاصطناعي.
</Note>
## كيف يعمل استهلاك الرصيد
Credits are consumed when workflows execute, not when you create them. يستهلك كل إجراء سير عمل الرصيد بناءً على تعقيده.
يتم استهلاك الأرصدة عند تنفيذ عمليات سير العمل، وليس عند إنشائها. يستهلك كل إجراء سير عمل الرصيد بناءً على تعقيده.
### استهلاك الرصيد حسب نوع الإجراء
@@ -29,40 +29,40 @@ Credits are consumed when workflows execute, not when you create them. يسته
* إنشاء سجل
* تحديث السجل
* حذف السجل
* Form actions
* إجراءات النماذج
* **Complex operations**: Higher credit consumption
* **عمليات معقدة**: استهلاك أعلى للأرصدة
* إجراءات الكود (تنفيذ JavaScript)
* طلبات HTTP إلى الخدمات الخارجية
* **AI features**: Higher credit consumption
* AI Agent actions consume credits based on the AI model used
* More complex prompts and longer outputs use more credits
* **ميزات الذكاء الاصطناعي**: استهلاك أعلى للأرصدة
* تستهلك إجراءات وكيل الذكاء الاصطناعي الأرصدة بناء على نموذج الذكاء الاصطناعي المستخدم
* تستخدم المطالبات الأكثر تعقيدا والمخرجات الأطول أرصدة أكثر
* **Delay actions**: Minimal credit consumption
* The Delay node consumes **1 credit** when it executes
* **No credits are consumed** during the wait period
* A 5-minute delay costs the same as a 5-day delay
* **إجراءات التأخير**: استهلاك ضئيل للأرصدة
* تستهلك عقدة Delay **رصيد واحد** عند التنفيذ
* **لا تستهلك أي أرصدة** خلال فترة الانتظار
* التأخير لمدة 5 دقائق يكلف المقدار نفسه مثل التأخير لمدة 5 أيام
### الخصم في الوقت الحقيقي
يتم خصم الرصيد في الوقت الفعلي عند تنفيذ سير العمل. هذا يعني:
* Draft workflows don't consume credits
* Only active, running workflows use your credit allocation
* Failed workflows still consume credits for completed steps
* لا تستهلك مسودات سير العمل أرصدة.
* لا تستخدم مخصص الأرصدة لديك إلا عمليات سير العمل النشطة والجارية.
* تظل عمليات سير العمل الفاشلة تستهلك أرصدة مقابل الخطوات المكتملة.
## إدارة الرصيد
### التحقق من استخدام الرصيد
1. اذهب إلى **الإعدادات → الفواتير**
2. View your current credit consumption and remaining balance
3. Monitor usage patterns to optimize your workflows
2. اعرض استهلاكك الحالي من الأرصدة والرصيد المتبقي
3. راقب أنماط الاستخدام لتحسين عمليات سير العمل لديك
### شراء رصيد إضافي
If you need more credits beyond your plan allocation:
إذا كنت بحاجة إلى المزيد من الأرصدة بما يتجاوز مخصص خطتك:
1. اذهب إلى **الإعدادات → الفواتير**
2. اضغط على الخيار لشراء رصيد إضافي. توفر باقات بأحجام مختلفة.
@@ -71,6 +71,6 @@ If you need more credits beyond your plan allocation:
## أفضل الممارسات
* **المعالجة الدفعية**: استخدم العمليات الجماعية وإجراءات المكرر بفعالية
* **Manual Trigger Optimization**: For manual triggers, choose `Bulk` availability to process multiple records in a single workflow run
* **تحسين المشغلات اليدوية**: بالنسبة للمشغلات اليدوية، اختر خيار التوفر `Bulk` لمعالجة سجلات متعددة في تشغيل واحد لسير عمل
* تحسين إجراءات الكود للكفاءة
* قم بتجميع العمليات لتقليل طلبات الإجراءات الفردية
@@ -1,54 +1,54 @@
---
title: Generate a PDF from Twenty
description: Create a workflow to generate and attach a PDF (such as a quote) to a record.
title: إنشاء ملف PDF من Twenty
description: أنشئ سير عمل لإنشاء ملف PDF (مثل عرض سعر) وإرفاقه بسجل.
---
Automatically generate or fetch a PDF and attach it to a record in Twenty. This is commonly used to create quotes, invoices, or reports that are linked to Companies, Opportunities, or other objects.
أنشئ أو اجلب ملف PDF تلقائيًا وأرفقه بسجل في Twenty. يُستخدم هذا عادةً لإنشاء عروض أسعار أو فواتير أو تقارير مرتبطة بالشركات أو الفرص أو كائنات أخرى.
## نظرة عامة
This workflow uses a **Manual Trigger** so users can generate a PDF on demand for any selected record. A **Serverless Function** handles:
يستخدم سير العمل هذا **المحفز اليدوي** بحيث يتمكن المستخدمون من إنشاء ملف PDF عند الطلب لأي سجل محدد. **وظيفة بلا خادم** تتولى ما يلي:
1. Downloading the PDF from a URL (from a PDF generation service)
2. Uploading the file to Twenty
3. Creating an Attachment linked to the record
1. تنزيل ملف PDF من عنوان URL (من خدمة إنشاء PDF)
2. رفع الملف إلى Twenty
3. إنشاء مرفق مرتبط بالسجل
## المتطلبات الأساسية
Before setting up the workflow:
قبل إعداد سير العمل:
1. **Create an API Key**: Go to **Settings → APIs** and create a new API key. You'll need this token for the serverless function.
2. **Set up a PDF generation service** (optional): If you want to dynamically generate PDFs (e.g., quotes), use a service like Carbone, PDFMonkey, or DocuSeal to create the PDF and get a download URL.
1. **أنشئ مفتاح API**: انتقل إلى **الإعدادات → واجهات برمجة التطبيقات** ثم أنشئ مفتاح API جديدًا. ستحتاج إلى هذا الرمز المميز للوظيفة بلا خادم.
2. **قم بإعداد خدمة إنشاء PDF** (اختياري): إذا كنت تريد إنشاء ملفات PDF ديناميكيًا (مثل عروض الأسعار)، فاستخدم خدمة مثل Carbone أو PDFMonkey أو DocuSeal لإنشاء ملف PDF والحصول على رابط تنزيل.
## إعداد خطوة بخطوة
### الخطوة 1: تهيئة المشغّل
1. Go to **Workflows** and create a new workflow
2. Select **Manual Trigger**
3. Choose the object you want to attach PDFs to (e.g., **Company** or **Opportunity**)
1. انتقل إلى **سير العمل** وأنشئ سير عمل جديدًا
2. اختر **المحفز اليدوي**
3. اختر الكائن الذي تريد إرفاق ملفات PDF به (مثل **شركة** أو **فرصة**)
<Tip>
With a Manual Trigger, users can run this workflow using a button that appears on the top right once a record is selected, to generate and attach a PDF.
باستخدام المحفز اليدوي، يمكن للمستخدمين تشغيل سير العمل هذا عبر زر يظهر في أعلى اليمين عند تحديد سجل، وذلك لإنشاء ملف PDF وإرفاقه.
</Tip>
### Step 2: Add a Serverless Function
### الخطوة 2: إضافة وظيفة بلا خادم
1. Add a **Serverless Function** action
2. Create a new function with the code below
3. Configure the input parameters
1. أضف إجراء **وظيفة بلا خادم**
2. أنشئ وظيفة جديدة باستخدام الكود أدناه
3. قم بتهيئة معلمات الإدخال
#### Input Parameters
#### معلمات الإدخال
| Parameter | القيمة |
| المعلمة | القيمة |
| ----------- | ----------------------- |
| `companyId` | `{{trigger.object.id}}` |
<Note>
If attaching to a different object (Person, Opportunity, etc.), rename the parameter accordingly (e.g., `personId`, `opportunityId`) and update the serverless function.
إذا كنت تُرفق إلى كائن مختلف (شخص، فرصة، إلخ)، فأعد تسمية المعلمة وفقًا لذلك (مثلًا، `personId`، `opportunityId`) وحدث الوظيفة بلا خادم.
</Note>
#### Serverless Function Code
#### كود الوظيفة بلا خادم
```typescript
export const main = async (
@@ -152,11 +152,11 @@ export const main = async (
};
```
### Step 3: Customize for Your Use Case
### الخطوة 3: خصّص وفق حالة الاستخدام الخاصة بك
#### To attach to a different object
#### لإرفاقه بكائن مختلف
Replace `companyId` with the appropriate field:
استبدل `companyId` بالحقل المناسب:
| كائن | اسم الحقل |
| ---------- | -------------------- |
@@ -165,14 +165,14 @@ Replace `companyId` with the appropriate field:
| الفرصة | `opportunityId` |
| كائن مخصّص | `yourCustomObjectId` |
Update both the function parameter and the `variables.data` object in the attachment mutation.
حدّث كل من معلمة الوظيفة وكائن `variables.data` في عملية الـ mutation الخاصة بالمرفق.
#### To use a dynamic PDF URL
#### لاستخدام رابط PDF ديناميكي
If using a PDF generation service, you can:
إذا كنت تستخدم خدمة إنشاء PDF، يمكنك:
1. First make an HTTP Request action to generate the PDF
2. Pass the returned PDF URL to the serverless function as a parameter
1. أولًا، أنشئ إجراء طلب HTTP لإنشاء ملف PDF
2. مرّر رابط ملف PDF المُعاد إلى الوظيفة بلا خادم كمعلمة
```typescript
export const main = async (
@@ -185,44 +185,44 @@ export const main = async (
### الخطوة 4: الاختبار والتفعيل
1. Save the workflow
2. Navigate to a Company record
3. Click the **⋮** menu and select your workflow
4. Check the **Attachments** section on the record to verify the PDF was attached
1. احفظ سير العمل
2. انتقل إلى سجل شركة
3. انقر على قائمة **⋮** واختر سير العمل الخاص بك
4. تحقّق من قسم **المرفقات** في السجل للتأكد من أنه تم إرفاق ملف PDF
5. فعّل سير العمل
## Combining with PDF Generation Services
## الدمج مع خدمات إنشاء ملفات PDF
For creating dynamic quotes or invoices:
لإنشاء عروض أسعار أو فواتير ديناميكية:
### Example: Generate Quote → Attach PDF
### مثال: إنشاء عرض سعر → إرفاق ملف PDF
| الخطوة | الإجراء | الغرض |
| ------ | ------------------------ | ---------------------------------------- |
| 1 | Manual Trigger (Company) | User initiates on a record |
| 2 | البحث عن سجل | Get Opportunity or line item details |
| 3 | طلب HTTP | Call PDF generation API with record data |
| 4 | Serverless Function | Download and attach the generated PDF |
| الخطوة | الإجراء | الغرض |
| ------ | ---------------------- | ---------------------------------------------------------- |
| 1 | المحفز اليدوي (الشركة) | يبدأ المستخدم التنفيذ على سجل |
| 2 | البحث عن سجل | الحصول على تفاصيل الفرصة أو بنود السطر |
| 3 | طلب HTTP | استدعِ واجهة برمجة تطبيقات إنشاء PDF باستخدام بيانات السجل |
| 4 | وظيفة بلا خادم | تنزيل وإرفاق ملف PDF المُنشأ |
### Popular PDF Generation Services
### خدمات شائعة لإنشاء ملفات PDF
* **Carbone** - Template-based document generation
* **PDFMonkey** - Dynamic PDF creation from templates
* **DocuSeal** - Document automation platform
* **Documint** - API-first document generation
* **Carbone** - إنشاء مستندات يعتمد على القوالب
* **PDFMonkey** - إنشاء PDF ديناميكي من القوالب
* **DocuSeal** - منصة أتمتة المستندات
* **Documint** - إنشاء مستندات يعتمد على واجهة برمجة التطبيقات أولًا
Each service provides an API that returns a PDF URL, which you can then pass to the serverless function.
توفر كل خدمة واجهة برمجة تطبيقات تُرجع رابط ملف PDF، ويمكنك بعدها تمريره إلى الوظيفة بلا خادم.
## استكشاف الأخطاء وإصلاحها
| المشكلة | الحل |
| ---------------------------- | ---------------------------------------------------------- |
| "Failed to download PDF" | Check the PDF URL is accessible and returns a valid PDF |
| "Upload failed" | Verify your API key is valid and has write permissions |
| "Attachment creation failed" | Ensure the object ID field name matches your target object |
| المشكلة | الحل |
| ------------------- | -------------------------------------------------------- |
| "فشل تنزيل ملف PDF" | تحقق من أن رابط ملف PDF قابل للوصول ويعيد ملف PDF صالحًا |
| "فشل الرفع" | تحقق من أن مفتاح API صالح ولديه أذونات كتابة |
| "فشل إنشاء المرفق" | تأكد من أن اسم حقل معرّف الكائن يطابق الكائن المستهدف |
## ذات صلة
* [مشغلات سير العمل](/l/ar/user-guide/workflows/capabilities/workflow-triggers)
* [Serverless Functions](/l/ar/user-guide/workflows/capabilities/workflow-actions#serverless-function)
* [Generate a Quote or Invoice from Twenty](/l/ar/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty)
* [وظائف بلا خادم](/l/ar/user-guide/workflows/capabilities/workflow-actions#serverless-function)
* [إنشاء عرض سعر أو فاتورة من Twenty](/l/ar/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty)
@@ -1,6 +1,6 @@
---
title: Display Number of Emails Received
description: Create a workflow to automatically count and display the number of emails received from each contact.
title: عرض عدد رسائل البريد الإلكتروني المستلمة
description: أنشئ سير عمل لحساب عدد رسائل البريد الإلكتروني المستلمة من كل جهة اتصال وعرضه تلقائيًا.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
@@ -9,66 +9,66 @@ import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## نظرة عامة
This workflow triggers every time a new email is received and updates a custom field on the Person record with the total count of emails from that sender.
يعمل سير العمل هذا في كل مرة يتم فيها استلام بريد إلكتروني جديد، ويحدّث حقلًا مخصصًا في سجل Person بالقيمة الإجمالية لعدد الرسائل من ذلك المرسِل.
## Prerequisites
## المتطلبات الأساسية
Before setting up this workflow, create a custom field on the **People** object:
قبل إعداد سير العمل هذا، أنشئ حقلًا مخصصًا على كائن **People**:
1. Go to **Settings → Data Model → People**
2. Add a new **Number** field
3. Name it something like "Number of emails received from this person"
1. اذهب إلى **الإعدادات → نموذج البيانات → People**
2. أضف حقل **Number** جديدًا
3. قم بتسميته بشيء مثل "عدد رسائل البريد الإلكتروني المستلمة من هذا الشخص"
## Step-by-Step Setup
## إعداد خطوة بخطوة
<VimeoEmbed videoId="1148700336" title="Video demonstration" />
<VimeoEmbed videoId="1148700336" title="عرض توضيحي بالفيديو" />
### Step 1: Configure the Trigger
### الخطوة 1: تهيئة المشغّل
1. Go to **Workflows** and create a new workflow
2. Select **Record is Created** as the trigger
3. Choose **Message Participants** (available under Advanced objects)
1. انتقل إلى **سير العمل** وأنشئ سير عمل جديدًا
2. اختر **Record is Created** كالمشغّل
3. اختر **Message Participants** (متوفر ضمن الكائنات المتقدمة)
<Note>
A Message Participant is a combination of a message ID and a person ID, creating one unique record per message. This is easier to track than Messages directly because we can access the `handle` field, which contains the sender's (or recipient's) email address.
يمثّل Message Participant مزيجًا بين معرّف الرسالة ومعرّف الشخص، ما ينشئ سجلًا فريدًا واحدًا لكل رسالة. يكون هذا أسهل في التتبع من Messages مباشرةً لأننا نستطيع الوصول إلى الحقل `handle` الذي يحتوي على عنوان البريد الإلكتروني للمرسل (أو المستلم).
</Note>
### Step 2: Filter on Role
### الخطوة 2: التصفية حسب Role
1. Add a **Filter** action
2. Set the condition: **Role** equals **FROM**
1. أضف إجراء **Filter**
2. عيّن الشرط: **Role** يساوي **FROM**
This ensures you only count messages sent by this person, not messages sent to them.
يضمن هذا أن تحسب الرسائل المُرسلة من هذا الشخص فقط، وليس الرسائل المُرسلة إليه.
### Step 3: Search All Message Participants with Same Handle
### الخطوة 3: البحث عن جميع Message Participants الذين لديهم نفس الـ Handle
1. Add a **Search Records** action
2. Select **Message Participants** as the object
3. Add filters: **Handle** equals the handle from the trigger (the sender's email address) and **Role** equals **FROM**
4. Increase the **Limit** from 1 to **200** (the maximum)
1. أضف إجراء **Search Records**
2. حدّد **Message Participants** كالكائن
3. أضف عوامل تصفية: **Handle** يساوي الـ handle من المشغّل (عنوان البريد الإلكتروني للمرسل) و**Role** يساوي **FROM**
4. قم بزيادة **Limit** من 1 إلى **200** (الحد الأقصى)
This finds all messages from this email address to get the total count.
هذا يعثر على جميع الرسائل من عنوان البريد الإلكتروني هذا للحصول على العدد الإجمالي.
<Note>
The Search Records action is limited to returning 200 records maximum. However, since you're only using the `totalCount` value (not the individual records), this step will return the total number of emails sent by this person.
إجراء Search Records محدود بإرجاع 200 سجل كحد أقصى. ومع ذلك، بما أنك تستخدم قيمة `totalCount` فقط (وليس السجلات الفردية)، فستُرجِع هذه الخطوة إجمالي عدد رسائل البريد الإلكتروني المُرسلة من هذا الشخص.
</Note>
### Step 4: Update the Person Record with a Create or Update Record action
### الخطوة 4: تحديث سجل Person باستخدام إجراء Create or Update Record
1. Add a **Create or Update Record** action
1. أضف إجراء **Create or Update Record**
<Warning>
Use **Upsert Record** instead of **Update Record** here. This lets you identify the person by their email address (the `handle` field) rather than requiring a record ID from a previous step.
استخدم **Upsert Record** بدلًا من **Update Record** هنا. يتيح لك هذا تحديد الشخص عبر عنوان بريده الإلكتروني (حقل `handle`) بدلًا من اشتراط معرّف سجل من خطوة سابقة.
</Warning>
2. Select **People** as the object
3. Find the person by matching their email to the `handle` from the Message Participant
4. Set your custom "Number of emails received" field to `{{searchRecords.totalCount}}`
2. حدّد **People** كالكائن
3. اعثر على الشخص بمطابقة بريده الإلكتروني مع قيمة `handle` من Message Participant
4. عيّن الحقل المخصص "عدد رسائل البريد الإلكتروني المستلمة" إلى `{{searchRecords.totalCount}}`
The `totalCount` value from the Search Records action represents the total number of emails received from this person.
تمثّل قيمة `totalCount` من إجراء Search Records إجمالي عدد رسائل البريد الإلكتروني المستلمة من هذا الشخص.
## Related
## ذات صلة
* [Workflow Actions](/l/ar/user-guide/workflows/capabilities/workflow-actions)
* [Create Custom Fields](/l/ar/user-guide/data-model/how-tos/customize-your-data-model)
* [Search Records Action](/l/ar/user-guide/workflows/capabilities/workflow-actions#search-records)
* [إجراءات سير العمل](/l/ar/user-guide/workflows/capabilities/workflow-actions)
* [إنشاء حقول مخصصة](/l/ar/user-guide/data-model/how-tos/customize-your-data-model)
* [إجراء Search Records](/l/ar/user-guide/workflows/capabilities/workflow-actions#search-records)
@@ -1,130 +1,130 @@
---
title: Display Related Record Data
description: Show data from related records (e.g., Company info on Opportunities) using workflows.
title: عرض بيانات السجل المرتبط
description: اعرض بيانات من سجلات مرتبطة (مثل معلومات الشركة على الفرص) باستخدام سير العمل.
---
Display data from related records directly on your records — for example, show the employee count from a Company on its Opportunities. This workflow workaround is useful until nested fields are natively available.
اعرض بيانات من سجلات مرتبطة مباشرةً على سجلاتك — على سبيل المثال، اعرض عدد الموظفين من شركة على فرصها. هذا الحل عبر سير العمل مفيد حتى تصبح الحقول المتداخلة مدعومة أصلاً.
## الاستخدامات الشائعة
| المصدر | Destination | Fields to Copy |
| ------ | ----------- | ------------------------------- |
| الشركة | الفرصة | Industry, Company Size, ARR |
| شخص | الفرصة | Email, Phone, Title |
| الفرصة | الشركة | Last Deal Amount, Last Won Date |
| المصدر | الوجهة | الحقول المطلوب نسخها |
| ------ | ------ | ------------------------------------------------- |
| الشركة | الفرصة | الصناعة، حجم الشركة، الإيراد السنوي المتكرر (ARR) |
| شخص | الفرصة | البريد الإلكتروني، الهاتف، المسمّى الوظيفي |
| الفرصة | الشركة | قيمة آخر صفقة، تاريخ آخر صفقة رابحة |
## Basic Field Copy
## نسخ أساسي للحقل
### Example: Copy Contact Email to Opportunity
### مثال: نسخ البريد الإلكتروني لجهة الاتصال إلى الفرصة
**Goal**: When setting a Point of Contact on an opportunity, copy their email to the opportunity for easy access.
**الهدف**: عند تعيين نقطة اتصال على فرصة، انسخ البريد الإلكتروني لجهة الاتصال إلى الفرصة لسهولة الوصول.
### Prerequisite
### المتطلبات الأساسية
Create the destination fields in **Settings → Data Model → Opportunities** before building the workflow:
أنشئ حقول الوجهة في **الإعدادات → نموذج البيانات → الفرص** قبل إنشاء سير العمل:
* Contact Email (type: Email)
* Contact Phone (type: Phone)
* البريد الإلكتروني لجهة الاتصال (النوع: Email)
* هاتف جهة الاتصال (النوع: Phone)
### إعداد
1. **Trigger**: Record is Updated (Opportunities, Point of Contact field)
1. **المحفّز**: يتم تحديث السجل (الفرص، حقل نقطة الاتصال)
2. **Filter**: Check that Point of Contact is not empty
2. **الفلتر**: تحقّق من أن نقطة الاتصال غير فارغة
3. **Search Records**: Find the linked person
* Object: People
* Filter: ID equals `{{trigger.object.pointOfContact.id}}`
3. **البحث في السجلات**: اعثر على الشخص المرتبط
* الكائن: الأشخاص
* الفلتر: المعرّف يساوي `{{trigger.object.pointOfContact.id}}`
4. **Update Record**:
* Object: Opportunities
* Record: `{{trigger.object.id}}`
* Contact Email: `{{searchRecords[0].email}}`
* Contact Phone: `{{searchRecords[0].phone}}`
4. **تحديث السجل**:
* الكائن: الفرص
* السجل: `{{trigger.object.id}}`
* البريد الإلكتروني لجهة الاتصال: `{{searchRecords[0].email}}`
* هاتف جهة الاتصال: `{{searchRecords[0].phone}}`
## Copy Multiple Fields
## نسخ عدة حقول
### Example: Sync Company Info to All Related Opportunities
### مثال: مزامنة معلومات الشركة مع جميع الفرص المرتبطة
**Goal**: When company details change, update all related opportunities.
**الهدف**: عند تغيّر تفاصيل الشركة، حدّث جميع الفرص المرتبطة.
### إعداد
1. **Trigger**: Record is Updated (Companies)
* Fields: Industry, Company Size, Annual Revenue
1. **المحفّز**: يتم تحديث السجل (الشركات)
* الحقول: الصناعة، حجم الشركة، الإيراد السنوي
2. **Search Records**: Find all opportunities for this company
* Object: Opportunities
* Filter: Company ID equals `{{trigger.object.id}}`
2. **البحث في السجلات**: اعثر على جميع الفرص الخاصة بهذه الشركة
* الكائن: الفرص
* الفلتر: معرّف الشركة يساوي `{{trigger.object.id}}`
3. **Iterator**: Loop through each opportunity
3. **Iterator**: التكرار عبر كل فرصة
4. **Update Record** (inside iterator):
* Object: Opportunities
* Record: `{{iterator.currentItem.id}}`
* Company Industry: `{{trigger.object.industry}}`
* Company Size: `{{trigger.object.companySize}}`
* Company ARR: `{{trigger.object.annualRevenue}}`
4. **تحديث السجل** (داخل الـ Iterator):
* الكائن: الفرص
* السجل: `{{iterator.currentItem.id}}`
* صناعة الشركة: `{{trigger.object.industry}}`
* حجم الشركة: `{{trigger.object.companySize}}`
* الإيراد السنوي المتكرر للشركة: `{{trigger.object.annualRevenue}}`
## Copy on Record Creation
## النسخ عند إنشاء السجل
### Example: Pre-fill Opportunity with Company Data
### مثال: تعبئة الفرصة مسبقًا ببيانات الشركة
**Goal**: When creating an opportunity linked to a company, automatically copy key company info.
**الهدف**: عند إنشاء فرصة مرتبطة بشركة، انسخ تلقائيًا معلومات الشركة الأساسية.
### Prerequisite
### المتطلبات الأساسية
Create the destination fields in **Settings → Data Model → Opportunities**:
أنشئ حقول الوجهة في **الإعدادات → نموذج البيانات → الفرص**:
* Company Industry (type: Text)
* Company Size (type: Number)
* صناعة الشركة (النوع: Text)
* حجم الشركة (النوع: Number)
### إعداد
1. **Trigger**: Record is Created (Opportunities)
* Filter: Company is not empty
1. **المحفّز**: يتم إنشاء السجل (الفرص)
* الفلتر: الشركة ليست فارغة
2. **Search Records**: Get the linked company's details
* Object: Companies
* Filter: ID equals `{{trigger.object.company.id}}`
2. **البحث في السجلات**: احصل على تفاصيل الشركة المرتبطة
* الكائن: الشركات
* الفلتر: المعرّف يساوي `{{trigger.object.company.id}}`
3. **Update Record**:
* Object: Opportunities
* Record: `{{trigger.object.id}}`
* Company Industry: `{{searchRecords[0].industry}}`
* Company Size: `{{searchRecords[0].employees}}`
3. **تحديث السجل**:
* الكائن: الفرص
* السجل: `{{trigger.object.id}}`
* صناعة الشركة: `{{searchRecords[0].industry}}`
* حجم الشركة: `{{searchRecords[0].employees}}`
<Note>
**Tasks and Notes limitation**: Relations on Tasks and Notes are hardcoded as many-to-many and are not yet available in workflow triggers or actions. To access these relations, use the [API](/l/ar/developers/extend/capabilities/apis) instead.
**قيود المهام والملاحظات**: العلاقات في المهام والملاحظات مُحدّدة في الشفرة كعلاقات متعدّدة-لمتعدّدة وليست متاحة بعد في محفّزات أو إجراءات سير العمل. للوصول إلى هذه العلاقات، استخدم بدلًا من ذلك [API](/l/ar/developers/extend/capabilities/apis).
</Note>
## Bidirectional Sync
## مزامنة ثنائية الاتجاه
### Example: Keep Primary Contact in Sync
### مثال: الحفاظ على تزامن جهة الاتصال الأساسية
**Goal**: When a company's primary contact changes, update the contact. When a person becomes primary, update the company.
**الهدف**: عند تغيّر جهة الاتصال الأساسية للشركة، حدّث جهة الاتصال. وعندما يصبح شخص ما جهة الاتصال الأساسية، حدّث الشركة.
### Workflow 1: Company → Person
### سير العمل 1: الشركة → الشخص
1. **Trigger**: Record is Updated (Companies, Primary Contact field)
2. **Update Record**: Set person's "Is Primary Contact" to true
3. **Search Records**: Find previous primary contact
4. **Update Record**: Set previous contact's "Is Primary Contact" to false
1. **المحفّز**: يتم تحديث السجل (الشركات، حقل جهة الاتصال الأساسية)
2. **تحديث السجل**: عيّن قيمة "Is Primary Contact" للشخص إلى true
3. **البحث في السجلات**: اعثر على جهة الاتصال الأساسية السابقة
4. **تحديث السجل**: عيّن قيمة "Is Primary Contact" لجهة الاتصال السابقة إلى false
### Workflow 2: Person → Company
### سير العمل 2: الشخص → الشركة
1. **Trigger**: Record is Updated (People, Is Primary Contact = true)
2. **Update Record**: Set company's Primary Contact to this person
1. **المحفّز**: يتم تحديث السجل (الأشخاص، Is Primary Contact = true)
2. **تحديث السجل**: عيّن جهة الاتصال الأساسية للشركة إلى هذا الشخص
<Note>
Be careful with bidirectional syncs to avoid infinite loops. Use filters to check if the value actually changed before updating.
كن حذرًا مع المزامنات ثنائية الاتجاه لتجنّب الحلقات اللانهائية. استخدم عوامل تصفية للتحقّق مما إذا كانت القيمة قد تغيّرت فعلاً قبل التحديث.
</Note>
## Using Code for Complex Mapping
## استخدام الشيفرة للتعيين المعقّد
### Example: Transform Data During Copy
### مثال: تحويل البيانات أثناء النسخ
**Goal**: Copy and format phone number from person to opportunity.
**الهدف**: نسخ رقم الهاتف من الشخص إلى الفرصة وتنسيقه.
```javascript
export const main = async (params) => {
@@ -146,25 +146,25 @@ export const main = async (params) => {
## أفضل الممارسات
### Avoid Loops
### تجنّب الحلقات
* Don't create workflows that trigger each other endlessly
* Use specific field conditions
* Add checks to see if value actually changed
* لا تنشئ سير عمل تُحفّز بعضها بعضًا بلا نهاية
* استخدم شروطًا خاصة بالحقول
* أضف تحقّقات لمعرفة ما إذا كانت القيمة قد تغيّرت فعلاً
### Handle Missing Data
### التعامل مع البيانات المفقودة
* Always check if source record exists before copying
* Provide default values for optional fields
* Use filters to skip when source field is empty
* تحقّق دائمًا من وجود سجل المصدر قبل النسخ
* وفّر قيمًا افتراضية للحقول الاختيارية
* استخدم عوامل تصفية للتخطّي عندما يكون حقل المصدر فارغًا
### Performance
### الأداء
* Batch updates when copying to many records
* Use scheduled workflows for bulk sync operations
* Consider using Iterator for multiple record updates
* نفّذ تحديثات دفعية عند النسخ إلى العديد من السجلات
* استخدم سير عمل مجدولة لعمليات المزامنة بالجملة
* فكّر في استخدام Iterator لتحديثات متعددة للسجلات
## Related
## ذات صلة
* [Workflow Actions](/l/ar/user-guide/workflows/capabilities/workflow-actions)
* [Workflow Triggers](/l/ar/user-guide/workflows/capabilities/workflow-triggers)
* [إجراءات سير العمل](/l/ar/user-guide/workflows/capabilities/workflow-actions)
* [محفّزات سير العمل](/l/ar/user-guide/workflows/capabilities/workflow-triggers)
@@ -1,37 +1,37 @@
---
title: Formula Fields
description: Create formula fields using workflows until native support is available.
title: حقول الصيغ
description: أنشئ حقول الصيغ باستخدام سير العمل إلى حين توفّر الدعم الأصلي.
---
Twenty doesn't yet support native formula fields yet (coming in 2026), but you can achieve the same result using workflows. This workaround lets you automatically calculate and populate field values—from simple concatenations to complex business logic.
لا يدعم Twenty حقول الصيغ الأصلية بعد (قادمة في 2026)، لكن يمكنك تحقيق النتيجة نفسها باستخدام سير العمل. يتيح لك هذا الحل البديل حساب قيم الحقول وملؤها تلقائيًا — من عمليات الربط البسيطة إلى منطق الأعمال المعقّد.
## الاستخدامات الشائعة
| Use Case | Formula Example |
| ------------------- | --------------------------------- |
| **Full name** | First Name + " " + Last Name |
| **Expected amount** | Amount × Probability |
| **Days until due** | Due Date - Today |
| **Days in stage** | Today - Stage Entry Date |
| **Lead score** | Points based on multiple criteria |
| حالة الاستخدام | مثال على الصيغة |
| ------------------------ | ------------------------------- |
| **الاسم الكامل** | الاسم الأول + " " + اسم العائلة |
| **المبلغ المتوقع** | المبلغ × الاحتمال |
| **الأيام حتى الاستحقاق** | تاريخ الاستحقاق - اليوم |
| **الأيام في المرحلة** | اليوم - تاريخ دخول المرحلة |
| **درجة العميل المحتمل** | نقاط استنادًا إلى معايير متعددة |
<Tip>
For a complete example of tracking time in pipeline stages, see [Track How Long Opportunities Stay in Each Stage](/l/ar/user-guide/views-pipelines/how-tos/track-time-in-stage).
للاطلاع على مثال كامل لتتبّع الوقت في مراحل خط الأنابيب، راجع [تتبّع مدة بقاء الفرص في كل مرحلة](/l/ar/user-guide/views-pipelines/how-tos/track-time-in-stage).
</Tip>
## Basic Formula: Concatenation
## صيغة أساسية: الربط
### Example: Auto-Fill Full Name
### مثال: تعبئة الاسم الكامل تلقائيًا
**Goal**: Automatically combine first and last name into a full name field.
**الهدف**: دمج الاسم الأول واسم العائلة تلقائيًا في حقل الاسم الكامل.
### إعداد
1. **Trigger**: Record is Updated or Created (People)
1. **المشغّل**: يتم تحديث السجل أو إنشاؤه (الأشخاص)
2. **Filter**: Check that first name or last name changed
2. **التصفية**: التحقق من تغيّر الاسم الأول أو اسم العائلة
3. **Code action**:
3. **إجراء الكود**:
```javascript
export const main = async (params) => {
@@ -45,21 +45,21 @@ export const main = async (params) => {
};
```
4. **Update Record**: Set Full Name to `{{code.fullName}}`
4. **تحديث السجل**: عيّن الاسم الكامل إلى `{{code.fullName}}`
## Numeric Formula: Expected Amount
## صيغة رقمية: المبلغ المتوقع
### Example: Calculate Expected Revenue
### مثال: حساب الإيراد المتوقع
**Goal**: Multiply opportunity amount by probability to get expected amount.
**الهدف**: ضرب مبلغ الفرصة في الاحتمال للحصول على المبلغ المتوقع.
See [How to Show Expected Amount in Pipeline](/l/ar/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline) for the complete workflow.
اطلع على [كيفية إظهار المبلغ المتوقع في خط الأنابيب](/l/ar/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline) للاطلاع على سير العمل الكامل.
### Quick Setup
### الإعداد السريع
1. **Trigger**: Record is Updated (Opportunities, Amount OR Probability field)
1. **المشغّل**: يتم تحديث السجل (الفرص، حقل المبلغ أو الاحتمال)
2. **Code action**:
2. **إجراء الكود**:
```javascript
export const main = async (params) => {
@@ -71,19 +71,19 @@ export const main = async (params) => {
};
```
3. **Update Record**: Set Expected Amount to `{{code.expectedAmount}}`
3. **تحديث السجل**: عيّن المبلغ المتوقع إلى `{{code.expectedAmount}}`
## Date Formula: Days Calculation
## صيغة التاريخ: حساب الأيام
### Example: Days Until Task Due
### مثال: الأيام المتبقية حتى استحقاق المهمة
**Goal**: Calculate how many days remain until a task's due date.
**الهدف**: حساب عدد الأيام المتبقية حتى تاريخ استحقاق المهمة.
### إعداد
1. **Trigger**: Record is Updated or Created (Tasks, Due Date field)
1. **المشغّل**: يتم تحديث السجل أو إنشاؤه (المهام، حقل تاريخ الاستحقاق)
2. **Code action**:
2. **إجراء الكود**:
```javascript
export const main = async (params) => {
@@ -102,23 +102,23 @@ export const main = async (params) => {
};
```
3. **Update Record**: Set Days Until Due to `{{code.daysUntilDue}}`
3. **تحديث السجل**: عيّن الأيام حتى الاستحقاق إلى `{{code.daysUntilDue}}`
<Note>
Negative values indicate overdue tasks. You can use this field to filter or sort tasks by urgency.
تشير القيم السالبة إلى مهام متأخرة عن موعدها. يمكنك استخدام هذا الحقل لتصفية المهام أو فرزها حسب الإلحاح.
</Note>
## Conditional Formula: Lead Score
## صيغة شرطية: درجة العميل المحتمل
### Example: Calculate Lead Score Based on Criteria
### مثال: حساب درجة العميل المحتمل بناءً على معايير
**Goal**: Score leads based on company size, industry, and engagement.
**الهدف**: منح نقاط للعملاء المحتملين استنادًا إلى حجم الشركة والصناعة والتفاعل.
### إعداد
1. **Trigger**: Record is Updated (People or Companies)
1. **المشغّل**: يتم تحديث السجل (الأشخاص أو الشركات)
2. **Code action**:
2. **إجراء الكود**:
```javascript
export const main = async (params) => {
@@ -147,19 +147,19 @@ export const main = async (params) => {
};
```
3. **Update Record**: Set Lead Score to `{{code.leadScore}}`
3. **تحديث السجل**: عيّن درجة العميل المحتمل إلى `{{code.leadScore}}`
## Text Formula: Domain Extraction
## صيغة نصية: استخراج النطاق
### Example: Extract Domain from Email
### مثال: استخراج النطاق من البريد الإلكتروني
**Goal**: Automatically extract and store the email domain.
**الهدف**: استخراج نطاق البريد الإلكتروني وتخزينه تلقائيًا.
### إعداد
1. **Trigger**: Record is Updated (People, Email field)
1. **المشغّل**: يتم تحديث السجل (الأشخاص، حقل البريد الإلكتروني)
2. **Code action**:
2. **إجراء الكود**:
```javascript
export const main = async (params) => {
@@ -173,30 +173,30 @@ export const main = async (params) => {
};
```
3. **Update Record**: Set Domain field to `{{code.domain}}`
3. **تحديث السجل**: عيّن حقل النطاق إلى `{{code.domain}}`
## أفضل الممارسات
### Performance
### الأداء
* Only trigger on relevant field changes
* Use filters to skip records that don't need calculation
* Avoid complex calculations in high-volume workflows
* فعّل المشغّل فقط عند تغيّر الحقول ذات الصلة
* استخدم عوامل التصفية لتجاوز السجلات التي لا تحتاج إلى حساب
* تجنّب الحسابات المعقّدة في عمليات سير عمل ذات حجم كبير
### Error Handling
### التعامل مع الأخطاء
* Check for null/undefined values before calculations
* Use default values when data is missing
* Return clear error messages when calculations fail
* تحقق من القيم null/undefined قبل إجراء الحسابات
* استخدم قيمًا افتراضية عند فقدان البيانات
* أعد رسائل خطأ واضحة عند فشل الحسابات
### "الاختبار"
* Test with edge cases (empty fields, zero values)
* Verify calculations manually before activating
* Monitor workflow runs for unexpected results
* اختبر بحالات الحافة (حقول فارغة، قيم صفرية)
* تحقّق من الحسابات يدويًا قبل التفعيل
* راقب تشغيلات سير العمل لرصد النتائج غير المتوقعة
## Related
## ذات صلة
* [How to Show Expected Amount in Pipeline](/l/ar/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline)
* [How to Track Time in Stage](/l/ar/user-guide/views-pipelines/how-tos/track-time-in-stage)
* [Workflow Actions](/l/ar/user-guide/workflows/capabilities/workflow-actions)
* [كيفية إظهار المبلغ المتوقع في خط الأنابيب](/l/ar/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline)
* [كيفية تتبّع الوقت في المرحلة](/l/ar/user-guide/views-pipelines/how-tos/track-time-in-stage)
* [إجراءات سير العمل](/l/ar/user-guide/workflows/capabilities/workflow-actions)
@@ -1,92 +1,92 @@
---
title: Notify Teammates of a Note to Review
description: Send automatic email notifications when assigning a colleague to review a note.
title: إشعار الزملاء بملاحظة للمراجعة
description: أرسل إشعارات بريد إلكتروني تلقائية عند إسناد زميل لمراجعة ملاحظة.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
<Note>
**Tagging teammates directly in notes is not yet supported.** This feature is planned for the second half of 2026. In the meantime, this workflow provides a practical workaround.
**الإشارة إلى الزملاء مباشرةً داخل الملاحظات غير مدعومة بعد.** من المخطط طرح هذه الميزة في النصف الثاني من عام 2026. في هذه الأثناء، يوفّر سير العمل هذا حلاً عمليًا بديلاً.
</Note>
## The Challenge
## التحدّي
You want to tag a colleague in a note so they receive a notification to review it. Today, Twenty doesn't support @mentions in notes or tasks.
تريد الإشارة إلى زميل في ملاحظة ليصله إشعار لمراجعتها. حاليًا، Twenty لا يدعم @mentions في الملاحظات أو المهام.
## The Workaround
## الحل البديل
Instead of tagging in the note text, you can:
بدلًا من الإشارة في نص الملاحظة، يمكنك:
1. Create a **Reviewer** relation field on the Notes object
2. Assign the reviewer when creating or editing the note
3. A workflow automatically sends an email to the reviewer with a link to the note
1. أنشئ حقل علاقة **Reviewer** على كائن Notes
2. عيّن المراجع عند إنشاء الملاحظة أو تحريرها
3. سير عمل يرسل تلقائيًا بريدًا إلكترونيًا إلى المراجع يتضمّن رابطًا إلى الملاحظة
<Warning>
**Limitation**: This approach allows assigning one reviewer per field. If you need to notify multiple people, create additional relation fields (e.g., Reviewer 1, Reviewer 2). This won't scale well if you need to tag many collaborators at once.
**قيد**: يتيح هذا الأسلوب تعيين مراجع واحد لكل حقل. إذا كنت بحاجة إلى إشعار عدة أشخاص، فأنشئ حقول علاقة إضافية (مثلًا: Reviewer 1، Reviewer 2). لن يكون ذلك قابلًا للتوسّع بشكلٍ جيد إذا احتجت إلى الإشارة إلى العديد من المتعاونين دفعةً واحدة.
</Warning>
## إعداد خطوة بخطوة
### Step 1: Create the Reviewer Field
### الخطوة 1: إنشاء حقل المراجع
<img src="/images/user-guide/workflows/reviewer-field-for-note.png" style={{width:'100%'}} />
1. Go to **Settings → Data Model → Notes**
2. Click **Add Field**
3. Configure:
1. انتقل إلى **الإعدادات → نموذج البيانات → Notes**
2. انقر **إضافة حقل**
3. التكوين:
| الإعداد | القيمة |
| ------------------ | --------------------------------- |
| **Name** | Reviewer |
| **النوع** | علاقة |
| **Related Object** | عضو في مساحة العمل |
| **Relation Type** | Many Notes → One Workspace Member |
| الإعداد | القيمة |
| ------------------ | --------------------------------------------- |
| **Name** | Reviewer |
| **النوع** | علاقة |
| **الكائن المرتبط** | عضو في مساحة العمل |
| **نوع العلاقة** | العديد من الملاحظات → عضو واحد في مساحة العمل |
4. Save the field
4. احفظ الحقل
### الخطوة 2: إنشاء سير العمل
<VimeoEmbed videoId="1151897168" title="عرض توضيحي بالفيديو" />
#### Create the Workflow Trigger
#### إنشاء مشغّل سير العمل
1. Go to the main view and create a new workflow
2. Select **Record Updated** as the trigger
3. Choose **Note** as the object and specify the Reviewer field.
4. This will trigger whenever the reviewer of a note is updated.
1. انتقل إلى العرض الرئيسي وأنشئ سير عمل جديدًا
2. اختر **Record Updated** كمشغِّل
3. اختر **Note** كالكائن وحدِّد حقل Reviewer.
4. سيؤدي ذلك إلى التشغيل كلما تم تحديث مُراجع الملاحظة.
#### Add a Filter to Check Reviewer Was Just Assigned
#### أضِف عامل تصفية للتحقق من أنه تم تعيين المراجع للتو
Add a **Filter** action to ensure the workflow only continues when a reviewer is assigned:
أضِف إجراء **Filter** للتأكد من أن سير العمل يستمر فقط عند تعيين مراجع:
| Condition | القيمة |
| الشرط | القيمة |
| ------------ | -------- |
| **Reviewer** | غير فارغ |
#### Search for the Workspace Member
#### ابحث عن عضو مساحة العمل
1. Add a **Search Records** action
2. Select **Workspace Member** (under Advanced Objects)
3. Add a filter:
1. أضف إجراء **Search Records**
2. حدِّد **Workspace Member** (ضمن الكائنات المتقدمة)
3. أضف عامل تصفية:
| Condition | القيمة |
| --------- | ---------------------------- |
| **ID** | equals `{{note.reviewerId}}` |
| الشرط | القيمة |
| ------ | --------------------------- |
| **ID** | يساوي `{{note.reviewerId}}` |
This retrieves the full workspace member record, including their email address and name.
هذا يجلب سجل عضو مساحة العمل الكامل، بما في ذلك عنوان بريده الإلكتروني واسمه.
#### Send the Notification Email
#### إرسال بريد الإشعار الإلكتروني
1. Add a **Send Email** action
2. Configure:
1. أضف إجراء **Send Email**
2. التكوين:
| الحقل | القيمة |
| ----------- | --------------------------------------------------- |
| **إلى** | Search Record → First Workspace Member → User Email |
| **الموضوع** | A note needs your review |
| **المحتوى** | See example below |
| **الموضوع** | هناك ملاحظة تحتاج إلى مراجعتك |
| **المحتوى** | انظر المثال أدناه |
**Email body example:**
**مثال على محتوى البريد الإلكتروني:**
```text
Hi {{searchRecord.firstWorkspaceMember.name.firstName}},
@@ -101,27 +101,27 @@ Twenty
```
<Note>
Replace `yourSubDomain` with your actual Twenty workspace subdomain.
استبدل `yourSubDomain` بنطاقك الفرعي الفعلي لمساحة عمل Twenty.
</Note>
#### Test and Activate
#### الاختبار والتفعيل
1. Click **Test** to run the workflow manually
2. Create or edit a note and assign a reviewer
3. Check the reviewer's inbox for the notification email
4. Activate the workflow
1. انقر **Test** لتشغيل سير العمل يدويًا
2. أنشئ ملاحظة (أو حرّر ملاحظة موجودة) وعيّن مراجعًا
3. تحقّق من بريد المراجع الوارد بحثًا عن رسالة الإشعار
4. فعّل سير العمل
## استخدام
Once set up, your team can use this workflow by:
بعد الإعداد، يمكن لفريقك استخدام سير العمل هذا عبر:
1. Creating a new note (or editing an existing one)
2. Selecting a colleague in the **Reviewer** field
3. The colleague automatically receives an email with a direct link to the note
1. إنشاء ملاحظة جديدة (أو تحرير ملاحظة موجودة)
2. اختيار زميل في حقل **Reviewer**
3. سيتلقى الزميل تلقائيًا بريدًا إلكترونيًا يحتوي على رابط مباشر إلى الملاحظة
## ذات صلة
* [مشغلات سير العمل](/l/ar/user-guide/workflows/capabilities/workflow-triggers)
* [Send Emails from Workflows](/l/ar/user-guide/workflows/capabilities/send-emails-from-workflows)
* [Create Custom Fields](/l/ar/user-guide/data-model/how-tos/create-custom-fields)
* [Create Relation Fields](/l/ar/user-guide/data-model/how-tos/create-relation-fields)
* [إرسال رسائل البريد الإلكتروني من سير العمل](/l/ar/user-guide/workflows/capabilities/send-emails-from-workflows)
* [إنشاء حقول مخصصة](/l/ar/user-guide/data-model/how-tos/create-custom-fields)
* [إنشاء حقول العلاقات](/l/ar/user-guide/data-model/how-tos/create-relation-fields)
@@ -4,14 +4,14 @@ title: Osvědčené postupy
Tento dokument popisuje osvědčené postupy, které byste měli dodržovat při práci na backendu.
## Follow a modular approach
## Dodržujte modulární přístup
Backend sleduje modulární přístup, což je základní princip při práci s NestJS. Ujistěte se, že rozdělujete svůj kód na znovupoužitelné moduly, abyste udrželi čistý a organizovaný kód.
Každý modul by měl zahrnovat určitou funkci nebo funkcionalitu a mít jasně definovaný rozsah. This modular approach enables clear separation of concerns and removes unnecessary complexities.
Každý modul by měl zahrnovat určitou funkci nebo funkcionalitu a mít jasně definovaný rozsah. Tento modulární přístup umožňuje jasné oddělení odpovědností a odstraňuje zbytečné složitosti.
## Expose services to use in modules
## Zpřístupněte služby pro použití v modulech.
Always create services that have a clear and single responsibility, which enhances code readability and maintainability. Pojmenovávejte služby výstižně a konzistentně.
Vždy vytvářejte služby s jasně vymezenou jedinou odpovědností, což zvyšuje čitelnost a udržovatelnost kódu. Pojmenovávejte služby výstižně a konzistentně.
Měli byste také zpřístupnit služby, které chcete používat v jiných modulech. Zpřístupnění služeb ostatním modulům je možné díky výkonnému systému injektování závislostí v NestJS a podporuje volné vazby mezi komponentami.
@@ -21,7 +21,7 @@ server
└───utils
```
## Ability
## Oprávnění
Definuje oprávnění a zahrnuje zpracovníky pro každou entitu.
@@ -29,7 +29,7 @@ Definuje oprávnění a zahrnuje zpracovníky pro každou entitu.
Definuje vlastní dekorátory v NestJS pro přídavnou funkčnost.
See [custom decorators](https://docs.nestjs.com/custom-decorators) for more details.
Více podrobností naleznete ve [vlastních dekorátorech](https://docs.nestjs.com/custom-decorators).
## Filtry
@@ -37,9 +37,9 @@ Zahrnuje filtry výjimek k zpracování výjimek, které mohou nastat v koncový
## Guards
See [guards](https://docs.nestjs.com/guards) for more details.
Více podrobností naleznete ve [strážích](https://docs.nestjs.com/guards).
## Health
## Zdraví
Zahrnuje veřejně dostupné REST API (healthz), které vrací JSON k potvrzení, zda databáze funguje, jak se očekává.
@@ -49,7 +49,7 @@ Definuje vlastní objekty a poskytuje GraphQL API (graphql/metadata).
## Pracovní prostor
Generates and serves custom GraphQL schema based on the metadata.
Generuje a poskytuje vlastní schéma GraphQL na základě metadat.
### Struktura adresáře pracovního prostoru
@@ -87,7 +87,7 @@ Kořen adresáře pracovního prostoru zahrnuje `workspace.factory.ts`, soubor o
Tato strategie neslouží pouze k organizaci, ale pomáhá i v optimalizaci, jako je ukládání vytvořených typových definic do mezipaměti pro zvýšení výkonu a škálovatelnosti.
### Workspace Schema builder
### Builder schématu pracovního prostoru
Generuje schéma GraphQL a zahrnuje:
@@ -114,7 +114,7 @@ Obsahuje službu, která spojuje FieldMetadataType s odpovídajícími GraphQL s
Zahrnuje třídu `TypeDefinitionsStorage`, která obsahuje opakovaně použitelné definice typů, zabraňující duplikaci typů GraphQL.
### Workspace Resolver Builder
### Builder resolveru pracovního prostoru
Vytváří funkce pro řešení dotazů a mutací v GraphQL schématu.
@@ -5,7 +5,7 @@ title: Příkazy backendu
## Užitečné příkazy
Tyto příkazy by měly být vykonávány z adresáře packages/twenty-server.
From any other folder you can run `npx nx {command} twenty-server` (or `npx nx run twenty-server:{command}`).
Z jakéhokoli jiného adresáře můžete spustit `npx nx {command} twenty-server` (nebo `npx nx run twenty-server:{command}`).
### První nastavení
@@ -36,7 +36,7 @@ Poznámka: můžete spustit `npx nx run twenty-server:test:integration:with-db-r
### Obnovení databáze
If you want to reset and seed the database, you can run the following command:
Pokud chcete resetovat a naplnit databázi daty, můžete spustit následující příkaz:
```bash
npx nx run twenty-server:database:reset
@@ -59,9 +59,9 @@ npx nx run twenty-server:command workspace:sync-metadata -f
```
<Warning>
This will drop the database and re-run the migrations and seed.
Tímto se databáze smaže a znovu se spustí migrace a seedování.
Make sure to back up any data you want to keep before running this command.
Před spuštěním tohoto příkazu si nezapomeňte zálohovat všechna data, která chcete zachovat.
</Warning>
## Technologický stack
@@ -1,6 +1,6 @@
---
title: Bugs, Requests & Pull Requests
info: Report issues, request features, and contribute code
title: Hlášení chyb, požadavky a pull requesty
info: Nahlašujte problémy, žádejte o nové funkce a přispívejte dem
---
## Nahlášení chyb
@@ -13,66 +13,66 @@ O pomoc můžete také požádat na [Discordu](https://discord.gg/cx5n4Jzs57).
Pokud si nejste jisti, zda se jedná o chybu, a máte pocit, že je to spíše žádost o funkci, pak byste pravděpodobně měli [otevřít diskuzi](https://github.com/twentyhq/twenty/discussions/new).
## Submit a Pull Request
## Odešlete pull request
Contributing code to Twenty starts with a pull request (PR).
Přispívání kódem do Twenty začíná pull requestem (PR).
### Než začnete
1. Check [existing issues](https://github.com/twentyhq/twenty/issues) for related work
2. For new features, open an issue first to discuss
3. Review our [Code of Conduct](https://github.com/twentyhq/twenty/blob/main/CODE_OF_CONDUCT.md)
1. Zkontrolujte [existující issues](https://github.com/twentyhq/twenty/issues) ohledně související práce
2. Pro nové funkce nejprve otevřete issue k diskusi
3. Prostudujte si náš [Kodex chování](https://github.com/twentyhq/twenty/blob/main/CODE_OF_CONDUCT.md)
### Fork and Clone
### Fork a klonování
1. Fork the repository on GitHub
2. Clone your fork:
1. Vytvořte fork repozitáře na GitHubu
2. Naklonujte svůj fork:
```bash
git clone https://github.com/YOUR_USERNAME/twenty.git
cd twenty
```
3. Add upstream remote:
3. Přidejte vzdálený upstream:
```bash
git remote add upstream https://github.com/twentyhq/twenty.git
```
### Create a Branch
### Vytvoření větve
```bash
git checkout -b feature/your-feature-name
```
Use descriptive branch names:
Používejte výstižné názvy větví:
* `feature/add-export-button`
* `fix/login-redirect-issue`
* `docs/update-api-guide`
### Make Your Changes
### Proveďte změny
1. Write clean, well-documented code
2. Follow existing code style
3. Add tests for new functionality
4. Update documentation if needed
1. Pište čistý, dobře zdokumentovaný kód
2. Dodržujte stávající styl kódu
3. Přidejte testy pro novou funkcionalitu
4. Podle potřeby aktualizujte dokumentaci
### Submit Your PR
### Odešlete svůj PR
1. Push your branch:
1. Odešlete svou větev:
```bash
git push origin feature/your-feature-name
```
2. Open a PR on GitHub
3. Fill in the PR template
4. Link related issues
2. Otevřete PR na GitHubu
3. Vyplňte šablonu PR
4. Propojte související issues
### PR Checklist
### Kontrolní seznam PR
* [ ] Code follows project style guidelines
* [ ] Tests pass locally
* [ ] Documentation is updated
* [ ] PR description explains the changes
* [ ] Kód odpovídá projektovým zásadám stylu
* [ ] Testy procházejí lokálně
* [ ] Dokumentace je aktualizována
* [ ] Popis PR vysvětluje změny
@@ -77,8 +77,8 @@ If you feel like you need to add a `useEffect` in your root component, you shoul
Stejný postup můžete aplikovat na logiku získávání dat pomocí Apollo hooks.
```tsx
// ❌ Bad, will cause re-renders even if data is not changing,
// because useEffect needs to be re-evaluated
// ❌ Špatně, způsobí překreslení i když se data nemění,
// protože useEffect je třeba přehodnotit
export const PageComponent = () => {
const [data, setData] = useRecoilState(dataState);
const [someDependency] = useRecoilState(someDependencyState);
@@ -96,12 +96,12 @@ export const App = () => (
<RecoilRoot>
<PageComponent />
</RecoilRoot>
);
);},{
```
```tsx
// ✅ Good, will not cause re-renders if data is not changing,
// because useEffect is re-evaluated in another sibling component
// ✅ Dobře, nezpůsobí překreslení, pokud se data nemění,
// protože useEffect je přehodnoceno v další sourozené komponentě
export const PageComponent = () => {
const [data, setData] = useRecoilState(dataState);
@@ -240,7 +240,7 @@ Nejčastější příklad je komponenta ikon:
```tsx
const SomeParentComponent = () => <MyComponent Icon={MyIcon} />;
// In MyComponent
// V komponentě MyComponent
const MyComponent = ({ MyIcon }: { MyIcon: IconComponent }) => {
const theme = useTheme();
@@ -29,7 +29,7 @@ Zahrnuje komponenty nejvyšší úrovně definované aplikačními trasami. Impo
## Moduly
Každý modul představuje funkci nebo skupinu funkcí s jejich specifickými komponenty, stavy a provozní logikou.
Všechny by měly dodržovat strukturu níže. You can nest modules within modules (referred to as submodules) and the same rules will apply.
Všechny by měly dodržovat strukturu níže. Moduly můžete vnořovat do sebe (tzv. podmoduly) a platí pro ně stejná pravidla.
```
module1
@@ -64,7 +64,7 @@ Více podrobností naleznete v [GraphQL](https://graphql.org/learn/).
* Fragmenty
Fragment je znovupoužitelný kus dotazu, který můžete použít na různých místech. By using fragments, it's easier to avoid duplicating code.
Fragment je znovupoužitelný kus dotazu, který můžete použít na různých místech. Pomocí fragmentů je snazší vyhnout se duplikaci kódu.
Více podrobností naleznete v [GraphQL Fragments](https://graphql.org/learn/queries/#fragments).
@@ -76,7 +76,7 @@ Více podrobností naleznete v [GraphQL Queries](https://graphql.org/learn/queri
Více podrobností naleznete v [GraphQL Mutations](https://graphql.org/learn/queries/#mutations).
### Hooks
### Hooky
Více podrobností naleznete v [Hooks](https://react.dev/learn/reusing-logic-with-custom-hooks).
@@ -88,9 +88,9 @@ Obsahuje logiku správy stavů. To řeší [RecoilJS](https://recoiljs.org).
Vestavěná správa stavů v Reactu stále spravuje stav uvnitř komponenty.
### Utils
### Pomocné funkce
Měly by obsahovat pouze znovupoužitelné čisté funkce. Otherwise, create custom hooks in the `hooks` folder.
Měly by obsahovat pouze znovupoužitelné čisté funkce. V opačném případě vytvořte vlastní hooky ve složce `hooks`.
## UI
@@ -25,7 +25,7 @@ npx nx run twenty-front:graphql:generate
### Linter
```bash
npx nx run twenty-front:lint # pass --fix to fix lint errors
npx nx run twenty-front:lint # přidejte --fix pro opravu chyb ve formátování
```
## Překlady
@@ -3,6 +3,6 @@ title: Storybook
description: Prozkoumejte knihovnu komponent UI na Twenty
---
View our complete component library and documentation in Storybook.
Prohlédněte si naši kompletní knihovnu komponent a dokumentaci ve Storybooku.
[Open Storybook →](https://storybook.twenty.com)
[Otevřít Storybook →](https://storybook.twenty.com)
@@ -36,9 +36,9 @@ export function MyComponent() {
### Vlastnosti
Create the type of the props and call it `(ComponentName)Props` if there's no need to export it.
Vytvořte typ rekvizit a pojmenujte jej `(ComponentName)Props`, pokud není potřeba jej exportovat.
Use props destructuring.
Použijte destrukturalizaci rekvizit.
```tsx
// ❌ Bad, no type
@@ -67,11 +67,11 @@ const EmailField: React.FC<{
```
```tsx
/* ✅ - Good, a separate type (OwnProps) is explicitly defined for the
* component's props
* - This method doesn't automatically include the children prop. If
* you want to include it, you have to specify it in OwnProps.
*/
/* ✅ - Dobré, explicitně definován samostatný typ (OwnProps) pro
* rekvizity komponenty
* - Tato metoda automaticky nezahrnuje rekvizitu children. Pokud
* ji chcete zahrnout, musíte ji specifikovat v OwnProps.
*/
type EmailFieldProps = {
value: string;
};
@@ -81,9 +81,9 @@ const EmailField = ({ value }: EmailFieldProps) => (
);
```
#### No Single Variable Prop Spreading in JSX Elements
#### Nepoužívejte rozbalení jediného objektu rekvizit v prvcích JSX
Avoid using single variable prop spreading in JSX elements, like `{...props}`. Tato praxe často vede k tomu, že kód je méně čitelný a obtížnější udržovat, protože není jasné, které rekvizity komponenta přijímá.
Vyhněte se používání rozbalení jediného objektu rekvizit v prvcích JSX, například `{...props}`. Tato praxe často vede k tomu, že kód je méně čitelný a obtížnější udržovat, protože není jasné, které rekvizity komponenta přijímá.
```tsx
/* ❌ - Bad, spreads a single variable prop into the underlying component
@@ -94,9 +94,9 @@ const MyComponent = (props: OwnProps) => {
```
```tsx
/* ✅ - Good, Explicitly lists all props
* - Enhances readability and maintainability
*/
/* ✅ - Dobré, explicitně uvádí všechny rekvizity
* - Zvyšuje čitelnost a udržovatelnost
*/
const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => {
return <OtherComponent {...{ prop1, prop2, prop3 }} />;
};
@@ -105,8 +105,8 @@ const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => {
Odůvodnění:
* Na první pohled je jasné, které prop kód předává, čímž je snazší pochopit a udržovat.
* It helps to prevent tight coupling between components via their props.
* Linting tools make it easier to identify misspelled or unused props when you list props explicitly.
* Pomáhá to předcházet těsnému provázání mezi komponentami prostřednictvím jejich rekvizit.
* Lintovací nástroje usnadňují identifikaci překlepů nebo nepoužívaných rekvizit, když rekvizity uvádíte explicit.
## JavaScript
@@ -123,10 +123,10 @@ const value = process.env.MY_VALUE ?? 'default';
### Používejte volitelné zřetězení `?.`
```tsx
// ❌ Bad
// ❌ Špatné
onClick && onClick();
// ✅ Good
// ✅ Dobré
onClick?.();
```
@@ -234,7 +234,7 @@ Vyhýbejte se používání hodnot `px` nebo `rem` přímo ve stylizovaných kom
#### Barvy
Refrain from introducing new colors; instead, use the existing palette from the theme. Pokud by došlo k tomu, že paleta neodpovídá, prosím nechte komentář, aby to tým mohl napravit.
Zdržte se zavádění nových barev; místo toho použijte existující paletu z tématu. Pokud by došlo k tomu, že paleta neodpovídá, prosím nechte komentář, aby to tým mohl napravit.
```tsx
// ❌ Špatné, přímo specifikuje hodnoty stylu bez využití tématu
@@ -275,11 +275,11 @@ import { Meta, StoryObj } from '@storybook/react';
### Proč Zákaz Importů Typů
* **Consistency**: By avoiding type imports and using a single approach for both type and value imports, the codebase remains consistent in its module import style.
* **Konzistence**: Vyhýbáním se importům typů a použitím jednotného přístupu pro importy typů i hodnot zůstává kódová základna konzistentní ve svém stylu importů modulů.
* **Readability**: No-type imports improve code readability by making it clear when you're importing values or types. Tím se snižuje dvojznačnost a usnadňuje pochopení účelu importovaných symbolů.
* **Čitelnost**: Importy bez type zlepšují čitelnost kódu tím, že je jasné, zda importujete hodnoty nebo typy. Tím se snižuje dvojznačnost a usnadňuje pochopení účelu importovaných symbolů.
* **Maintainability**: It enhances codebase maintainability because developers can identify and locate type-only imports when reviewing or modifying code.
* **Udržovatelnost**: Zvyšuje udržovatelnost kódové základny, protože vývojáři mohou při revizi nebo úpravách kódu identifikovat a najít importy pouze typů.
### Pravidlo ESLint
@@ -287,4 +287,4 @@ Pravidlo ESLint, `@typescript-eslint/consistent-type-imports`, prosazuje standar
Upozorňujeme, že toto pravidlo konkrétně řeší vzácné okrajové případy, kdy dochází k neúmyslným typovým importům. TypeScript sám odrazuje tuto praxi, jak je uvedeno v [poznámkách k verzi TypeScript 3.8](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). Ve většině případů byste neměli potřebovat používat pouze typové importy.
To ensure your code complies with this rule, make sure to run ESLint as part of your development workflow.
Aby váš kód splňoval toto pravidlo, spusťte ESLint jako součást svého vývojového pracovního postupu.
@@ -1,6 +1,6 @@
---
title: Práce s Figma
info: Learn how you can collaborate with Twenty's Figma
info: Zjistěte, jak můžete spolupracovat s Figmou Twenty
---
Figma je nástroj pro návrh uživatelského rozhraní, který pomáhá překlenout komunikační bariéru mezi návrháři a vývojáři.
@@ -18,7 +18,7 @@ Tento průvodce vysvětluje, jak můžete spolupracovat s Figma.
## Struktura Figma
On the left sidebar, you can access the different pages of Twenty's Figma. Takto jsou organizovány:
Na levém postranním panelu můžete přistupovat k různým stránkám Figmy společnosti Twenty. Takto jsou organizovány:
* **Stránka komponentů:** Toto je první stránka. Návrhář ji používá k vytváření a organizování znovupoužitelných návrhových prvků použitých v celém návrhovém souboru. Například tlačítka, ikony, symboly nebo jakékoli jiné znovupoužitelné komponenty. Slouží k zajištění konzistence v celém návrhu.
* **Hlavní stránka:** Druhá stránka je hlavní stránka, která zobrazuje kompletní uživatelské rozhraní projektu. Můžete stisknout **"Přehrát"**, abyste použili kompletní prototyp aplikace.
@@ -114,7 +114,7 @@ Všechny příkazy v následujících krocích byste měli provádět z kořene
**Možnost 2:** Pokud máte nainstalován docker:
```bash
make postgres-on-docker
make -C packages/twenty-docker postgres-on-docker
```
</Tab>
@@ -172,7 +172,7 @@ Všechny příkazy v následujících krocích byste měli provádět z kořene
**Možnost 2:** Pokud máte nainstalován docker:
```bash
make postgres-on-docker
make -C packages/twenty-docker postgres-on-docker
```
</Tab>
@@ -193,7 +193,7 @@ Všechny příkazy v následujících krocích byste měli provádět z kořene
Použijte tuto možnost pouze pokud si jste jisti extra kroky včetně zapnutí [Docker Desktop WSL2](https://docs.docker.com/desktop/wsl).
```bash
make postgres-on-docker
make -C packages/twenty-docker postgres-on-docker
```
</Tab>
</Tabs>
@@ -212,7 +212,7 @@ Twenty vyžaduje ke svému provozu Redis cache pro zajištění nejlepšího vý
**Možnost 2:** Pokud máte nainstalován docker:
```bash
make redis-on-docker
make -C packages/twenty-docker redis-on-docker
```
</Tab>
@@ -229,7 +229,7 @@ Twenty vyžaduje ke svému provozu Redis cache pro zajištění nejlepšího vý
**Možnost 2:** Pokud máte nainstalován docker:
```bash
make redis-on-docker
make -C packages/twenty-docker redis-on-docker
```
</Tab>
@@ -240,7 +240,7 @@ Twenty vyžaduje ke svému provozu Redis cache pro zajištění nejlepšího vý
**Možnost 2:** Pokud máte nainstalován docker:
```bash
make redis-on-docker
make -C packages/twenty-docker redis-on-docker
```
</Tab>
</Tabs>
@@ -259,7 +259,7 @@ cp ./packages/twenty-server/.env.example ./packages/twenty-server/.env
```
<Info>
**Multi-Workspace Mode:** By default, Twenty runs in single-workspace mode where only one workspace can be created. To enable multi-workspace support (useful for testing subdomain-based features), set `IS_MULTIWORKSPACE_ENABLED=true` in your server `.env` file. See [Multi-Workspace Mode](/l/cs/developers/self-host/capabilities/setup#multi-workspace-mode) for details.
**Režim více pracovních prostorů:** Ve výchozím nastavení běží Twenty v režimu jednoho pracovního prostoru, ve kterém lze vytvořit pouze jeden pracovní prostor. Chcete-li povolit podporu více pracovních prostorů (užitečné pro testování funkcí založených na subdoménách), nastavte v serverovém souboru `.env` hodnotu `IS_MULTIWORKSPACE_ENABLED=true`. Podrobnosti viz [Režim více pracovních prostorů](/l/cs/developers/self-host/capabilities/setup#multi-workspace-mode).
</Info>
## Krok 6: Instalace závislostí
@@ -1,6 +1,6 @@
---
title: Contribute
description: Contribute to Twenty's open-source development.
title: Přispět
description: Přispějte k open-source vývoji Twenty.
---
<Frame>
@@ -9,24 +9,24 @@ description: Contribute to Twenty's open-source development.
## Přehled
Twenty is open-source and welcomes contributions from the community. Whether you're fixing bugs, adding features, or improving documentation, your contributions help make Twenty better for everyone.
Twenty je open-source a vítá příspěvky od komunity. Ať už opravujete chyby, přidáváte funkce nebo zlepšujete dokumentaci, vaše příspěvky pomáhají zlepšovat Twenty pro všechny.
## Ways to Contribute
## Způsoby, jak přispět
* **Report bugs**: Help identify and document issues
* **Submit features**: Propose and implement new functionality
* **Improve documentation**: Make our docs clearer and more helpful
* **Frontend development**: Work on the React-based UI
* **Backend development**: Contribute to the NestJS server
* **Nahlašujte chyby**: Pomozte identifikovat a dokumentovat problémy
* **Přidávejte funkce**: Navrhujte a implementujte novou funkcionalitu
* **Zlepšujte dokumentaci**: Udělejte naši dokumentaci přehlednější a užitečnější
* **Vývoj frontendu**: Pracujte na uživatelském rozhraní postaveném na Reactu
* **Vývoj backendu**: Podílejte se na serveru NestJS
## Getting Started
## Začínáme
<CardGroup cols={2}>
<Card title="Bug Reports & Requests" icon="bug" href="/l/cs/developers/contribute/capabilities/bug-and-requests">
Report issues or request features
<Card title="Hlášení chyb a požadavky" icon="bug" href="/l/cs/developers/contribute/capabilities/bug-and-requests">
Nahlaste problémy nebo požádejte o nové funkce
</Card>
<Card title="Vývoj frontendu" icon="browser" href="/l/cs/developers/contribute/capabilities/frontend-development">
Contribute to the UI
Přispějte k vývoji uživatelského rozhraní
</Card>
</CardGroup>
@@ -1,6 +1,6 @@
---
title: API
description: Query and modify your CRM data programmatically using REST or GraphQL.
description: Programově dotazujte a upravujte svá CRM data pomocí REST nebo GraphQL.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
@@ -9,7 +9,7 @@ Twenty bylo vytvořeno s ohledem na vývojáře, nabízíme výkonné API, kter
## Přístup orientovaný na vývojáře
Twenty generates APIs specifically for your data model:
Twenty generuje API specificky pro váš datový model:
* **Nejsou vyžadována dlouhá ID**: Používejte v koncových bodech přímo názvy objektů a polí.
* **Standardní a vlastní objekty jsou rovnocenně zpracovány**: Vaše vlastní objekty mají stejnou podporu API jako vestavěné.
@@ -17,52 +17,52 @@ Twenty generates APIs specifically for your data model:
* **Vlastní dokumentace**: Generována specificky pro datový model vašeho pracovního prostoru.
<Note>
Your personalized API documentation is available under **Settings → API & Webhooks** after creating an API key. Since Twenty generates APIs that match your custom data model, the documentation is unique to your workspace.
Vaše personalizovaná dokumentace k API je dostupná v **Nastavení → API & Webhooks** po vytvoření API klíče. Protože Twenty generuje API odpovídající vašemu vlastnímu datovému modelu, dokumentace je jedinečná pro váš pracovní prostor.
</Note>
## The Two API Types
## Dva typy API
### Core API
Přístupné na `/rest/` nebo `/graphql/`
Work with your actual **records** (the data):
Pracujte se svými skutečnými **záznamy** (daty):
* Create, read, update, delete People, Companies, Opportunities, etc.
* Query and filter data
* Vytvářejte, čtěte, aktualizujte a mazejte Lidi, Společnosti, Příležitosti atd.
* Dotazujte a filtrujte data
* Spravování vztahů mezi záznamy.
### Metadata API
Přístupné na `/rest/metadata/` nebo `/metadata/`
Manage your **workspace and data model**:
Spravujte svůj **pracovní prostor a datový model**:
* Vytvářet, upravovat nebo mazat objekty a pole.
* Konfigurace nastavení pracovního prostoru.
* Define relationships between objects
* Definujte vztahy mezi objekty
## REST vs GraphQL
Both Core and Metadata APIs are available in REST and GraphQL formats:
Jak Core, tak Metadata API jsou k dispozici ve formátech REST a GraphQL:
| Formát | Available Operations |
| ----------- | ---------------------------------------------------------- |
| **REST** | CRUD, batch operations, upserts |
| **GraphQL** | Same + **batch upserts**, relationship queries in one call |
| Formát | Dostupné operace |
| ----------- | ---------------------------------------------------------------------- |
| **REST** | CRUD, hromadné operace, operace upsert |
| **GraphQL** | Stejné + **hromadné operace upsert**, dotazy na vztahy v jednom volání |
Choose based on your needs — both formats access the same data.
Zvolte podle svých potřeb — oba formáty přistupují ke stejným datům.
## Koncové body API
| Environment | Base URL |
| --------------- | ------------------------- |
| **Cloud** | `https://api.twenty.com/` |
| **Self-Hosted** | `https://{your-domain}/` |
| Prostředí | Základní URL |
| ------------------- | ------------------------- |
| **Cloud** | `https://api.twenty.com/` |
| **Vlastní hosting** | `https://{your-domain}/` |
## Ověření
Every API request requires an API key in the header:
Každý požadavek na API vyžaduje klíč API v hlavičce:
```
Authorization: Bearer YOUR_API_KEY
@@ -70,78 +70,78 @@ Authorization: Bearer YOUR_API_KEY
### Vytvořit API klíč
1. Go to **Settings → APIs & Webhooks**
2. Click **+ Create key**
1. Přejděte na **Nastavení → APIs & Webhooks**
2. Klikněte na **+ Vytvořit klíč**
3. Nakonfigurujte:
* **Name**: Descriptive name for the key
* **Expiration Date**: When the key expires
* **Název**: Popisný název pro klíč
* **Datum vypršení platnosti**: Kdy klíč vyprší
4. Klikněte na **Uložit**
5. **Copy immediately** — the key is only shown once
5. **Zkopírujte ihned** — klíč se zobrazí pouze jednou
<VimeoEmbed videoId="928786722" title="Creating API key" />
<VimeoEmbed videoId="928786722" title="Vytvoření klíče API" />
<Warning>
Your API key grants access to sensitive data. Don't share it with untrusted services. If compromised, disable it immediately and generate a new one.
Váš klíč API poskytuje přístup k citlivým datům. Nesdílejte ho s nedůvěryhodnými službami. Pokud je kompromitován, okamžitě ho deaktivujte a vygenerujte nový.
</Warning>
### Assign a Role to an API Key
### Přiřaďte roli klíči API
For better security, assign a specific role to limit access:
Pro vyšší bezpečnost přiřaďte konkrétní roli, abyste omezili přístup:
1. Přejděte na **Nastavení → Role**
2. Click on the role to assign
2. Klikněte na roli, kterou chcete přiřadit
3. Otevřete záložku **Přiřazení**
4. Under **API Keys**, click **+ Assign to API key**
5. Select the API key
4. V části **API Keys** klikněte na **+ Přiřadit ke klíči API**
5. Vyberte klíč API
The key will inherit that role's permissions. See [Permissions](/l/cs/user-guide/permissions-access/capabilities/permissions) for details.
Klíč zdědí oprávnění této role. Podrobnosti viz [Oprávnění](/l/cs/user-guide/permissions-access/capabilities/permissions).
### Spravovat API klíče
**Regenerate**: Settings → APIs & Webhooks → Click key → **Regenerate**
**Znovu vygenerovat**: Nastavení → APIs & Webhooks → Klikněte na klíč → **Znovu vygenerovat**
**Delete**: Settings → APIs & Webhooks → Click key → **Delete**
**Smazat**: Nastavení → APIs & Webhooks → Klikněte na klíč → **Smazat**
## API Playground
Test your APIs directly in the browser with our built-in playground — available for both **REST** and **GraphQL**.
Testujte svá API přímo v prohlížeči pomocí našeho vestavěného playgrounduk dispozici pro **REST** i **GraphQL**.
### Access the Playground
### Přístup do Playgroundu
1. Go to **Settings → APIs & Webhooks**
2. Create an API key (required)
3. Click on **REST API** or **GraphQL API** to open the playground
1. Přejděte na **Nastavení → APIs & Webhooks**
2. Vytvořte klíč API (povinné)
3. Klikněte na **REST API** nebo **GraphQL API** pro otevření playgroundu
### What You Get
### Co získáte
* **Interactive documentation**: Generated for your specific data model
* **Live testing**: Execute real API calls against your workspace
* **Schema explorer**: Browse available objects, fields, and relationships
* **Request builder**: Construct queries with autocomplete
* **Interaktiv dokumentace**: Generována pro váš specific datový model
* **Živé testování**: Spouštějte reálná volání API vůči vašemu pracovnímu prostoru
* **Průzkumník schématu**: Procházejte dostupné objekty, pole a vztahy
* **Tvůrce požadavků**: Sestavujte dotazy s automatickým doplňováním
The playground reflects your custom objects and fields, so documentation is always accurate for your workspace.
Playground odráží vaše vlastní objekty a pole, takže dokumentace je pro váš pracovní prostor vždy přesná.
## Hromadné operace
Both REST and GraphQL support batch operations:
REST i GraphQL podporují hromadné operace:
* **Velikost dávky**: Až 60 záznamů na požadavek.
* **Operations**: Create, update, delete multiple records
* **Operace**: Vytváření, aktualizace a mazání více záznamů
**GraphQL-only features:**
**Funkce pouze pro GraphQL:**
* **Batch Upsert**: Create or update in one call
* Use plural object names (e.g., `CreateCompanies` instead of `CreateCompany`)
* **Hromadný upsert**: Vytvoření nebo aktualizace v jednom volání
* Používejte množná čísla názvů objektů (např. `CreateCompanies` místo `CreateCompany`)
## Rate Limits
## Limity rychlosti
API requests are throttled to ensure platform stability:
Požadavky na API jsou omezovány, aby byla zajištěna stabilita platformy:
| Limit | Hodnota |
| -------------- | -------------------- |
| **Requests** | 100 calls per minute |
| **Batch size** | 60 records per call |
| Limit | Hodnota |
| ------------------ | -------------------- |
| **Požadavky** | 100 volání za minutu |
| **Velikost dávky** | 60 záznamů na volání |
<Tip>
Use batch operations to maximize throughput — process up to 60 records in a single API call instead of making individual requests.
Pro maximalizaci propustnosti používejte hromadné operace — zpracujte až 60 záznamů v jediném volání API místo odesílání jednotlivých požadavků.
</Tip>
@@ -1,34 +1,34 @@
---
title: Twenty Apps
description: Build and manage Twenty customizations as code.
title: Aplikace Twenty
description: Vytvářejte a spravujte přizpůsobení Twenty jako kód.
---
<Warning>
Apps are currently in alpha testing. The feature is functional but still evolving.
Aplikace jsou aktuálně v alfa testování. Tato funkce je funkční, ale stále se vyvíjí.
</Warning>
## What Are Apps?
## Co jsou aplikace?
Apps let you build and manage Twenty customizations **as code**. Instead of configuring everything through the UI, you define your data model and serverless functions in code — making it faster to build, maintain, and roll out to multiple workspaces.
Aplikace vám umožňují vytvářet a spravovat přizpůsobení Twenty **jako kód**. Místo konfigurace všeho přes uživatelské rozhraní definujete v kódu svůj datový model a serverless funkce — což zrychluje vývoj, údržbu i nasazování do více pracovních prostorů.
**What you can do today:**
**Co můžete dělat už dnes:**
* Define custom objects and fields as code (managed data model)
* Build serverless functions with custom triggers
* Deploy the same app across multiple workspaces
* Definujte vlastní objekty a pole jako kód (spravovaný datový model)
* Vytvářejte serverless funkce s vlastními spouštěči
* Nasazujte stejnou aplikaci do více pracovních prostorů
**Coming soon:**
**Již brzy:**
* Custom UI layouts and components
* Vlastní rozvržení a komponenty uživatelského rozhraní
## Předpoklady
* Node.js 24+ and Yarn 4
* A Twenty workspace and an API key (create one at https://app.twenty.com/settings/api-webhooks)
* Node.js 24+ a Yarn 4
* Pracovní prostor Twenty a klíč API (vytvořte si jej na https://app.twenty.com/settings/api-webhooks)
## Getting Started
## Začínáme
Create a new app using the official scaffolder, then authenticate and start developing:
Vytvořte novou aplikaci pomocí oficiálního scaffolderu, poté se ověřte a začněte vyvíjet:
```bash filename="Terminal"
# Scaffold a new app
@@ -64,18 +64,18 @@ yarn uninstall
yarn help
```
See also: the CLI reference pages for [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) and [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
Viz také: referenční stránky CLI pro [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) a [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
## Project structure (scaffolded)
## Struktura projektu (vytvořená scaffolderem)
When you run `npx create-twenty-app@latest my-twenty-app`, the scaffolder:
Když spustíte `npx create-twenty-app@latest my-twenty-app`, scaffolder:
* Copies a minimal base application into `my-twenty-app/`
* Adds a local `twenty-sdk` dependency and Yarn 4 configuration
* Creates config files and scripts wired to the `twenty` CLI
* Generates a default application config and a default function role
* Zkopíruje minimální základní aplikaci do `my-twenty-app/`
* Přidá lokální závislost `twenty-sdk` a konfiguraci pro Yarn 4
* Vytvoří konfigurační soubory a skripty napojené na `twenty` CLI
* Vygeneruje výchozí konfiguraci aplikace a výchozí roli funkcí
A freshly scaffolded app looks like this:
Čerstvě vytvořená aplikace vypadá takto:
```text filename="my-twenty-app/"
my-twenty-app/
@@ -99,21 +99,21 @@ my-twenty-app/
utils/ # Optional - handler implementations & utilities
```
### Convention-over-configuration
### Konvence před konfigura
Applications use a **convention-over-configuration** approach where entities are detected by their file suffix. This allows flexible organization within the `src/app/` folder:
Aplikace používají přístup **konvence před konfigurací**, kde jsou entity detekovány podle přípony souboru. To umožňuje flexibilní organizaci ve složce `src/app/`:
| File suffix | Entity type |
| --------------- | ------------------------------- |
| `*.object.ts` | Custom object definitions |
| `*.function.ts` | Serverless function definitions |
| `*.role.ts` | Role definitions |
| Přípona souboru | Typ entity |
| --------------- | -------------------------- |
| `*.object.ts` | Definice vlastních objektů |
| `*.function.ts` | Definice serverless funkcí |
| `*.role.ts` | Definice rolí |
### Supported folder organizations
### Podporované uspořádání složek
You can organize your entities in any of these patterns:
Entity můžete uspořádat podle některého z těchto vzorů:
**Traditional (by type):**
**Tradiční (podle typu):**
```text
src/app/
@@ -126,7 +126,7 @@ src/app/
└── admin.role.ts
```
**Feature-based:**
**Podle funkcí:**
```text
src/app/
@@ -137,7 +137,7 @@ src/app/
└── postCardAdmin.role.ts
```
**Flat:**
**Plochá:**
```text
src/app/
@@ -147,34 +147,34 @@ src/app/
└── admin.role.ts
```
At a high level:
V kostce:
* **package.json**: Declares the app name, version, engines (Node 24+, Yarn 4), and adds `twenty-sdk` plus scripts like `dev`, `sync`, `generate`, `create-entity`, `logs`, `uninstall`, and `auth` that delegate to the local `twenty` CLI.
* **.gitignore**: Ignores common artifacts such as `node_modules`, `.yarn`, `generated/` (typed client), `dist/`, `build/`, coverage folders, log files, and `.env*` files.
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Lock and configure the Yarn 4 toolchain used by the project.
* **.nvmrc**: Pins the Node.js version expected by the project.
* **eslint.config.mjs** and **tsconfig.json**: Provide linting and TypeScript configuration for your app's TypeScript sources.
* **README.md**: A short README in the app root with basic instructions.
* **src/app/**: The main place where you define your application-as-code:
* `application.config.ts`: Global configuration for your app (metadata and runtime wiring). See "Application config" below.
* `*.role.ts`: Role definitions used by your serverless functions. See "Default function role" below.
* `*.object.ts`: Custom object definitions.
* `*.function.ts`: Serverless function definitions.
* **src/utils/**: Optional folder for handler implementations and utilities.
* **package.json**: Deklaruje název aplikace, verzi, engines (Node 24+, Yarn 4) a přidává `twenty-sdk` plus skripty jako `dev`, `sync`, `generate`, `create-entity`, `logs`, `uninstall` a `auth`, které delegují na lokální `twenty` CLI.
* **.gitignore**: Ignoruje běžné artefakty jako `node_modules`, `.yarn`, `generated/` (typovaný klient), `dist/`, `build/`, složky s coverage, logy a soubory `.env*`.
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Zamykají a konfigurují nástrojový řetězec Yarn 4 používaný projektem.
* **.nvmrc**: Fixuje verzi Node.js požadovanou projektem.
* **eslint.config.mjs** a **tsconfig.json**: Poskytují lintování a konfiguraci TypeScriptu pro zdrojové soubory vaší aplikace v TypeScriptu.
* **README.md**: Krátké README v kořeni aplikace se základními pokyny.
* **src/app/**: Hlavní místo, kde definujete svou aplikaci jako kód:
* `application.config.ts`: Globální konfigurace vaší aplikace (metadata a napojení za běhu). Viz „Konfigurace aplikace“ níže.
* `*.role.ts`: Definice rolí používané vašimi serverless funkcemi. Viz „Výchozí role funkce“ níže.
* `*.object.ts`: Definice vlastních objektů.
* `*.function.ts`: Definice serverless funkcí.
* **src/utils/**: Volitelná složka pro implementace obslužných funkcí a pomocné nástroje.
Later commands will add more files and folders:
Pozdější příkazy přidají další soubory a složky:
* `yarn generate` will create a `generated/` folder (typed Twenty client + workspace types).
* `yarn create-entity` will add entity definition files under `src/app/` for your custom objects, functions, or roles.
* `yarn generate` vytvoří složku `generated/` (typovaný klient Twenty + typy pracovního prostoru).
* `yarn create-entity` přidá soubory s definicemi entit do `src/app/` pro vaše vlastní objekty, funkce nebo role.
## Ověření
The first time you run `yarn auth`, you'll be prompted for:
Při prvním spuštění `yarn auth` budete vyzváni k zadání:
* API URL (defaults to http://localhost:3000 or your current workspace profile)
* API key
* URL API (výchozí je http://localhost:3000 nebo váš aktuální profil pracovního prostoru)
* Klíč API
Your credentials are stored per-user in `~/.twenty/config.json`. You can maintain multiple profiles and switch using `--workspace <name>`.
Vaše přihlašovací údaje se ukládají pro jednotlivé uživatele do `~/.twenty/config.json`. Můžete spravovat více profilů a přepínat pomocí `--workspace <name>`.
Příklady:
@@ -186,26 +186,26 @@ yarn auth
yarn auth --workspace my-custom-workspace
```
## Use the SDK resources (types & config)
## Používejte zdroje SDK (typy a konfiguraci)
The twenty-sdk provides typed building blocks and helper functions you use inside your app. Below are the key pieces you'll touch most often.
twenty-sdk poskytuje typované stavební bloky a pomocné funkce, které používáte ve své aplikaci. Níže jsou klíčové části, se kterými budete nejčastěji pracovat.
### Helper functions
### Pomocné funkce
The SDK provides four helper functions with built-in validation for defining your app entities:
SDK poskytuje čtyři pomocné funkce s vestavěnou validací pro definování entit vaší aplikace:
| Function | Účel |
| ------------------ | -------------------------------------------- |
| `defineApp()` | Configure application metadata |
| `defineObject()` | Define custom objects with fields |
| `defineFunction()` | Define serverless functions with handlers |
| `defineRole()` | Configure role permissions and object access |
| Funkce | Účel |
| ------------------ | ------------------------------------------------ |
| `defineApp()` | Konfigurace metadat aplikace |
| `defineObject()` | Definice vlastních objektů s poli |
| `defineFunction()` | Definice serverless funkcí s obslužnými funkcemi |
| `defineRole()` | Konfigurace oprávnění rolí a přístupu k objektům |
These functions validate your configuration at runtime and provide better IDE autocompletion and type safety.
Tyto funkce validují vaši konfiguraci za běhu a poskytují lepší automatické doplňování v IDE a lepší typovou bezpečnost.
### Defining objects
### Definování objektů
Custom objects describe both schema and behavior for records in your workspace. Use `defineObject()` to define objects with built-in validation:
Vlastní objekty popisují jak schéma, tak chování záznamů ve vašem pracovním prostoru. K definování objektů s vestavěnou validací použijte `defineObject()`:
```typescript
// src/app/postCard.object.ts
@@ -276,20 +276,20 @@ export default defineObject({
});
```
Key points:
Hlavní body:
* Use `defineObject()` for built-in validation and better IDE support.
* The `universalIdentifier` must be unique and stable across deployments.
* Each field requires a `name`, `type`, `label`, and its own stable `universalIdentifier`.
* The `fields` array is optional — you can define objects without custom fields.
* You can scaffold new objects using `yarn create-entity`, which guides you through naming, fields, and relationships.
* Použijte `defineObject()` pro vestavěnou validaci a lepší podporu v IDE.
* Hodnota `universalIdentifier` musí být jedinečná a stabilní napříč nasazeními.
* Každé pole vyžaduje `name`, `type`, `label` a svůj vlastní stabilní `universalIdentifier`.
* Pole `fields` je volitelné — objekty můžete definovat i bez vlastních polí.
* Nové objekty můžete vygenerovat pomocí `yarn create-entity`, který vás provede pojmenováním, poli a vztahy.
<Note>
**Base fields are created automatically.** When you define a custom object, Twenty automatically adds standard fields such as `name`, `createdAt`, `updatedAt`, `createdBy`, `position`, and `deletedAt`. You don't need to define these in your `fields` array — only add your custom fields.
**Základní pole jsou vytvořena automaticky.** Když definujete vlastní objekt, Twenty automaticky přidá standardní pole jako `name`, `createdAt`, `updatedAt`, `createdBy`, `position` a `deletedAt`. Nemusíte je definovat v poli `fields` — přidejte pouze svá vlastní pole.
</Note>
<Accordion title="Alternative: Decorator-based syntax">
You can also define objects using TypeScript decorators. This approach uses class-based syntax with `@Object`, `@Field`, and `@Relation` decorators:
<Accordion title="Alternativa: Syntaxe založená na dekorátorech">
Objekty můžete definovat také pomocí dekorátorů TypeScriptu. Tento přístup používá třídovou syntaxi s dekorátory `@Object`, `@Field` a `@Relation`:
```typescript
import {
@@ -336,18 +336,18 @@ Key points:
}
```
Note: The decorator approach requires `experimentalDecorators` in your TypeScript config.
Poznámka: Přístup s dekorátory vyžaduje `experimentalDecorators` v konfiguraci TypeScriptu.
</Accordion>
### Application config (application.config.ts)
### Konfigurace aplikace (application.config.ts)
Every app has a single `application.config.ts` file that describes:
Každá aplikace má jeden soubor `application.config.ts`, který popisuje:
* **Who the app is**: identifiers, display name, and description.
* **How its functions run**: which role they use for permissions.
* **(Optional) variables**: keyvalue pairs exposed to your functions as environment variables.
* **Identitu aplikace**: identifikátory, zobrazovaný název a popis.
* **Jak běží její funkce**: kterou roli používají pro oprávnění.
* **(Volitelné) proměnné**: dvojice klíč–hodnota zpřístupněné vašim funkcím jako proměnné prostředí.
Use `defineApp()` to define your application configuration:
K definování konfigurace aplikace použijte `defineApp()`:
```typescript
// src/app/application.config.ts
@@ -371,23 +371,23 @@ export default defineApp({
});
```
Notes:
Poznámky:
* `universalIdentifier` fields are deterministic IDs you own; generate them once and keep them stable across syncs.
* `applicationVariables` become environment variables for your functions (for example, `DEFAULT_RECIPIENT_NAME` is available as `process.env.DEFAULT_RECIPIENT_NAME`).
* `functionRoleUniversalIdentifier` must match the role you define in your `*.role.ts` file (see below).
* Pole `universalIdentifier` jsou deterministic ID, která vlastníte; vygenerujte je jednou a udržujte je stabilní napříč synchronizacemi.
* `applicationVariables` se stanou proměnnými prostředí pro vaše funkce (například `DEFAULT_RECIPIENT_NAME` je dostupné jako `process.env.DEFAULT_RECIPIENT_NAME`).
* `functionRoleUniversalIdentifier` se musí shodovat s rolí, kterou definujete ve svém souboru `*.role.ts` (viz níže).
#### Roles and permissions
#### Role a oprávnění
Applications can define roles that encapsulate permissions on your workspace's objects and actions. The field `functionRoleUniversalIdentifier` in `application.config.ts` designates the default role used by your app's serverless functions.
Aplikace mohou definovat role, které zapouzdřují oprávnění k objektům a akcím ve vašem pracovním prostoru. Pole `functionRoleUniversalIdentifier` v `application.config.ts` určuje výchozí roli používanou serverless funkcemi vaší aplikace.
* The runtime API key injected as `TWENTY_API_KEY` is derived from this default function role.
* The typed client will be restricted to the permissions granted to that role.
* Follow leastprivilege: create a dedicated role with only the permissions your functions need, then reference its universal identifier.
* Běhový klíč API vložený jako `TWENTY_API_KEY` je odvozen z této výchozí role funkcí.
* Typovaný klient bude omezen oprávněními udělenými této roli.
* Dodržujte princip nejmenších oprávnění: vytvořte vyhrazenou roli pouze s oprávněními, která vaše funkce potřebují, a poté odkazujte na její univerzální identifikátor.
##### Default function role (\*.role.ts)
##### Výchozí role funkce (\*.role.ts)
When you scaffold a new app, the CLI also creates a default role file. Use `defineRole()` to define roles with built-in validation:
Když vygenerujete novou aplikaci, CLI také vytvoří výchozí soubor role. K definování rolí s vestavěnou validací použijte `defineRole()`:
```typescript
// src/app/default-function.role.ts
@@ -429,37 +429,37 @@ export default defineRole({
});
```
The `universalIdentifier` of this role is then referenced in `application.config.ts` as `functionRoleUniversalIdentifier`. In other words:
Na `universalIdentifier` této role se poté odkazuje v `application.config.ts` jako na `functionRoleUniversalIdentifier`. Jinými slovy:
* **\*.role.ts** defines what the default function role can do.
* **application.config.ts** points to that role so your functions inherit its permissions.
* **\*.role.ts** definuje, co může výchozí role funkce dělat.
* **application.config.ts** ukazuje na tuto roli, aby vaše funkce zdědily její oprávnění.
Notes:
Poznámky:
* Start from the scaffolded role, then progressively restrict it following leastprivilege.
* Replace the `objectPermissions` and `fieldPermissions` with the objects/fields your functions need.
* `permissionFlags` control access to platform-level capabilities. Keep them minimal; add only what you need.
* See a working example in the Hello World app: [`packages/twenty-apps/hello-world/src/roles/function-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/hello-world/src/roles/function-role.ts).
* Začněte rolí vytvořenou scaffolderem a postupně ji omezujte podle principu nejmenších oprávnění.
* Nahraďte `objectPermissions` a `fieldPermissions` objekty/poli, která vaše funkce potřebují.
* `permissionFlags` řídí přístup k schopnostem na úrovni platformy. Držte je na minimu; přidávejte pouze to, co potřebujete.
* Podívejte se na funkční příklad v aplikaci Hello World: [`packages/twenty-apps/hello-world/src/roles/function-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/hello-world/src/roles/function-role.ts).
### Serverless function config and entrypoint
### Konfigurace serverless funkcí a vstupní bod
Each function file uses `defineFunction()` to export a configuration with a handler and optional triggers. Use the `*.function.ts` file suffix for automatic detection.
Každý soubor funkce používá `defineFunction()` k exportu konfigurace s obslužnou funkcí (handlerem) a volitelnými spouštěči. Pro automatickou detekci použijte příponu souboru `*.function.ts`.
```typescript
// src/app/createPostCard.function.ts
import { defineFunction } from 'twenty-sdk';
import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload } from 'twenty-sdk';
import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload, RoutePayload } from 'twenty-sdk';
import Twenty, { type Person } from '../../generated';
const handler = async (
params:
| { name?: string }
| RoutePayload
| DatabaseEventPayload<ObjectRecordCreateEvent<Person>>
| CronPayload,
) => {
const client = new Twenty(); // generated typed client
const name = 'name' in params
? params.name ?? process.env.DEFAULT_RECIPIENT_NAME ?? 'Hello world'
const name = 'name' in params.queryStringParameters
? params.queryStringParameters.name ?? process.env.DEFAULT_RECIPIENT_NAME ?? 'Hello world'
: 'Hello world';
const result = await client.mutation({
@@ -502,30 +502,122 @@ export default defineFunction({
});
```
Common trigger types:
Běžné typy spouštěčů:
* **route**: Exposes your function on an HTTP path and method **under the `/s/` endpoint**:
* **route**: Zpřístupní vaši funkci na HTTP cestě a metodě **pod koncovým bodem `/s/`**:
> e.g. `path: '/post-card/create',` -> call on `<APP_URL>/s/post-card/create`
> např. `path: '/post-card/create',` -> volání na `<APP_URL>/s/post-card/create`
* **cron**: Runs your function on a schedule using a CRON expression.
* **databaseEvent**: Runs on workspace object lifecycle events
* **cron**: Spouští vaši funkci podle plánu pomocí výrazu CRON.
* **databaseEvent**: Spouští se při událostech životního cyklu objektů v pracovním prostoru
> e.g. `person.created`
> např. `person.created`
Notes:
Poznámky:
* The `triggers` array is optional. Functions without triggers can be used as utility functions called by other functions.
* You can mix multiple trigger types in a single function.
* Pole `triggers` je volitelné. Funkce bez spouštěčů lze použít jako pomocné funkce volané jinými funkcemi.
* V jedné funkci můžete kombinovat více typů spouštěčů.
You can create new functions in two ways:
### Route trigger payload
* **Scaffolded**: Run `yarn create-entity` and choose the option to add a new function. This generates a starter file with a handler and config.
* **Manual**: Create a new `*.function.ts` file and use `defineFunction()`, following the same pattern.
<Warning>
**Breaking change (v1.16, January 2026):** The route trigger payload format has changed. Prior to v1.16, query parameters, path parameters, and body were sent directly as the payload. Starting with v1.16, they are nested inside a structured `RoutePayload` object.
### Generated typed client
**Before v1.16:**
Run yarn generate to create a local typed client in generated/ based on your workspace schema. Use it in your functions:
```typescript
const handler = async (params) => {
const { param1, param2 } = params; // Direct access
};
```
**After v1.16:**
```typescript
const handler = async (event: RoutePayload) => {
const { param1, param2 } = event.body; // Access via .body
const { queryParam } = event.queryStringParameters;
const { id } = event.pathParameters;
};
```
**To migrate existing functions:** Update your handler to destructure from `event.body`, `event.queryStringParameters`, or `event.pathParameters` instead of directly from the params object.
</Warning>
When a route trigger invokes your function, it receives a `RoutePayload` object that follows the AWS HTTP API v2 format. Import the type from `twenty-sdk`:
```typescript
import { defineFunction, type RoutePayload } from 'twenty-sdk';
const handler = async (event: RoutePayload) => {
// Access request data
const { headers, queryStringParameters, pathParameters, body } = event;
// HTTP method and path are available in requestContext
const { method, path } = event.requestContext.http;
return { message: 'Success' };
};
```
The `RoutePayload` type has the following structure:
| Property | Typ | Popis |
| ---------------------------- | ------------------------------------- | --------------------------------------------------------------------------------------- |
| `headers` | `Record<string, string \| undefined>` | HTTP headers (only those listed in `forwardedRequestHeaders`) |
| `queryStringParameters` | `Record<string, string \| undefined>` | Query string parameters (multiple values joined with commas) |
| `pathParameters` | `Record<string, string \| undefined>` | Path parameters extracted from the route pattern (e.g., `/users/:id` → `{ id: '123' }`) |
| `text zprávy` | `object \| null` | Parsed request body (JSON) |
| `isBase64Encoded` | `booleovská hodnota` | Whether the body is base64 encoded |
| `requestContext.http.method` | `string` | HTTP method (GET, POST, PUT, PATCH, DELETE) |
| `requestContext.http.path` | `string` | Raw request path |
### Forwarding HTTP headers
By default, HTTP headers from incoming requests are **not** passed to your serverless function for security reasons. To access specific headers, explicitly list them in the `forwardedRequestHeaders` array:
```typescript
export default defineFunction({
universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
name: 'webhook-handler',
handler,
triggers: [
{
universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
type: 'route',
path: '/webhook',
httpMethod: 'POST',
isAuthRequired: false,
forwardedRequestHeaders: ['x-webhook-signature', 'content-type'],
},
],
});
```
In your handler, you can then access these headers:
```typescript
const handler = async (event: RoutePayload) => {
const signature = event.headers['x-webhook-signature'];
const contentType = event.headers['content-type'];
// Validate webhook signature...
return { received: true };
};
```
<Note>
Header names are normalized to lowercase. Access them using lowercase keys (for example, `event.headers['content-type']`).
</Note>
Nové funkce můžete vytvářet dvěma způsoby:
* **Vygenerované**: Spusťte `yarn create-entity` a zvolte možnost přidat novou funkci. Tím se vygeneruje startovací soubor s obslužnou funkcí a konfigurací.
* **Ruční**: Vytvořte nový soubor `*.function.ts` a použijte `defineFunction()` podle stejného vzoru.
### Generovaný typovaný klient
Spusťte yarn generate a vytvořte lokální typovaný klient v generated/ na základě schématu vašeho pracovního prostoru. Použijte jej ve svých funkcích:
```typescript
import Twenty from './generated';
@@ -534,34 +626,34 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
The client is re-generated by `yarn generate`. Re-run after changing your objects and `yarn sync` or when onboarding to a new workspace.
Klient je znovu generován příkazem `yarn generate`. Spusťte jej znovu po změně objektů a po `yarn sync`, případně při připojení k novému pracovnímu prostoru.
#### Runtime credentials in serverless functions
#### Běhové přihlašovací údaje v serverless funkcích
When your function runs on Twenty, the platform injects credentials as environment variables before your code executes:
Když vaše funkce běží na Twenty, platforma před spuštěním kódu vloží přihlašovací údaje jako proměnné prostředí:
* `TWENTY_API_URL`: Base URL of the Twenty API your app targets.
* `TWENTY_API_KEY`: Shortlived key scoped to your application's default function role.
* `TWENTY_API_URL`: Základní URL Twenty API, na které vaše aplikace cílí.
* `TWENTY_API_KEY`: Krátkodobý klíč s rozsahem omezeným na výchozí roli funkce vaší aplikace.
Poznámky:
* You do not need to pass URL or API key to the generated client. It reads `TWENTY_API_URL` and `TWENTY_API_KEY` from process.env at runtime.
* The API key's permissions are determined by the role referenced in your `application.config.ts` via `functionRoleUniversalIdentifier`. This is the default role used by serverless functions of your application.
* Applications can define roles to follow leastprivilege. Grant only the permissions your functions need, then point `functionRoleUniversalIdentifier` to that role's universal identifier.
* Není nutné předávat URL ani klíč API vygenerovanému klientovi. Za běhu čte `TWENTY_API_URL` a `TWENTY_API_KEY` z process.env.
* Oprávnění API klíče jsou určena rolí odkazovanou v `application.config.ts` prostřednictvím `functionRoleUniversalIdentifier`. Toto je výchozí role používaná serverless funkcemi vaší aplikace.
* Aplikace mohou definovat role podle principu nejmenších oprávnění. Udělte pouze oprávnění, která vaše funkce potřebují, a poté nastavte `functionRoleUniversalIdentifier` na univerzální identifikátor této role.
### Hello World example
### Příklad Hello World
Explore a minimal, end-to-end example that demonstrates objects, functions, and multiple triggers [here](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world):
Prozkoumejte minimalistický end-to-end příklad, který demonstruje objekty, funkce a více spouštěčů [zde](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world):
## Manual setup (without the scaffolder)
## Ruční nastavení (bez scaffolderu)
While we recommend using `create-twenty-app` for the best getting-started experience, you can also set up a project manually. Do not install the CLI globally. Instead, add `twenty-sdk` as a local dependency and wire scripts in your package.json:
Ačkoli pro nejlepší začátky doporučujeme použít `create-twenty-app`, projekt můžete nastavit i ručně. Neinstalujte CLI globálně. Místo toho přidejte `twenty-sdk` jako lokální závislost a propojte skripty v souboru package.json:
```bash filename="Terminal"
yarn add -D twenty-sdk
```
Then add scripts like these:
Poté přidejte skripty jako tyto:
```json filename="package.json"
{
@@ -578,13 +670,13 @@ Then add scripts like these:
}
```
Now you can run the same commands via Yarn, e.g. `yarn dev`, `yarn sync`, etc.
Nyní můžete spouštět stejné příkazy přes Yarn, např. `yarn dev`, `yarn sync` atd.
## Řešení potíží
* Authentication errors: run `yarn auth` and ensure your API key has the required permissions.
* Cannot connect to server: verify the API URL and that the Twenty server is reachable.
* Types or client missing/outdated: run `yarn generate` and then `yarn dev`.
* Dev mode not syncing: ensure `yarn dev` is running and that changes are not ignored by your environment.
* Chyby ověření: spusťte `yarn auth` a ujistěte se, že váš klíč API má požadovaná oprávnění.
* Nelze se připojit k serveru: ověřte URL API a že je server Twenty dosažitelný.
* Typy nebo klient chybí/jsou zastaralé: spusťte `yarn generate` a poté `yarn dev`.
* Režim vývoje nesynchronizuje: ujistěte se, že běží `yarn dev` a že vaše prostředí změny neignoruje.
Discord Help Channel: https://discord.com/channels/1130383047699738754/1130386664812982322
Kanál podpory na Discordu: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -1,44 +1,44 @@
---
title: Webhooky
description: Receive real-time notifications when events occur in your CRM.
description: Dostávejte oznámení v reálném čase, když ve vašem CRM dojde k událostem.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
Webhooks push data to your systems in real-time when events occur in Twenty — no polling required. Use them to keep external systems in sync, trigger automations, or send alerts.
Webhooky posílají data do vašich systémů v reálném čase, když v Twenty dojde k událostem — bez potřeby průběžného dotazování. Použijte je k udržování externích systémů v synchronizaci, spouštění automatizací nebo zasílání upozornění.
## Vytvořit Webhook
1. Přejděte na **Nastavení → API & Webhooks → Webhooks**
2. Klikněte na **+ Vytvořit webhook**
3. Enter your webhook URL (must be publicly accessible)
3. Zadejte adresu URL svého webhooku (musí být veřejně přístupná)
4. Klikněte na **Uložit**
The webhook activates immediately and starts sending notifications.
Webhook se aktivuje okamžitě a začne odesílat oznámení.
<VimeoEmbed videoId="928786708" title="Creating a webhook" />
<VimeoEmbed videoId="928786708" title="Vytvoření webhooku" />
### Spravovat Webhooky
**Edit**: Click the webhook → Update URL → **Save**
**Upravit**: Klikněte na webhook → Aktualizovat adresu URL → **Uložit**
**Delete**: Click the webhook → **Delete** → Confirm
**Odstranit**: Klikněte na webhook → **Odstranit** → Potvrdit
## Události
Twenty sends webhooks for these event types:
Twenty odesílá webhooky pro tyto typy událostí:
| Událost | Příklad |
| ------------------ | ---------------------------------------------------------- |
| **Record Created** | `person.created`, `company.created`, `note.created` |
| **Record Updated** | `person.updated`, `company.updated`, `opportunity.updated` |
| **Record Deleted** | `person.deleted`, `company.deleted` |
| Událost | Příklad |
| -------------------------- | ---------------------------------------------------------- |
| **Záznam je vytvořen** | `person.created`, `company.created`, `note.created` |
| **Záznam je aktualizován** | `person.updated`, `company.updated`, `opportunity.updated` |
| **Záznam je odstraněn** | `person.deleted`, `company.deleted` |
All event types are sent to your webhook URL. Event filtering may be added in future releases.
Všechny typy událostí jsou odesílány na adresu URL vašeho webhooku. Filtrování událostí může být přidáno v budoucích verzích.
## Payload Format
## Formát payloadu
Each webhook sends an HTTP POST with a JSON body:
Každý webhook odesílá HTTP POST s tělem ve formátu JSON:
```json
{
@@ -55,35 +55,35 @@ Each webhook sends an HTTP POST with a JSON body:
}
```
| Pole | Popis |
| ---------------- | ------------------------------------------------ |
| `událost` | What happened (e.g., `person.created`) |
| `data` | The full record that was created/updated/deleted |
| `časové razítko` | When the event occurred (UTC) |
| Pole | Popis |
| ---------------- | ------------------------------------------------------ |
| `událost` | Co se stalo (např. `person.created`) |
| `data` | Celý záznam, který byl vytvořen/aktualizován/odstraněn |
| `časové razítko` | Kdy k události došlo (UTC) |
<Note>
Respond with a **2xx HTTP status** (200-299) to acknowledge receipt. Non-2xx responses are logged as delivery failures.
Odpovězte se **stavem HTTP 2xx** (200299) pro potvrzení přijetí. Odpovědi mimo 2xx se zaznamenávají jako selhání doručení.
</Note>
## Ověření Webhooku
Twenty signs each webhook request for security. Validate signatures to ensure requests are authentic.
Twenty kvůli bezpečnosti podepisuje každý požadavek webhooku. Ověřujte podpisy, abyste zajistili, že požadavky jsou autentic.
### Headers
### Záhlaví
| Hlavička | Popis |
| ---------------------------- | --------------------- |
| `X-Twenty-Webhook-Signature` | HMAC SHA256 signature |
| `X-Twenty-Webhook-Timestamp` | Request timestamp |
| Hlavička | Popis |
| ---------------------------- | ------------------------ |
| `X-Twenty-Webhook-Signature` | Podpis HMAC SHA256 |
| `X-Twenty-Webhook-Timestamp` | Časové razítko požadavku |
### Validation Steps
### Kroky ověření
1. Get the timestamp from `X-Twenty-Webhook-Timestamp`
2. Create the string: `{timestamp}:{JSON payload}`
3. Compute HMAC SHA256 using your webhook secret
4. Compare with `X-Twenty-Webhook-Signature`
1. Získejte časové razítko z `X-Twenty-Webhook-Timestamp`
2. Vytvořte řetězec: `{timestamp}:{JSON payload}`
3. Vypočítejte HMAC SHA256 pomocí vašeho tajného klíče webhooku
4. Porovnejte s `X-Twenty-Webhook-Signature`
### Example (Node.js)
### Příklad (Node.js)
```javascript
const crypto = require("crypto");
@@ -101,12 +101,12 @@ const expectedSignature = crypto
const isValid = expectedSignature === req.headers["x-twenty-webhook-signature"];
```
## Webhooks vs Workflows
## Webhooky vs. pracovní postupy
| Metoda | Směr | Use Case |
| ---------------------------- | ---- | ---------------------------------------------------------- |
| **Webhooks** | OUT | Automatically notify external systems of any record change |
| **Workflow + HTTP Request** | OUT | Send data out with custom logic (filters, transformations) |
| **Workflow Webhook Trigger** | IN | Receive data into Twenty from external systems |
| Metoda | Směr | Případ použití |
| ----------------------------------------- | ---- | --------------------------------------------------------------- |
| **Webhooky** | OUT | Automaticky informujte externí systémy o jakékoli změně záznamu |
| **Pracovní postup + požadavek HTTP** | OUT | Odesílejte data ven s vlastní logikou (filtry, transformace) |
| **Spouštěč webhooku v pracovním postupu** | IN | Přijímejte data do Twenty z externích systémů |
For receiving external data, see [Set Up a Webhook Trigger](/l/cs/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger).
Pro příjem externích dat viz [Nastavení spouštěče webhooku](/l/cs/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger).
@@ -1,6 +1,6 @@
---
title: Extend
description: Extend Twenty's functionality with APIs, webhooks, and custom apps.
title: Rozšiřte
description: Rozšiřte funkčnost Twenty pomocí rozhraní API, webhooků a vlastních aplikací.
---
<Frame>
@@ -9,26 +9,26 @@ description: Extend Twenty's functionality with APIs, webhooks, and custom apps.
## Přehled
Twenty is designed to be extensible. Use our APIs, webhooks, and app framework to integrate with your existing tools and build custom functionality.
Twenty je navrženo tak, aby bylo rozšiřitelné. Použijte naše rozhraní API, webhooky a aplikační framework k integraci se svými stávajícími nástroji a k vytváření vlastní funkčnosti.
## What You Can Do
## Co můžete dělat
* **APIs**: Query and modify your CRM data programmatically using REST or GraphQL
* **Webhooks**: Receive real-time notifications when events occur in Twenty
* **Apps**: Build custom applications that extend Twenty's capabilities - Coming soon!
* **API**: Programově dotazujte a upravujte svá CRM data pomocí REST nebo GraphQL
* **Webhooky**: Dostávejte oznámení v reálném čase, když v Twenty dojde k událostem
* **Aplikace**: Vytvářejte vlastní aplikace, které rozšiřují možnosti Twenty - Již brzy!
## Getting Started
## Začínáme
<CardGroup cols={2}>
<Card title="API" icon="kód" href="/l/cs/developers/extend/capabilities/apis">
Connect to Twenty programmatically
Programově se připojte k Twenty
</Card>
<Card title="Webhooky" icon="bell" href="/l/cs/developers/extend/capabilities/webhooks">
Get notified of events in real-time
Dostávejte oznámení o událostech v reálném čase
</Card>
<Card title="Apps" icon="puzzle-piece" href="/l/cs/developers/extend/capabilities/apps">
Build customizations as code (Alpha)
<Card title="Aplikace" icon="puzzle-piece" href="/l/cs/developers/extend/capabilities/apps">
Vytvářejte přizpůsobení jako kód (Alpha)
</Card>
</CardGroup>
@@ -1,23 +1,23 @@
---
title: Getting Started
description: Welcome to Twenty Developer Documentation, your resources for extending, self-hosting, and contributing to Twenty.
title: Začínáme
description: Vítejte v dokumentaci pro vývojáře Twenty, která je vaším zdrojem informací pro rozšiřování, vlastní hostování a přispívání do Twenty.
---
import { CardTitle } from "/snippets/card-title.mdx"
<CardGroup cols={3}>
<Card href="/l/cs/developers/extend/extend" img="/images/user-guide/integrations/plug.png">
<CardTitle>Extend</CardTitle>
Build integrations with APIs, webhooks, and custom apps.
<CardTitle>Rozšiřte</CardTitle>
Vytvářejte integrace pomocí API, webhooků a vlastních aplikací.
</Card>
<Card href="/l/cs/developers/self-host/self-host" img="/images/user-guide/what-is-twenty/20.png">
<CardTitle>Self-Host</CardTitle>
Deploy and manage Twenty on your own infrastructure.
<CardTitle>Hostujte sami</CardTitle>
Nasaďte a spravujte Twenty na vlastní infrastruktuře.
</Card>
<Card href="/l/cs/developers/contribute/contribute" img="/images/user-guide/github/github-header.png">
<CardTitle>Contribute</CardTitle>
Join our open-source community and contribute to Twenty.
<CardTitle>Přispějte</CardTitle>
Připojte se k naší open-source komunitě a přispívejte do Twenty.
</Card>
</CardGroup>
@@ -1,9 +1,9 @@
---
title: 1-Click w/ Docker Compose
title: Docker Compose jedním kliknutím
---
<Warning>
Docker containers are for production hosting or self-hosting, for the contribution please check the [Local Setup](/l/cs/developers/contribute/capabilities/local-setup).
Docker kontejnery jsou určeny pro produkční hosting nebo samohostování; pro přispívání si prosím přečtěte [Lokální nastavení](/l/cs/developers/contribute/capabilities/local-setup).
</Warning>
## Přehled
@@ -50,7 +50,7 @@ Postupujte podle těchto kroků pro ruční nastavení.
curl -o .env https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-docker/.env.example
```
2. **Generate Secret Tokens**
2. **Vygenerujte tajné tokeny**
Spusťte následující příkaz k generování jedinečného náhodného řetězce:
@@ -96,7 +96,7 @@ docker compose up -d
Pokud hostujete twentyCRM na svém vlastním počítači, otevřete svůj prohlížeč a přejděte na stránku [http://localhost:3000](http://localhost:3000).
If you host it on a server, check that the server is running and that everything is ok with
Pokud to hostujete na serveru, zkontrolujte, že server běží a že je vše v pořádku s
```bash
curl http://localhost:3000
@@ -183,7 +183,7 @@ Důrazně doporučujeme nastavit Twenty za reverzní proxy se SSL ukončením pr
* **Konfigurace reverzního proxy:**
Ujistěte se, že váš reverzní proxy přesměruje požadavky na správný interní port (výchozí `3000`). Configure SSL termination and any necessary headers.
Ujistěte se, že váš reverzní proxy přesměruje požadavky na správný interní port (výchozí `3000`). Nakonfigurujte terminaci SSL a všechny potřebné hlavičky.
* **Nastavení firewallu:**
@@ -203,50 +203,50 @@ Důrazně doporučujeme nastavit Twenty za reverzní proxy se SSL ukončením pr
Pokud nasazujete do bezstavového prostředí (např. některé cloudové služby), nakonfigurujte externí úložiště pro uchování dat.
## Backup and Restore
## Zálohování a obnovení
Regular backups protect your CRM data from loss.
Pravidelné zálohy chrání vaše data v CRM před ztrátou.
### Create a Database Backup
### Vytvořte zálohu databáze
```bash
docker exec twenty-postgres pg_dump -U postgres twenty > backup_$(date +%Y%m%d).sql
```
### Automate Daily Backups
### Automatizujte denní zálohy
Add to your crontab (`crontab -e`):
Přidejte do svého crontabu (`crontab -e`):
```bash
0 2 * * * docker exec twenty-postgres pg_dump -U postgres twenty > /backups/twenty_$(date +\%Y\%m\%d).sql
```
### Restore from Backup
### Obnovte ze zálohy
1. Stop the application:
1. Zastavte aplikaci:
```bash
docker compose stop twenty-server twenty-front
```
2. Restore the database:
2. Obnovte databázi:
```bash
docker exec -i twenty-postgres psql -U postgres twenty < backup_20240115.sql
```
3. Restart services:
3. Restartujte služby:
```bash
docker compose up -d
```
### Backup Best Practices
### Osvědčené postupy pro zálohování
* **Test restores regularly** — verify backups actually work
* **Store backups off-site** — use cloud storage (S3, GCS, etc.)
* **Encrypt sensitive data** — protect backups with encryption
* **Retain multiple copies** — keep daily, weekly, and monthly backups
* **Pravidelně testujte obnovy** — ověřte, že zálohy skutečně fungují
* **Ukládejte zálohy mimo lokalitu** — použijte cloudové úložiště (S3, GCS, atd.)
* **Šifrujte citlivá data** — chraňte zálohy šifrováním
* **Uchovávejte více kopií** — mějte denní, týdenní a měsíční zálohy
## Řešení potíží
@@ -18,9 +18,9 @@ Twenty nabízí **dvě konfigurační režimy** pro různé potřeby nasazení:
IS_CONFIG_VARIABLES_IN_DB_ENABLED=true # výchozí
```
**Most configuration happens through the UI** after installation:
**Většina konfigurace probíhá prostřednictvím uživatelského rozhraní** po instalaci:
1. Access your Twenty instance (usually `http://localhost:3000`)
1. Přistupte ke své instanci Twenty (obvykle `http://localhost:3000`)
2. Jděte na **Nastavení / Admin panel / Konfigurační proměnné**
3. Nakonfigurujte integrace, e-mail, úložiště a další
4. Změny se projeví okamžitě (u nasazení s více kontejnery do 15 sekund)
@@ -58,63 +58,63 @@ IS_CONFIG_VARIABLES_IN_DB_ENABLED=false
1. Nastavte `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false` ve vašem souboru `.env`
2. Přidejte všechny konfigurační proměnné do souboru `.env`
3. Restartujte kontejnery, aby se změny projevily
4. Admin panel will show current values but cannot modify them
4. Administrační panel zobrazí aktuální hodnoty, ale nemůže je upravovat
## Multi-Workspace Mode
## Režim více pracovních prostorů
By default, Twenty runs in **single-workspace mode** — ideal for most self-hosted deployments where you need one CRM instance for your organization.
Ve výchozím nastavení běží Twenty v **režimu jednoho pracovního prostoru** — ideální pro většinu samostatně hostovaných nasazení, kde potřebujete jednu instanci CRM pro svou organizaci.
### Single-Workspace Mode (Default)
### Režim jednoho pracovního prostoru (výchozí)
```bash
IS_MULTIWORKSPACE_ENABLED=false # default
```
* One workspace per Twenty instance
* First user automatically becomes admin with full privileges (`canImpersonate` and `canAccessFullAdminPanel`)
* New signups are disabled after the first workspace is created
* Simple URL structure: `https://your-domain.com`
* Jeden pracovní prostor na instanci Twenty
* První uživatel se automaticky stává administrátorem s plnými oprávněními (`canImpersonate` a `canAccessFullAdminPanel`)
* Po vytvoření prvního pracovního prostoru jsou nové registrace zakázány.
* Jednoduchá struktura URL: `https://your-domain.com`
### Enabling Multi-Workspace Mode
### Povolení režimu více pracovních prostorů
```bash
IS_MULTIWORKSPACE_ENABLED=true
DEFAULT_SUBDOMAIN=app # default value
```
Enable multi-workspace mode for SaaS-like deployments where multiple independent teams need their own workspaces on the same Twenty instance.
Povolte režim více pracovních prostorů pro nasazení typu SaaS, kde více nezávislých týmů potřebuje své vlastní pracovní prostory na téže instanci Twenty.
**Key differences from single-workspace mode:**
**Klíčové rozdíly oproti režimu jednoho pracovního prostoru:**
* Multiple workspaces can be created on the same instance
* Each workspace gets its own subdomain (e.g., `sales.your-domain.com`, `marketing.your-domain.com`)
* Users sign up and log in at `{DEFAULT_SUBDOMAIN}.your-domain.com` (e.g., `app.your-domain.com`)
* No automatic admin privileges — first user in each workspace is a regular user
* Workspace-specific settings like subdomain and custom domain become available in workspace settings
* Na téže instanci lze vytvářet více pracovních prostorů
* Každý pracovní prostor získá vlastní subdoménu (např. `sales.your-domain.com`, `marketing.your-domain.com`)
* Uživatelé se registrují a přihlašují na `{DEFAULT_SUBDOMAIN}.your-domain.com` (např. `app.your-domain.com`)
* Žádná automatic administrátorská oprávnění — první uživatel v každém pracovním prostoru je běžný uživatel
* Nastavení specifická pro pracovní prostor, jako je subdoména a vlastní doména, se zpřístupní v nastavení pracovního prostoru
<Warning>
**Environment-only setting:** `IS_MULTIWORKSPACE_ENABLED` can only be configured via `.env` file and requires a restart. It cannot be changed through the admin panel.
**Nastavení pouze na úrovni prostředí:** `IS_MULTIWORKSPACE_ENABLED` lze konfigurovat pouze prostřednictvím souboru `.env` a vyžaduje restart. Nelze jej změnit prostřednictvím administračního panelu.
</Warning>
### DNS Configuration for Multi-Workspace
### Konfigurace DNS pro více pracovních prostorů
When using multi-workspace mode, configure your DNS with a wildcard record to allow dynamic subdomain creation:
Při použití režimu více pracovních prostorů nakonfigurujte své DNS pomocí zástupného (wildcard) záznamu, aby bylo možné dynamicky vytvářet subdomény:
```
*.your-domain.com -> your-server-ip
```
This enables automatic subdomain routing for new workspaces without manual DNS configuration.
Tím se umožní automatické směrování subdomén pro nové pracovní prostory bez ruční konfigurace DNS.
### Restricting Workspace Creation
### Omezení vytváření pracovních prostorů
In multi-workspace mode, you may want to limit who can create new workspaces:
V režimu více pracovních prostorů možná budete chtít omezit, kdo může vytvářet nové pracovní prostory:
```bash
IS_WORKSPACE_CREATION_LIMITED_TO_SERVER_ADMINS=true
```
When enabled, only users with `canAccessFullAdminPanel` can create additional workspaces. Users can still create their first workspace during initial signup.
Pokud je povoleno, pouze uživatelé s `canAccessFullAdminPanel` mohou vytvářet další pracovní prostory. Uživatelé si stále mohou při úvodní registraci vytvořit svůj první pracovní prostor.
## Integrace Gmail & Google Kalendář
@@ -133,8 +133,8 @@ When enabled, only users with `canAccessFullAdminPanel` can create additional wo
1. Přejděte na [Pověření](https://console.cloud.google.com/apis/credentials)
2. Vytvořte OAuth 2.0 Client ID
3. Přidejte tyto URI přesměrování:
* `https://{your-domain}/auth/google/redirect` (for SSO)
* `https://{your-domain}/auth/google-apis/get-access-token` (for integrations)
* `https://{your-domain}/auth/google/redirect` (pro SSO)
* `https://{your-domain}/auth/google-apis/get-access-token` (pro integrace)
### Konfigurace v Twenty
@@ -194,7 +194,7 @@ Poznámka: "Mail.ReadWrite" a "Mail.Send" jsou povinné pouze v případě, že
Musíte přidat následující URI přesměrování do vašeho projektu:
* `https://{your-domain}/auth/microsoft/redirect` if you want to use Microsoft SSO
* `https://{your-domain}/auth/microsoft/redirect`, pokud chcete použít Microsoft SSO
* `https://{your-domain}/auth/microsoft-apis/get-access-token`
### Konfigurace v Twenty
@@ -291,3 +291,47 @@ yarn command:prod cron:workflow:automated-cron-trigger
<Warning>
**Režim pouze s prostředím:** Pokud nastavíte `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`, přidejte tyto proměnné do souboru `.env`
</Warning>
## Serverless Functions
Twenty supports serverless functions for workflows and custom logic. The execution environment is configured via the `SERVERLESS_TYPE` environment variable.
<Warning>
**Security Notice:** The local serverless driver (`SERVERLESS_TYPE=LOCAL`) runs code directly on the host in a Node.js process with no sandboxing. It should only be used for trusted code in development. For production deployments handling untrusted code, we highly recommend using `SERVERLESS_TYPE=LAMBDA` or `SERVERLESS_TYPE=DISABLED`.
</Warning>
### Available Drivers
| Driver | Environment Variable | Případ použití | Security Level |
| -------- | -------------------------- | ------------------------------------- | ------------------------------- |
| Disabled | `SERVERLESS_TYPE=DISABLED` | Disable serverless functions entirely | N/A |
| Local | `SERVERLESS_TYPE=LOCAL` | Development and trusted environments | Low (no sandboxing) |
| Lambda | `SERVERLESS_TYPE=LAMBDA` | Production with untrusted code | High (hardware-level isolation) |
### Recommended Configuration
**For development:**
```bash
SERVERLESS_TYPE=LOCAL # default
```
**For production (AWS):**
```bash
SERVERLESS_TYPE=LAMBDA
SERVERLESS_LAMBDA_REGION=us-east-1
SERVERLESS_LAMBDA_ROLE=arn:aws:iam::123456789:role/your-lambda-role
SERVERLESS_LAMBDA_ACCESS_KEY_ID=your-access-key
SERVERLESS_LAMBDA_SECRET_ACCESS_KEY=your-secret-key
```
**To disable serverless functions:**
```bash
SERVERLESS_TYPE=DISABLED
```
<Note>
When using `SERVERLESS_TYPE=DISABLED`, any attempt to execute a serverless function will return an error. This is useful if you want to run Twenty without serverless function capabilities.
</Note>
@@ -4,12 +4,12 @@ title: Řešení potíží
## Řešení potíží
If you encounter any problem while setting up environment for development, upgrading your instance or self-hosting,
here are some solutions for common problems.
Pokud narazíte na jakýkoli problém při nastavování prostředí pro vývoj, při aktualizaci své instance nebo při samostatném hostování,
zde jsou některá řešení běžných problémů.
### Vlastní hosting
#### First install results in `password authentication failed for user "postgres"`
#### První instalace skončí chybou `password authentication failed for user "postgres"`
🚨 **DŮLEŽITÉ: Toto řešení je POUZE pro nové instalace** 🚨
Pokud máte existující instanci Twenty s produkčními daty, **NEPROVÁDĚJTE** tyto kroky, protože trvale smažou vaši databázi!
@@ -28,9 +28,9 @@ docker compose down --volumes
docker compose up -d
```
#### CR line breaks found [Windows]
#### Nalezeny konce řádků CR [Windows]
This is due to the line break characters of Windows and the git configuration. Zkuste spustit:
Je to způsobeno znaky konce řádku ve Windows a konfigurací gitu. Zkuste spustit:
```
git config --global core.autocrlf false
@@ -44,7 +44,7 @@ Během instalace Twenty musíte nastavit svou postgres databázi s správnými s
Pokud se vám podaří spustit toto nastavování, měli byste mít ve své databázi schémata `default` a `metadata`.
Pokud ne, ujistěte se, že na vašem počítači neběží více než jedna instance postgres.
#### Cannot find module 'twenty-emails' or its corresponding type declarations.
#### Nelze najít modul 'twenty-emails' ani jeho odpovídající deklarace typů.
Před spuštěním inicializace databáze musíte sestavit balíček `twenty-emails` s `npx nx run twenty-emails:build`
@@ -54,7 +54,7 @@ Ujistěte se, že v kořenovém adresáři spouštíte `yarn` a poté spusťte `
#### Lint při ukládání nefunguje
Toto by mělo fungovat přímo s nainstalovaným rozšířením eslint. If this doesn't work try adding this to your vscode setting (on the dev container scope):
Toto by mělo fungovat přímo s nainstalovaným rozšířením eslint. Pokud to nefunguje, zkuste přidat toto do svého nastavení vscode (v rozsahu dev containeru):
```
"editor.codeActionsOnSave": {
@@ -68,11 +68,11 @@ Toto by mělo fungovat přímo s nainstalovaným rozšířením eslint. If this
In `packages/twenty-front/.env` uncomment `VITE_DISABLE_TYPESCRIPT_CHECKER=true` and `VITE_DISABLE_ESLINT_CHECKER=true` to disable background checks thus reducing amount of needed RAM.
**If it does not work:**
Run only the services you need, instead of `npx nx start`. Například pokud pracujete na serveru, spusťte pouze `npx nx worker twenty-server`
**Pokud to nefunguje:**
Spusťte pouze služby, které potřebujete, místo `npx nx start`. Například pokud pracujete na serveru, spusťte pouze `npx nx worker twenty-server`
**If it does not work:**
If you tried to run only `npx nx run twenty-server:start` on WSL and it's failing with the below memory error:
**Pokud to nefunguje:**
Pokud jste se pokusili spustit pouze `npx nx run twenty-server:start` na WSL a selhává to s následující chybou paměti:
`FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory`
@@ -83,11 +83,11 @@ Pro obejití proveďte níže uvedený příkaz v terminálu nebo jej přidejte
Příznak --max-old-space-size=8192 nastavuje horní limit 8 GB pro hromadu v Node.js; využití se škáluje s požadavkem aplikace.
Odkaz: https://stackoverflow.com/questions/56982005/where-do-i-set-node-options-max-old-space-size-2048
**If it does not work:**
Investigate which processes are taking you most of your machine RAM. V Twenty jsme si všimli, že některá rozšíření VScode zabírala hodně paměti RAM, takže jsme je dočasně deaktivovali.
**Pokud to nefunguje:**
Analyzujte, které procesy vám zabírají většinu paměti na stroji. V Twenty jsme si všimli, že některá rozšíření VScode zabírala hodně paměti RAM, takže jsme je dočasně deaktivovali.
**If it does not work:**
Restart your machine helps to clean up ghost processes.
**Pokud to nefunguje:**
Restartování počítače pomůže vyčistit zombie procesy.
#### Při běhu `npx nx start` se v protokolech objevují podivné [0] a [1]
@@ -142,7 +142,7 @@ To je očekávané, protože uživatel je neautorizovaný, když je odhlášen,
#### Front-end se nedaří spustit a vrací chybu TS5042: Možnost 'project' nelze kombinovat se zdrojovými soubory na příkazovém řádku
Comment out checker plugin in `packages/twenty-ui/vite-config.ts` like in example below
Zakomentujte plugin checker v `packages/twenty-ui/vite-config.ts` jako v příkladu níže
```
plugins: [
@@ -170,7 +170,7 @@ plugins: [
Spusťte `UPDATE core."user" SET "canAccessFullAdminPanel" = TRUE WHERE email = 'you@yourdomain.com';` v databázovém kontejneru pro získání přístupu k administračnímu panelu.
### 1-click Docker compose
### Docker Compose jedním kliknutím
#### Nelze se přihlásit
@@ -206,9 +206,9 @@ Pokud provozujete Twenty za reverzní proxy a máte problémy s připojením:
Po provedení změn restartujte jak reverzní proxy, tak kontejnery Twenty.
#### Error when uploading an image - permission denied
#### Chyba při nahrávání obrázku - přístup odepřen
Switching the data folder ownership on the host from root to another user and group resolves this problem.
Změna vlastnictví datové složky na hostiteli z uživatele root na jiného uživatele a skupinu tento problém vyřeší.
## Získání pomoci
@@ -216,7 +216,7 @@ Pokud se setkáte s problémy, které tento průvodce nepokrývá:
* Zkontrolujte protokoly:
View container logs for error messages:
Zobrazte protokoly kontejneru kvůli chybovým zprávám:
```bash
docker compose logs
@@ -4,9 +4,9 @@ title: Průvodce upgradem
## Obecné pokyny
**Always make sure to back up your database before starting the upgrade process** by running `docker exec -it {db_container_name_or_id} pg_dumpall -U {postgres_user} > databases_backup.sql`.
**Před zahájením procesu upgradu se vždy ujistěte, že jste zálohovali svou databázi** spuštěním `docker exec -it {db_container_name_or_id} pg_dumpall -U {postgres_user} > databases_backup.sql`.
To restore backup, run `cat databases_backup.sql | docker exec -i {db_container_name_or_id} psql -U {postgres_user}`.
Pro obnovení zálohy spusťte `cat databases_backup.sql | docker exec -i {db_container_name_or_id} psql -U {postgres_user}`.
Pokud jste použili Docker Compose, postupujte takto:
@@ -32,7 +32,7 @@ Ahoj Twenty v1.0! 🎉
Všechny interakce s metadatovým API byly optimalizovány pro lepší výkon, zejména pro manipulaci s metadaty objektů a operace vytváření pracovních prostorů.
We've refactored our caching strategy to prioritize cache hits over database queries when possible, significantly improving the performance of metadata API operations.
Refaktorovali jsme naši strategii mezipaměti tak, aby upřednostňovala, pokud je to možné, zásahy do mezipaměti před databázovými dotazy, což výrazně zlepšilo výkon operací rozhraní API metadat.
Pokud po upgradu narazíte na problémy s výkonem, může být nutné vyprázdnit cache, aby bylo zajištěno její sladění s nejnovějšími změnami. Spusťte tento příkaz v kontejneru twenty-server:
@@ -316,8 +316,8 @@ Příkaz `yarn command:prod upgrade-0.31` se postará o datovou migraci všech p
Upgradujte svou instanci Twenty pro použití v0.30.0 image
**Breaking change**:
To enhance performances, Twenty now requires redis cache to be configured. Aktualizovali jsme náš [docker-compose.yml](https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/docker-compose.yml), aby to odrážel.
**Změna, která způsobí nekompatibilitu**:
Pro zvýšení výkonu nyní vyžaduje Twenty konfiguraci cache Redis. Aktualizovali jsme náš [docker-compose.yml](https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/docker-compose.yml), aby to odrážel.
Ujistěte se, že jste aktualizovali svou konfiguraci a své proměnné prostředí odpovídajícím způsobem:
```
@@ -1,6 +1,6 @@
---
title: Self-Host
description: Deploy and manage Twenty on your own infrastructure.
title: Vlastní hosting
description: Nasaďte a spravujte Twenty na vlastní infrastruktuře.
---
<Frame>
@@ -9,22 +9,22 @@ description: Deploy and manage Twenty on your own infrastructure.
## Přehled
Twenty can be self-hosted on your own infrastructure, giving you full control over your data and deployment.
Twenty můžete samostatně hostovat na vlastní infrastruktuře, což vám dává plnou kontrolu nad daty a nasazením.
## Why Self-Host?
## Proč samohostovat?
* **Data ownership**: Keep all CRM data on your own servers
* **Compliance**: Meet regulatory requirements for data residency
* **Customization**: Full access to modify and extend the platform
* **Vlastnictví dat**: Uchovávejte veškerá data CRM na vlastních serverech
* **Soulad**: Splňte regulační požadavky na umístění dat
* **Přizpůsobení**: Plný přístup k úpravám a rozšiřování platformy
## Getting Started
## Začínáme
<CardGroup cols={2}>
<Card title="Docker Compose" icon="docker" href="/l/cs/developers/self-host/capabilities/docker-compose">
Quick setup with Docker
Rychlé nastavení s Dockerem
</Card>
<Card title="Cloud Providers" icon="cloud" href="/l/cs/developers/self-host/capabilities/cloud-providers">
Deploy on AWS, GCP, or Azure
<Card title="Poskytovatelé cloudu" icon="cloud" href="/l/cs/developers/self-host/capabilities/cloud-providers">
Nasaďte na AWS, GCP nebo Azure
</Card>
</CardGroup>
+37 -37
View File
@@ -1,16 +1,16 @@
{
"tabs": {
"userGuide": {
"label": "User Guide",
"label": "Uživatelská příručka",
"groups": {
"discoverTwenty": {
"label": "Discover Twenty",
"label": "Objevte Twenty",
"groups": {
"gettingStartedCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
},
"gettingStartedHowTos": {
"label": "How-Tos"
"label": "Návody"
}
}
},
@@ -18,32 +18,32 @@
"label": "Datový model",
"groups": {
"dataModelCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
},
"dataModelHowTos": {
"label": "How-Tos"
"label": "Návody"
}
}
},
"dataMigration": {
"label": "Data Migration",
"label": "Migrace dat",
"groups": {
"dataMigrationCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
},
"dataMigrationHowTos": {
"label": "How-Tos"
"label": "Návody"
}
}
},
"calendarEmails": {
"label": "Calendar & Emails",
"label": "Kalendář a e-maily",
"groups": {
"calendarEmailsCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
},
"calendarEmailsHowTos": {
"label": "How-Tos"
"label": "Návody"
}
}
},
@@ -51,19 +51,19 @@
"label": "Pracovní postupy",
"groups": {
"workflowsCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
},
"workflowsHowTos": {
"label": "How-Tos",
"label": "Návody",
"groups": {
"crmAutomations": {
"label": "CRM Automations"
"label": "Automatizace CRM"
},
"connectToOtherTools": {
"label": "Connect to Other Tools"
"label": "Propojení s dalšími nástroji"
},
"advancedConfigurations": {
"label": "Advanced Configurations"
"label": "Pokročilá nastavení"
},
"needMoreHelp": {
"label": "Potřebujete další pomoc"
@@ -76,21 +76,21 @@
"label": "AI",
"groups": {
"aiCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
},
"aiHowTos": {
"label": "How-Tos"
"label": "Návody"
}
}
},
"viewsPipelines": {
"label": "Views & Pipelines",
"label": "Zobrazení a pipeline",
"groups": {
"viewsPipelinesCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
},
"viewsPipelinesHowTos": {
"label": "How-Tos"
"label": "Návody"
}
}
},
@@ -98,21 +98,21 @@
"label": "Panely",
"groups": {
"dashboardsCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
},
"dashboardsHowTos": {
"label": "How-Tos"
"label": "Návody"
}
}
},
"permissionsAccess": {
"label": "Permissions & Access",
"label": "Oprávnění a přístup",
"groups": {
"permissionsAccessCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
},
"permissionsAccessHowTos": {
"label": "How-Tos"
"label": "Návody"
}
}
},
@@ -120,10 +120,10 @@
"label": "Fakturace",
"groups": {
"billingCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
},
"billingHowTos": {
"label": "How-Tos"
"label": "Návody"
}
}
},
@@ -131,10 +131,10 @@
"label": "Nastavení",
"groups": {
"settingsCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
},
"settingsHowTos": {
"label": "How-Tos"
"label": "Návody"
}
}
}
@@ -147,26 +147,26 @@
"label": "Vývojáři"
},
"extend": {
"label": "Extend",
"label": "Rozšíření",
"groups": {
"extendCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
}
}
},
"selfHost": {
"label": "Self-Host",
"label": "Vlastní hosting",
"groups": {
"selfHostCapabilities": {
"label": "Capabilities"
"label": "Možnosti"
}
}
},
"contribute": {
"label": "Contribute",
"label": "Přispět",
"groups": {
"contributeCapabilities": {
"label": "Capabilities",
"label": "Možnosti",
"groups": {
"frontendDevelopment": {
"label": "Vývoj frontendu",
@@ -18,12 +18,12 @@ Krátká zpráva, která zobrazí další informace, když uživatel interaguje
return (
<>
<p id="hoverText" style={{ display: "inline-block" }}>
Customer Insights
Zákaznické přehledy
</p>
<AppTooltip
className
anchorSelect="#hoverText"
content="Explore customer behavior and preferences"
content="Prozkoumejte chování a preference zákazníků"
delayHide={0}
offset={6}
noArrow={false}
@@ -38,17 +38,17 @@ Krátká zpráva, která zobrazí další informace, když uživatel interaguje
</Tab>
<Tab title="Vlastnosti">
| Vlastnosti | Typ | Popis |
| ---------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| className | řetězec | Volitelná CSS třída pro dodatečné stylování. |
| anchorSelect | CSS selektor | Selektor pro kotvu tooltipu (prvek, který spouští tooltip). |
| obsah | textový řetězec | Obsah, který chcete zobrazit v rámci tooltipu. |
| delayHide | číslo | Zpoždění v sekundách před skrytím tooltipu poté, co kurzor opustí kotvu. |
| odsazení | číslo | Odsazení v pixelech pro umístění tooltipu. |
| noArrow | booleovská hodnota | Pokud je `true`, skrývá šipku na tooltipu. |
| isOpen | booleovská hodnota | Pokud je `true`, tooltip je výchozím způsobem otevřen. |
| umístění | řetězec `PlacesType` z `react-tooltipu` | Určuje umístění tooltipu. Hodnoty zahrnují `bottom`, `left`, `right`, `top`, `top-start`, `top-end`, `right-start`, `right-end`, `bottom-start`, `bottom-end`, `left-start`, a `left-end`. |
| positionStrategy | `PositionStrategy` string from `react-tooltip` | Strategie umístění pro tooltip. Má dvě hodnoty: `absolute` a `fixed`. |
| Vlastnosti | Typ | Popis |
| ---------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| className | řetězec | Volitelná CSS třída pro dodatečné stylování. |
| anchorSelect | CSS selektor | Selektor pro kotvu tooltipu (prvek, který spouští tooltip). |
| obsah | textový řetězec | Obsah, který chcete zobrazit v rámci tooltipu. |
| delayHide | číslo | Zpoždění v sekundách před skrytím tooltipu poté, co kurzor opustí kotvu. |
| odsazení | číslo | Odsazení v pixelech pro umístění tooltipu. |
| noArrow | booleovská hodnota | Pokud je `true`, skrývá šipku na tooltipu. |
| isOpen | booleovská hodnota | Pokud je `true`, tooltip je výchozím způsobem otevřen. |
| umístění | řetězec `PlacesType` z `react-tooltipu` | Určuje umístění tooltipu. Hodnoty zahrnují `bottom`, `left`, `right`, `top`, `top-start`, `top-end`, `right-start`, `right-end`, `bottom-start`, `bottom-end`, `left-start`, a `left-end`. |
| positionStrategy | řetězec `PositionStrategy` z `react-tooltipu` | Strategie umístění pro tooltip. Má dvě hodnoty: `absolute` a `fixed`. |
</Tab>
</Tabs>
@@ -63,7 +63,7 @@ Krátká zpráva, která zobrazí další informace, když uživatel interaguje
export const MyComponent = () => {
const crmTaskDescription =
'Follow up with client regarding their recent product inquiry. Discuss pricing options, address any concerns, and provide additional product information. Record the details of the conversation in the CRM for future reference.';
'Kontaktujte klienta ohledně jeho nedávného dotazu na produkt. Proberte cenové možnosti, vyřešte případné obavy a poskytněte další informace o produktu. Zaznamenejte podrobnosti rozhovoru do systému CRM pro budoucí potřebu.';
return <OverflowingTextWithTooltip text={crmTaskDescription} />;
};
@@ -1,5 +1,5 @@
---
title: Checkmark
title: Zaškrtnutí
image: /images/user-guide/tasks/tasks_header.png
---
@@ -25,7 +25,7 @@ Představuje úspěšnou nebo dokončenou akci.
</Tab>
</Tabs>
## Animated Checkmark
## Animované zaškrtnutí
Představuje ikonu zaškrtnutí s přidanou funkcí animace.
@@ -18,7 +18,7 @@ Vizuální prvek, který můžete používat jako kliknutelný nebo nekliknuteln
return (
<Chip
size="large"
label="Clickable Chip"
label="Klikatelný štítek"
clickable={true}
variant="highlighted"
accent="text-primary"
@@ -39,7 +39,7 @@ Vizuální prvek, který můžete používat jako kliknutelný nebo nekliknuteln
| odkazNaEntitu | řetězec | Odkaz na entitu |
| entitaId | řetězec | Jedinečný identifikátor pro entitu |
| název | textový řetězec | Název entity |
| obrázekUrl | řetězec | s picture", |
| obrázekUrl | řetězec | s obrázkem", |
| typAvatara | Typ avatara | Typ avatara, který chcete zobrazit. Má dvě možnosti: `zaoblený` a `hranatý` |
| varianta | `EntityChipVariant` výčet | Varianta čipu entity, kterou chcete zobrazit. Má dvě možnosti: `běžný` a `transparentní` |
| Levá ikona | Ikonová komponenta | React komponenta představující ikonu. Zobrazeno na levé straně čipu |
@@ -57,7 +57,7 @@ export const MyComponent = () => {
return (
<Chip
size="large"
label="Transparent Disabled Chip"
label="Průhledný neaktivní štítek"
clickable={false}
variant="rounded"
accent="text-secondary"
@@ -82,7 +82,7 @@ export const MyComponent = () => {
return (
<Chip
size="large"
label="Disabled chip that triggers a tooltip when overflowing."
label="Neaktivní štítek, který při přetečení zobrazí popisek."
clickable={false}
variant="regular"
accent="text-primary"
@@ -112,7 +112,7 @@ Prvek podobný čipu pro zobrazení informací o entitě.
<Chip
linkToEntity="/entity-link"
entityId="entityTest"
name="Entity name"
name="Název entity"
pictureUrl=""
avatarType="rounded"
variant="regular"
@@ -130,7 +130,7 @@ Prvek podobný čipu pro zobrazení informací o entitě.
| odkazNaEntitu | řetězec | Odkaz na entitu |
| entitaId | řetězec | Jedinečný identifikátor pro entitu |
| název | řetězec | Název entity |
| obrázekUrl | řetězec | s picture", |
| obrázekUrl | řetězec | s obrázkem", |
| typAvatara | Typ avatara | Typ avatara, který chcete zobrazit. Má dvě možnosti: `zaoblený` a `hranatý` |
| varianta | `EntityChipVariant` výčet | Varianta čipu entity, kterou chcete zobrazit. Má dvě možnosti: `běžný` a `transparentní` |
| Levá ikona | Ikonová komponenta | React komponenta představující ikonu. Zobrazeno na levé straně čipu |
@@ -45,11 +45,11 @@ V celé aplikaci používáme ikony Tabler pro React.
</Tab>
</Tabs>
## Custom Icons
## Vlastní ikony
Kromě ikon Tabler aplikace používá také některé vlastní ikony.
### Icon Address Book
### Ikona adresáře
Zobrazí ikonu adresáře.
@@ -1,5 +1,5 @@
---
title: Soon Pill
title: Štítek „Brzy“
image: /images/user-guide/kanban-views/kanban.png
---
@@ -19,7 +19,7 @@ Komponenta pro vizuální kategorizaci nebo označení obsahu.
<Tag
className
color="red"
text="Urgent"
text="Urgent"
onClick={() => console.log("click")}
/>
);
@@ -43,10 +43,10 @@ Rozbalovací výběr ikon, který uživatelům umožňuje vybrat ikonu ze seznam
| --------------- | ------------------ | ------------------------------------------------------------------------------------------------------------- |
| neaktivní | booleovská hodnota | Deaktivuje výběr ikon, pokud je nastavena hodnota `true` |
| onChange | funkce | Vyvolá se funkce zpětného volání, když uživatel vybere ikonu. Přijímá objekt s vlastnostmi `iconKey` a `Icon` |
| selectedIconKey | textový řetězec | The key of the initially selected icon |
| selectedIconKey | textový řetězec | Klíč výchozí vybrané ikony |
| onClickOutside | funkce | Funkce zpětného volání, vyvolaná, když uživatel klikne mimo rozbalovací nabídku. |
| onClose | funkce | Callback function triggered when the dropdown is closed |
| onClose | funkce | Funkce zpětného volání, vyvolaná, když je rozbalovací nabídka zavřena. |
| onOpen | funkce | Funkce zpětného volání, vyvolaná, když je rozbalovací nabídka otevřena. |
| varianta | řetězec | The visual style variant of the clickable icon. Možnosti zahrnují: "primární", "sekundární" a "terciární" |
| varianta | řetězec | Vizuální stylová varianta klikatelné ikony. Možnosti zahrnují: "primární", "sekundární" a "terciární" |
</Tab>
</Tabs>
@@ -27,8 +27,8 @@ Umožňuje uživatelům nahrát a odstranit obrázek.
| onUpload | funkce | Funkce, která se spustí při nahrání nového obrázku uživatelem. Přijímá objekt `File` jako parametr |
| onRemove | funkce | Funkce, která se spustí po kliknutí uživatele na tlačítko odstranění |
| onAbort | funkce | Funkce, která se spustí při kliknutí uživatele na tlačítko přerušení během nahrávání obrázku |
| isUploading | booleovská hodnota | Indicates whether an image is currently being uploaded |
| isUploading | booleovská hodnota | Označuje, zda se obrázek aktuálně nahrává |
| chybová zpráva | řetězec | Volitelná chybová zpráva k zobrazení pod vstupním polem pro obrázek |
| neaktivní | booleovská hodnota | If `true`, the entire input is disabled, and the buttons are not clickable |
| neaktivní | booleovská hodnota | Pokud je `true`, je celý vstup deaktivován a na tlačítka nelze kliknout |
</Tab>
</Tabs>
@@ -24,10 +24,10 @@ Umožňuje uživatelům vybrat hodnotu z nabídky předdefinovaných možností.
<Select
className
disabled={false}
label="Select an option"
label="Vyberte možnost"
options={[
{ value: 'option1', label: 'Option A', Icon: IconTwentyStar },
{ value: 'option2', label: 'Option B', Icon: IconTwentyStar },
{ value: 'option1', label: 'Možnost A', Icon: IconTwentyStar },
{ value: 'option2', label: 'Možnost B', Icon: IconTwentyStar },
]}
value="option1"
/>
@@ -39,13 +39,13 @@ Umožňuje uživatelům vybrat hodnotu z nabídky předdefinovaných možností.
</Tab>
<Tab title="Vlastnosti">
| Vlastnosti | Typ | Popis |
| ---------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| className | řetězec | Volitelná CSS třída pro dodatečné stylování. |
| neaktivní | booleovská hodnota | Pokud je nastaveno na `true`, zakáže interakci uživatele s komponentou. |
| štítek | textový řetězec | Štítek popisující účel komponenty `Vybrat`. |
| onChange | funkce | Funkce volaná při změně vybraných hodnot. |
| možnosti | pole | Represents the options available for the `Selected` component. It's an array of objects where each object has a `value` (the unique identifier), `label` (the unique identifier), and an optional `Icon` |
| hodnota | řetězec | Reprezentuje aktuálně vybranou hodnotu. Měla by odpovídat jedné z `hodnot` v poli `možnosti`. |
| Vlastnosti | Typ | Popis |
| ---------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| className | řetězec | Volitelná CSS třída pro dodatečné stylování. |
| neaktivní | booleovská hodnota | Pokud je nastaveno na `true`, zakáže interakci uživatele s komponentou. |
| štítek | textový řetězec | Štítek popisující účel komponenty `Vybrat`. |
| onChange | funkce | Funkce volaná při změně vybraných hodnot. |
| možnosti | pole | Představuje možnosti dostupné pro komponentu `Selected`. Je to pole objektů, kde každý objekt `value` (jedinečný identifikátor), `label` (jedinečný identifikátor) a volitelný `Icon` |
| hodnota | řetězec | Reprezentuje aktuálně vybranou hodnotu. Měla by odpovídat jedné z `hodnot` v poli `možnosti`. |
</Tab>
</Tabs>

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