Compare commits
104
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22a4bcfd3a | ||
|
|
7ec4508d5f | ||
|
|
a05a9c8f79 | ||
|
|
ce1ffa8550 | ||
|
|
2cc3c75c7e | ||
|
|
9733ff1b8e | ||
|
|
e4075caa65 | ||
|
|
c3781e87cc | ||
|
|
e9b5cb830c | ||
|
|
e40c758aa6 | ||
|
|
53c314d0fa | ||
|
|
618df704e6 | ||
|
|
058489b5cc | ||
|
|
3bd431e95d | ||
|
|
f4a61f26c0 | ||
|
|
8e6b267ff3 | ||
|
|
88146c2170 | ||
|
|
3706da9bcb | ||
|
|
9bac8f15d4 | ||
|
|
7332379d26 | ||
|
|
2455c859b4 | ||
|
|
e3753bf822 | ||
|
|
f3faa11dd2 | ||
|
|
477fbc0865 | ||
|
|
08a3d983cb | ||
|
|
ee15e034b5 | ||
|
|
b7274da8fa | ||
|
|
4a485aecb0 | ||
|
|
5ae1d94f23 | ||
|
|
015ccbf0a7 | ||
|
|
3d362e6e01 | ||
|
|
d7f025157b | ||
|
|
98482f3a01 | ||
|
|
171efe2a19 | ||
|
|
7512b9f9bb | ||
|
|
c0cc0689d6 | ||
|
|
0891886aa0 | ||
|
|
f768bbe512 | ||
|
|
610c0ebc9d | ||
|
|
e4aad7751f | ||
|
|
7c5a13852b | ||
|
|
163c1175cb | ||
|
|
963f2de864 | ||
|
|
e3fcff00b0 | ||
|
|
b4e924b671 | ||
|
|
63a3f93a78 | ||
|
|
8938dd637f | ||
|
|
20977428a1 | ||
|
|
347298902d | ||
|
|
5750c9be0c | ||
|
|
08feb6f651 | ||
|
|
c9c3b2b691 | ||
|
|
09e1684300 | ||
|
|
e80e9a6a25 | ||
|
|
c2fe18af53 | ||
|
|
2b702b2b45 | ||
|
|
dc167b2d3d | ||
|
|
1e6c5b57b2 | ||
|
|
3516be2cf4 | ||
|
|
9477bb3677 | ||
|
|
aac032e517 | ||
|
|
5544b5dcfe | ||
|
|
8244610bdc | ||
|
|
e3db73ef46 | ||
|
|
7523143f12 | ||
|
|
cfc4e0e343 | ||
|
|
c3d565f266 | ||
|
|
2b7b05de2e | ||
|
|
4b3c58e013 | ||
|
|
c775d65952 | ||
|
|
b80146c890 | ||
|
|
5604cdbb4b | ||
|
|
da064d5e88 | ||
|
|
f694bb99b3 | ||
|
|
8190cd5fbf | ||
|
|
b901bdec40 | ||
|
|
b1d3ec665a | ||
|
|
ac3ac5cd4d | ||
|
|
6f251a6f8e | ||
|
|
0876197c8d | ||
|
|
4f903fa0ba | ||
|
|
2072d5f720 | ||
|
|
d54b713264 | ||
|
|
84afbb4d2c | ||
|
|
ebfaff0a53 | ||
|
|
c3d8404112 | ||
|
|
a95a286c59 | ||
|
|
c173f01601 | ||
|
|
cda70a70ca | ||
|
|
a48b69d1e5 | ||
|
|
4817c86bf0 | ||
|
|
0befb021d0 | ||
|
|
e7b3f65c0c | ||
|
|
5184491c59 | ||
|
|
f17cc4d190 | ||
|
|
463ce43442 | ||
|
|
5cc0c03262 | ||
|
|
e2b9bc935f | ||
|
|
b7c1d47273 | ||
|
|
befbcef824 | ||
|
|
83b800a077 | ||
|
|
d08c098065 | ||
|
|
d88fa0cb2b | ||
|
|
216a7331f8 |
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,393 @@
|
||||
---
|
||||
name: syncable-entity-builder-and-validation
|
||||
description: Create validation logic and migration action builders for syncable entities in Twenty. Use when implementing business rule validation, uniqueness checks, foreign key validation, or building workspace migration actions for syncable entities. Validators never throw and never mutate.
|
||||
---
|
||||
|
||||
# Syncable Entity: Builder & Validation (Step 3/6)
|
||||
|
||||
**Purpose**: Implement business rule validation and create migration action builders.
|
||||
|
||||
**When to use**: After completing Steps 1-2 (Types, Cache, Transform). Required before implementing action handlers.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
This step creates:
|
||||
1. Validator service (business logic validation)
|
||||
2. Builder service (action creation)
|
||||
3. Orchestrator wiring (**CRITICAL** - often forgotten!)
|
||||
|
||||
**Key principles**:
|
||||
- Validators **never throw** - return error arrays
|
||||
- Validators **never mutate** - pass optimistic entity maps
|
||||
- Use indexed lookups (O(1)) not `Object.values().find()` (O(n))
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Create Validator Service
|
||||
|
||||
**File**: `src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-my-entity-validator.service.ts`
|
||||
|
||||
```typescript
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { t, msg } from '@lingui/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatMyEntity } from 'src/engine/metadata-modules/flat-my-entity/types/flat-my-entity.type';
|
||||
import { type FlatMyEntityMaps } from 'src/engine/metadata-modules/flat-my-entity/types/flat-my-entity-maps.type';
|
||||
import { WorkspaceMigrationValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/types/workspace-migration-validation-error.type';
|
||||
import { MyEntityExceptionCode } from 'src/engine/metadata-modules/my-entity/exceptions/my-entity-exception-code.enum';
|
||||
|
||||
@Injectable()
|
||||
export class FlatMyEntityValidatorService {
|
||||
validateMyEntityForCreate(
|
||||
flatMyEntity: FlatMyEntity,
|
||||
optimisticFlatMyEntityMaps: FlatMyEntityMaps,
|
||||
): WorkspaceMigrationValidationError[] {
|
||||
const errors: WorkspaceMigrationValidationError[] = [];
|
||||
|
||||
// Pattern 1: Required field validation
|
||||
if (!isDefined(flatMyEntity.name) || flatMyEntity.name.trim() === '') {
|
||||
errors.push({
|
||||
code: MyEntityExceptionCode.NAME_REQUIRED,
|
||||
message: t`Name is required`,
|
||||
userFriendlyMessage: msg`Please provide a name for this entity`,
|
||||
});
|
||||
}
|
||||
|
||||
// Pattern 2: Uniqueness check - use indexed map (O(1))
|
||||
const existingEntityWithName = optimisticFlatMyEntityMaps.byName[flatMyEntity.name];
|
||||
|
||||
if (isDefined(existingEntityWithName) && existingEntityWithName.id !== flatMyEntity.id) {
|
||||
errors.push({
|
||||
code: MyEntityExceptionCode.MY_ENTITY_ALREADY_EXISTS,
|
||||
message: t`Entity with name ${flatMyEntity.name} already exists`,
|
||||
userFriendlyMessage: msg`An entity with this name already exists`,
|
||||
});
|
||||
}
|
||||
|
||||
// Pattern 3: Foreign key validation
|
||||
if (isDefined(flatMyEntity.parentEntityId)) {
|
||||
const parentEntity = optimisticFlatParentEntityMaps.byId[flatMyEntity.parentEntityId];
|
||||
|
||||
if (!isDefined(parentEntity)) {
|
||||
errors.push({
|
||||
code: MyEntityExceptionCode.PARENT_ENTITY_NOT_FOUND,
|
||||
message: t`Parent entity with ID ${flatMyEntity.parentEntityId} not found`,
|
||||
userFriendlyMessage: msg`The specified parent entity does not exist`,
|
||||
});
|
||||
} else if (isDefined(parentEntity.deletedAt)) {
|
||||
errors.push({
|
||||
code: MyEntityExceptionCode.PARENT_ENTITY_DELETED,
|
||||
message: t`Parent entity is deleted`,
|
||||
userFriendlyMessage: msg`Cannot reference a deleted parent entity`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Pattern 4: Standard entity protection
|
||||
if (flatMyEntity.isCustom === false) {
|
||||
errors.push({
|
||||
code: MyEntityExceptionCode.STANDARD_ENTITY_CANNOT_BE_CREATED,
|
||||
message: t`Cannot create standard entity`,
|
||||
userFriendlyMessage: msg`Standard entities can only be created by the system`,
|
||||
});
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
validateMyEntityForUpdate(
|
||||
flatMyEntity: FlatMyEntity,
|
||||
updates: Partial<FlatMyEntity>,
|
||||
optimisticFlatMyEntityMaps: FlatMyEntityMaps,
|
||||
): WorkspaceMigrationValidationError[] {
|
||||
const errors: WorkspaceMigrationValidationError[] = [];
|
||||
|
||||
// Standard entity protection
|
||||
if (flatMyEntity.isCustom === false) {
|
||||
errors.push({
|
||||
code: MyEntityExceptionCode.STANDARD_ENTITY_CANNOT_BE_UPDATED,
|
||||
message: t`Cannot update standard entity`,
|
||||
userFriendlyMessage: msg`Standard entities cannot be modified`,
|
||||
});
|
||||
return errors; // Early return if standard
|
||||
}
|
||||
|
||||
// Uniqueness check for name changes
|
||||
if (isDefined(updates.name) && updates.name !== flatMyEntity.name) {
|
||||
const existingEntityWithName = optimisticFlatMyEntityMaps.byName[updates.name];
|
||||
|
||||
if (isDefined(existingEntityWithName) && existingEntityWithName.id !== flatMyEntity.id) {
|
||||
errors.push({
|
||||
code: MyEntityExceptionCode.MY_ENTITY_ALREADY_EXISTS,
|
||||
message: t`Entity with name ${updates.name} already exists`,
|
||||
userFriendlyMessage: msg`An entity with this name already exists`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
validateMyEntityForDelete(
|
||||
flatMyEntity: FlatMyEntity,
|
||||
): WorkspaceMigrationValidationError[] {
|
||||
const errors: WorkspaceMigrationValidationError[] = [];
|
||||
|
||||
// Standard entity protection
|
||||
if (flatMyEntity.isCustom === false) {
|
||||
errors.push({
|
||||
code: MyEntityExceptionCode.STANDARD_ENTITY_CANNOT_BE_DELETED,
|
||||
message: t`Cannot delete standard entity`,
|
||||
userFriendlyMessage: msg`Standard entities cannot be deleted`,
|
||||
});
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Performance warning**: Avoid `Object.values().find()` - use indexed maps instead!
|
||||
|
||||
```typescript
|
||||
// ❌ BAD: O(n) - slow for large datasets
|
||||
const duplicate = Object.values(optimisticFlatMyEntityMaps.byId).find(
|
||||
(entity) => entity.name === flatMyEntity.name && entity.id !== flatMyEntity.id
|
||||
);
|
||||
|
||||
// ✅ GOOD: O(1) - use indexed map
|
||||
const existingEntityWithName = optimisticFlatMyEntityMaps.byName[flatMyEntity.name];
|
||||
if (isDefined(existingEntityWithName) && existingEntityWithName.id !== flatMyEntity.id) {
|
||||
// Handle duplicate
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Create Builder Service
|
||||
|
||||
**File**: `src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/my-entity/workspace-migration-my-entity-actions-builder.service.ts`
|
||||
|
||||
```typescript
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/workspace-entity-migration-builder.service';
|
||||
import { FlatMyEntityValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-my-entity-validator.service';
|
||||
import { type UniversalFlatMyEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-my-entity.type';
|
||||
import {
|
||||
type UniversalCreateMyEntityAction,
|
||||
type UniversalUpdateMyEntityAction,
|
||||
type UniversalDeleteMyEntityAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/my-entity/types/workspace-migration-my-entity-action.type';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationMyEntityActionsBuilderService extends WorkspaceEntityMigrationBuilderService<
|
||||
'myEntity',
|
||||
UniversalFlatMyEntity,
|
||||
UniversalCreateMyEntityAction,
|
||||
UniversalUpdateMyEntityAction,
|
||||
UniversalDeleteMyEntityAction
|
||||
> {
|
||||
constructor(
|
||||
private readonly flatMyEntityValidatorService: FlatMyEntityValidatorService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected buildCreateAction(
|
||||
universalFlatMyEntity: UniversalFlatMyEntity,
|
||||
flatEntityMaps: AllFlatEntityMapsByMetadataName,
|
||||
): BuildWorkspaceMigrationActionReturnType<UniversalCreateMyEntityAction> {
|
||||
const validationResult = this.flatMyEntityValidatorService.validateMyEntityForCreate(
|
||||
universalFlatMyEntity,
|
||||
flatEntityMaps.flatMyEntityMaps,
|
||||
);
|
||||
|
||||
if (validationResult.length > 0) {
|
||||
return {
|
||||
status: 'failed',
|
||||
errors: validationResult,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
action: {
|
||||
type: 'create',
|
||||
metadataName: 'myEntity',
|
||||
universalFlatEntity: universalFlatMyEntity,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected buildUpdateAction(
|
||||
universalFlatMyEntity: UniversalFlatMyEntity,
|
||||
universalUpdates: Partial<UniversalFlatMyEntity>,
|
||||
flatEntityMaps: AllFlatEntityMapsByMetadataName,
|
||||
): BuildWorkspaceMigrationActionReturnType<UniversalUpdateMyEntityAction> {
|
||||
const validationResult = this.flatMyEntityValidatorService.validateMyEntityForUpdate(
|
||||
universalFlatMyEntity,
|
||||
universalUpdates,
|
||||
flatEntityMaps.flatMyEntityMaps,
|
||||
);
|
||||
|
||||
if (validationResult.length > 0) {
|
||||
return {
|
||||
status: 'failed',
|
||||
errors: validationResult,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
action: {
|
||||
type: 'update',
|
||||
metadataName: 'myEntity',
|
||||
universalFlatEntity: universalFlatMyEntity,
|
||||
universalUpdates,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected buildDeleteAction(
|
||||
universalFlatMyEntity: UniversalFlatMyEntity,
|
||||
): BuildWorkspaceMigrationActionReturnType<UniversalDeleteMyEntityAction> {
|
||||
const validationResult = this.flatMyEntityValidatorService.validateMyEntityForDelete(
|
||||
universalFlatMyEntity,
|
||||
);
|
||||
|
||||
if (validationResult.length > 0) {
|
||||
return {
|
||||
status: 'failed',
|
||||
errors: validationResult,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
action: {
|
||||
type: 'delete',
|
||||
metadataName: 'myEntity',
|
||||
universalFlatEntity: universalFlatMyEntity,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Wire into Orchestrator (**CRITICAL**)
|
||||
|
||||
**File**: `src/engine/workspace-manager/workspace-migration/workspace-migration-builder/workspace-migration-build-orchestrator.service.ts`
|
||||
|
||||
```typescript
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationBuildOrchestratorService {
|
||||
constructor(
|
||||
// ... existing builders
|
||||
private readonly workspaceMigrationMyEntityActionsBuilderService: WorkspaceMigrationMyEntityActionsBuilderService,
|
||||
) {}
|
||||
|
||||
async buildWorkspaceMigration({
|
||||
allFlatEntityOperationByMetadataName,
|
||||
flatEntityMaps,
|
||||
isSystemBuild,
|
||||
}: BuildWorkspaceMigrationInput): Promise<BuildWorkspaceMigrationOutput> {
|
||||
// ... existing code
|
||||
|
||||
// Add your entity builder
|
||||
const myEntityResult = await this.workspaceMigrationMyEntityActionsBuilderService.build({
|
||||
flatEntitiesToCreate: allFlatEntityOperationByMetadataName.myEntity?.flatEntityToCreate ?? [],
|
||||
flatEntitiesToUpdate: allFlatEntityOperationByMetadataName.myEntity?.flatEntityToUpdate ?? [],
|
||||
flatEntitiesToDelete: allFlatEntityOperationByMetadataName.myEntity?.flatEntityToDelete ?? [],
|
||||
flatEntityMaps,
|
||||
isSystemBuild,
|
||||
});
|
||||
|
||||
// ... aggregate errors
|
||||
|
||||
return {
|
||||
status: aggregatedErrors.length > 0 ? 'failed' : 'success',
|
||||
errors: aggregatedErrors,
|
||||
actions: [
|
||||
...existingActions,
|
||||
...myEntityResult.actions,
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**⚠️ This step is the most commonly forgotten!** Your entity won't sync without orchestrator wiring.
|
||||
|
||||
---
|
||||
|
||||
## Validation Patterns
|
||||
|
||||
### Pattern 1: Required Field
|
||||
```typescript
|
||||
if (!isDefined(field) || field.trim() === '') {
|
||||
errors.push({ code: ..., message: ..., userFriendlyMessage: ... });
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 2: Uniqueness (O(1) lookup)
|
||||
```typescript
|
||||
const existing = optimisticMaps.byName[entity.name];
|
||||
if (isDefined(existing) && existing.id !== entity.id) {
|
||||
errors.push({ ... });
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 3: Foreign Key Validation
|
||||
```typescript
|
||||
if (isDefined(entity.parentId)) {
|
||||
const parent = parentMaps.byId[entity.parentId];
|
||||
if (!isDefined(parent)) {
|
||||
errors.push({ code: NOT_FOUND, ... });
|
||||
} else if (isDefined(parent.deletedAt)) {
|
||||
errors.push({ code: DELETED, ... });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 4: Standard Entity Protection
|
||||
```typescript
|
||||
if (entity.isCustom === false) {
|
||||
errors.push({ code: STANDARD_ENTITY_PROTECTED, ... });
|
||||
return errors; // Early return
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
Before moving to Step 4:
|
||||
|
||||
- [ ] Validator service created
|
||||
- [ ] Validator **never throws** (returns error arrays)
|
||||
- [ ] Validator **never mutates** (uses optimistic maps)
|
||||
- [ ] All uniqueness checks use indexed maps (O(1))
|
||||
- [ ] Required field validation implemented
|
||||
- [ ] Foreign key validation implemented
|
||||
- [ ] Standard entity protection implemented
|
||||
- [ ] Builder service extends `WorkspaceEntityMigrationBuilderService`
|
||||
- [ ] Builder creates actions with universal entities
|
||||
- [ ] **Builder wired into orchestrator** (**CRITICAL**)
|
||||
- [ ] **Builder injected in orchestrator constructor**
|
||||
- [ ] **Builder called in `buildWorkspaceMigration`**
|
||||
- [ ] **Actions added to orchestrator return statement**
|
||||
|
||||
---
|
||||
|
||||
## Next Step
|
||||
|
||||
Once builder and validation are complete, proceed to:
|
||||
**[Syncable Entity: Runner & Actions (Step 4/6)](../syncable-entity-runner-and-actions/SKILL.md)**
|
||||
|
||||
For complete workflow, see `@creating-syncable-entity` rule.
|
||||
@@ -0,0 +1,303 @@
|
||||
---
|
||||
name: syncable-entity-cache-and-transform
|
||||
description: Create cache services and transformation utilities for syncable entities in Twenty. Use when implementing entity-to-flat conversions, input DTO transpilation to universal flat entities, or cache recomputation for syncable entities.
|
||||
---
|
||||
|
||||
# Syncable Entity: Cache & Transform (Step 2/6)
|
||||
|
||||
**Purpose**: Create cache layer and transformation utilities to convert between different entity representations.
|
||||
|
||||
**When to use**: After completing Step 1 (Types & Constants). Required before building validators and action handlers.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
This step creates:
|
||||
1. Cache service for flat entity maps
|
||||
2. Entity-to-flat conversion utility
|
||||
3. Input transform utils (DTO → Universal Flat Entity)
|
||||
|
||||
**Key principle**: Input transform utils must output **universal flat entities** (with `universalIdentifier` and foreign keys mapped to universal identifiers).
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Create Cache Service
|
||||
|
||||
**File**: `src/engine/metadata-modules/flat-my-entity/services/flat-my-entity-cache.service.ts`
|
||||
|
||||
```typescript
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { WorkspaceCache } from 'src/engine/twenty-orm/decorators/workspace-cache.decorator';
|
||||
import { MyEntityEntity } from 'src/engine/metadata-modules/my-entity/entities/my-entity.entity';
|
||||
import { type FlatMyEntityMaps } from 'src/engine/metadata-modules/flat-my-entity/types/flat-my-entity-maps.type';
|
||||
import { fromMyEntityEntityToFlatMyEntity } from 'src/engine/metadata-modules/flat-my-entity/utils/from-my-entity-entity-to-flat-my-entity.util';
|
||||
|
||||
@Injectable()
|
||||
export class FlatMyEntityCacheService {
|
||||
constructor(
|
||||
@InjectRepository(MyEntityEntity, 'metadata')
|
||||
private readonly myEntityRepository: Repository<MyEntityEntity>,
|
||||
) {}
|
||||
|
||||
@WorkspaceCache({ flatMapsKey: 'flatMyEntityMaps' })
|
||||
async getFlatMyEntityMaps(): Promise<FlatMyEntityMaps> {
|
||||
const myEntities = await this.myEntityRepository.find({
|
||||
withDeleted: true, // CRITICAL: Include soft-deleted entities
|
||||
});
|
||||
|
||||
const flatMyEntities = myEntities.map((entity) =>
|
||||
fromMyEntityEntityToFlatMyEntity(entity),
|
||||
);
|
||||
|
||||
return {
|
||||
byId: Object.fromEntries(flatMyEntities.map((e) => [e.id, e])),
|
||||
byName: Object.fromEntries(flatMyEntities.map((e) => [e.name, e])),
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Critical rules**:
|
||||
- Use `@WorkspaceCache` decorator with unique `flatMapsKey`
|
||||
- **Always** use `withDeleted: true` to include soft-deleted entities
|
||||
- Cache key pattern: `flat{EntityName}Maps` (camelCase)
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Entity-to-Flat Conversion
|
||||
|
||||
**File**: `src/engine/metadata-modules/flat-my-entity/utils/from-my-entity-entity-to-flat-my-entity.util.ts`
|
||||
|
||||
```typescript
|
||||
import { v4 } from 'uuid';
|
||||
import { type MyEntityEntity } from 'src/engine/metadata-modules/my-entity/entities/my-entity.entity';
|
||||
import { type FlatMyEntity } from 'src/engine/metadata-modules/flat-my-entity/types/flat-my-entity.type';
|
||||
|
||||
export const fromMyEntityEntityToFlatMyEntity = (
|
||||
entity: MyEntityEntity,
|
||||
): FlatMyEntity => {
|
||||
return {
|
||||
id: entity.id,
|
||||
// Critical: generate a new UUID for universalIdentifier
|
||||
universalIdentifier: v4(),
|
||||
workspaceId: entity.workspaceId,
|
||||
applicationId: entity.applicationId,
|
||||
name: entity.name,
|
||||
label: entity.label,
|
||||
description: entity.description,
|
||||
isCustom: entity.isCustom,
|
||||
parentEntityId: entity.parentEntityId,
|
||||
settings: entity.settings,
|
||||
createdAt: entity.createdAt.toISOString(),
|
||||
updatedAt: entity.updatedAt.toISOString(),
|
||||
deletedAt: entity.deletedAt?.toISOString() ?? null,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
**Critical**: `universalIdentifier` must be a new UUID generated with `v4()` (not `entity.id`)
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Input Transform Utils (DTO → Universal Flat Entity)
|
||||
|
||||
**File**: `src/engine/metadata-modules/flat-my-entity/utils/from-create-my-entity-input-to-universal-flat-my-entity.util.ts`
|
||||
|
||||
```typescript
|
||||
import { v4 } from 'uuid';
|
||||
import { sanitizeString } from 'twenty-shared/string';
|
||||
import { type CreateMyEntityInput } from 'src/engine/metadata-modules/my-entity/dtos/create-my-entity.input';
|
||||
import { type UniversalFlatMyEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-my-entity.type';
|
||||
import { resolveEntityRelationUniversalIdentifiers } from 'src/engine/metadata-modules/flat-entity/utils/resolve-entity-relation-universal-identifiers.util';
|
||||
import { type AllFlatEntityMapsByMetadataName } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps-by-metadata-name.type';
|
||||
|
||||
export const fromCreateMyEntityInputToUniversalFlatMyEntity = ({
|
||||
input,
|
||||
workspaceId,
|
||||
flatEntityMaps,
|
||||
}: {
|
||||
input: CreateMyEntityInput;
|
||||
workspaceId: string;
|
||||
flatEntityMaps?: AllFlatEntityMapsByMetadataName;
|
||||
}): UniversalFlatMyEntity => {
|
||||
const id = v4();
|
||||
const universalIdentifier = v4();
|
||||
|
||||
// 1. Extract foreign key IDs BEFORE sanitization
|
||||
const parentEntityId = input.parentEntityId ?? null;
|
||||
|
||||
// 2. Sanitize string properties
|
||||
const name = sanitizeString(input.name);
|
||||
const label = sanitizeString(input.label);
|
||||
const description = input.description ? sanitizeString(input.description) : null;
|
||||
|
||||
// 3. Build base flat entity
|
||||
const baseFlatEntity = {
|
||||
id,
|
||||
universalIdentifier,
|
||||
workspaceId,
|
||||
applicationId: null,
|
||||
name,
|
||||
label,
|
||||
description,
|
||||
isCustom: true,
|
||||
parentEntityId,
|
||||
settings: input.settings ?? null,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
deletedAt: null,
|
||||
};
|
||||
|
||||
// 4. Resolve foreign keys to universal identifiers (if flatEntityMaps provided)
|
||||
if (flatEntityMaps) {
|
||||
return resolveEntityRelationUniversalIdentifiers({
|
||||
metadataName: 'myEntity',
|
||||
flatEntity: baseFlatEntity,
|
||||
flatEntityMaps,
|
||||
});
|
||||
}
|
||||
|
||||
// 5. Return with null universal foreign keys if no maps
|
||||
return {
|
||||
...baseFlatEntity,
|
||||
parentEntityUniversalIdentifier: null,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
**Key steps**:
|
||||
1. Generate IDs (`id` and `universalIdentifier` with `v4()`)
|
||||
2. Extract foreign keys **before** sanitization
|
||||
3. Sanitize all string properties
|
||||
4. Build base flat entity
|
||||
5. Resolve foreign keys → universal identifiers
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Create Flat Entity Module
|
||||
|
||||
**File**: `src/engine/metadata-modules/flat-my-entity/flat-my-entity.module.ts`
|
||||
|
||||
```typescript
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { MyEntityEntity } from 'src/engine/metadata-modules/my-entity/entities/my-entity.entity';
|
||||
import { FlatMyEntityCacheService } from 'src/engine/metadata-modules/flat-my-entity/services/flat-my-entity-cache.service';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([MyEntityEntity], 'metadata')],
|
||||
providers: [FlatMyEntityCacheService],
|
||||
exports: [FlatMyEntityCacheService],
|
||||
})
|
||||
export class FlatMyEntityModule {}
|
||||
```
|
||||
|
||||
**Rules**:
|
||||
- Import entity with `'metadata'` datasource
|
||||
- Export cache service for use in other modules
|
||||
|
||||
---
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Pattern: Foreign Key Resolution
|
||||
|
||||
```typescript
|
||||
// Extract foreign keys BEFORE sanitization
|
||||
const parentEntityId = input.parentEntityId ?? null;
|
||||
|
||||
// After building base entity, resolve to universal identifiers
|
||||
const universalFlatEntity = resolveEntityRelationUniversalIdentifiers({
|
||||
metadataName: 'myEntity',
|
||||
flatEntity: baseFlatEntity,
|
||||
flatEntityMaps,
|
||||
});
|
||||
```
|
||||
|
||||
### Pattern: JSONB with SerializedRelation
|
||||
|
||||
```typescript
|
||||
// For JSONB properties containing foreign keys
|
||||
const settings = input.settings
|
||||
? {
|
||||
...input.settings,
|
||||
fieldMetadataId: input.settings.fieldMetadataId,
|
||||
}
|
||||
: null;
|
||||
|
||||
// After resolution, JSONB foreign keys become universal identifiers
|
||||
return resolveEntityRelationUniversalIdentifiers({
|
||||
metadataName: 'myEntity',
|
||||
flatEntity: { ...baseFlatEntity, settings },
|
||||
flatEntityMaps,
|
||||
});
|
||||
```
|
||||
|
||||
### Pattern: Update Transform
|
||||
|
||||
```typescript
|
||||
// from-update-my-entity-input-to-universal-flat-my-entity-updates.util.ts
|
||||
export const fromUpdateMyEntityInputToUniversalFlatMyEntityUpdates = ({
|
||||
input,
|
||||
flatEntityMaps,
|
||||
}: {
|
||||
input: UpdateMyEntityInput;
|
||||
flatEntityMaps?: AllFlatEntityMapsByMetadataName;
|
||||
}): Partial<UniversalFlatMyEntity> => {
|
||||
const updates: Partial<UniversalFlatMyEntity> = {};
|
||||
|
||||
if (input.name !== undefined) {
|
||||
updates.name = sanitizeString(input.name);
|
||||
}
|
||||
|
||||
if (input.parentEntityId !== undefined) {
|
||||
updates.parentEntityId = input.parentEntityId;
|
||||
}
|
||||
|
||||
updates.updatedAt = new Date().toISOString();
|
||||
|
||||
// Resolve foreign keys if maps provided
|
||||
if (flatEntityMaps) {
|
||||
return resolveEntityRelationUniversalIdentifiers({
|
||||
metadataName: 'myEntity',
|
||||
flatEntity: updates as any,
|
||||
flatEntityMaps,
|
||||
});
|
||||
}
|
||||
|
||||
return updates;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
Before moving to Step 3:
|
||||
|
||||
- [ ] Cache service created with `@WorkspaceCache` decorator
|
||||
- [ ] Cache uses `withDeleted: true`
|
||||
- [ ] Cache key follows `flat{EntityName}Maps` pattern
|
||||
- [ ] Entity-to-flat conversion implemented
|
||||
- [ ] `universalIdentifier` set correctly (generated with `v4()`)
|
||||
- [ ] Create input transform implemented
|
||||
- [ ] Update input transform implemented (if needed)
|
||||
- [ ] Foreign keys extracted before sanitization
|
||||
- [ ] String properties sanitized
|
||||
- [ ] Foreign keys resolved to universal identifiers
|
||||
- [ ] Flat entity module created and exports cache service
|
||||
|
||||
---
|
||||
|
||||
## Next Step
|
||||
|
||||
Once cache and transform utilities are complete, proceed to:
|
||||
**[Syncable Entity: Builder & Validation (Step 3/6)](../syncable-entity-builder-and-validation/SKILL.md)**
|
||||
|
||||
For complete workflow, see `@creating-syncable-entity` rule.
|
||||
@@ -0,0 +1,326 @@
|
||||
---
|
||||
name: syncable-entity-integration
|
||||
description: Wire syncable entity services into NestJS modules, create service layer and resolvers for Twenty entities. Use when registering builders, validators, and action handlers in modules, creating business services, or exposing entities via GraphQL API with proper exception handling.
|
||||
---
|
||||
|
||||
# Syncable Entity: Integration (Step 5/6)
|
||||
|
||||
**Purpose**: Wire everything together, register in modules, create services and resolvers.
|
||||
|
||||
**When to use**: After completing Steps 1-4 (all previous steps). Required before testing.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
This step:
|
||||
1. Registers services in 3 NestJS modules
|
||||
2. Creates service layer (returns flat entities)
|
||||
3. Creates resolver layer (converts flat → DTO)
|
||||
4. Uses exception interceptor for GraphQL
|
||||
|
||||
**Key principle**: Services return flat entities, resolvers transpile flat → DTO.
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Register in Builder Module
|
||||
|
||||
**File**: `src/engine/workspace-manager/workspace-migration/workspace-migration-builder/workspace-migration-builder.module.ts`
|
||||
|
||||
```typescript
|
||||
import { WorkspaceMigrationMyEntityActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/my-entity/workspace-migration-my-entity-actions-builder.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
// ... existing imports
|
||||
],
|
||||
providers: [
|
||||
// ... existing providers
|
||||
WorkspaceMigrationMyEntityActionsBuilderService,
|
||||
],
|
||||
exports: [
|
||||
// ... existing exports
|
||||
WorkspaceMigrationMyEntityActionsBuilderService,
|
||||
],
|
||||
})
|
||||
export class WorkspaceMigrationBuilderModule {}
|
||||
```
|
||||
|
||||
**Important**: Add to both `providers` AND `exports` (builder needs to be exported for orchestrator).
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Register in Validators Module
|
||||
|
||||
**File**: `src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/workspace-migration-builder-validators.module.ts`
|
||||
|
||||
```typescript
|
||||
import { FlatMyEntityValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-my-entity-validator.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
// ... existing imports
|
||||
],
|
||||
providers: [
|
||||
// ... existing providers
|
||||
FlatMyEntityValidatorService,
|
||||
],
|
||||
exports: [
|
||||
// ... existing exports
|
||||
FlatMyEntityValidatorService,
|
||||
],
|
||||
})
|
||||
export class WorkspaceMigrationBuilderValidatorsModule {}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Register Action Handlers
|
||||
|
||||
**File**: `src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/workspace-schema-migration-runner-action-handlers.module.ts`
|
||||
|
||||
```typescript
|
||||
import { CreateMyEntityActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/my-entity/services/create-my-entity-action-handler.service';
|
||||
import { UpdateMyEntityActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/my-entity/services/update-my-entity-action-handler.service';
|
||||
import { DeleteMyEntityActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/my-entity/services/delete-my-entity-action-handler.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
// ... existing imports
|
||||
],
|
||||
providers: [
|
||||
// ... existing providers
|
||||
CreateMyEntityActionHandlerService,
|
||||
UpdateMyEntityActionHandlerService,
|
||||
DeleteMyEntityActionHandlerService,
|
||||
],
|
||||
exports: [
|
||||
// ... existing exports (action handlers typically not exported)
|
||||
],
|
||||
})
|
||||
export class WorkspaceSchemaMigrationRunnerActionHandlersModule {}
|
||||
```
|
||||
|
||||
**Note**: Action handlers are typically only in `providers`, not `exports`.
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Create Service Layer
|
||||
|
||||
**File**: `src/engine/metadata-modules/my-entity/my-entity.service.ts`
|
||||
|
||||
```typescript
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatMyEntity } from 'src/engine/metadata-modules/flat-my-entity/types/flat-my-entity.type';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||
import { fromCreateMyEntityInputToUniversalFlatMyEntity } from 'src/engine/metadata-modules/flat-my-entity/utils/from-create-my-entity-input-to-universal-flat-my-entity.util';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@Injectable()
|
||||
export class MyEntityService {
|
||||
constructor(
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly workspaceManyOrAllFlatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
) {}
|
||||
|
||||
async create(input: CreateMyEntityInput, workspaceId: string): Promise<FlatMyEntity> {
|
||||
// 1. Transform input to universal flat entity
|
||||
const universalFlatMyEntityToCreate = fromCreateMyEntityInputToUniversalFlatMyEntity({
|
||||
input,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
// 2. Validate, build, and run
|
||||
const result =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
allFlatEntityOperationByMetadataName: {
|
||||
myEntity: {
|
||||
flatEntityToCreate: [universalFlatMyEntityToCreate],
|
||||
flatEntityToDelete: [],
|
||||
flatEntityToUpdate: [],
|
||||
},
|
||||
},
|
||||
workspaceId,
|
||||
isSystemBuild: false,
|
||||
},
|
||||
);
|
||||
|
||||
// 3. Throw if validation failed
|
||||
if (isDefined(result)) {
|
||||
throw new WorkspaceMigrationBuilderException(
|
||||
result,
|
||||
'Validation errors occurred while creating entity',
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Return freshly cached flat entity
|
||||
const { flatMyEntityMaps } =
|
||||
await this.workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatMyEntityMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: universalFlatMyEntityToCreate.id,
|
||||
flatEntityMaps: flatMyEntityMaps,
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Service pattern**:
|
||||
1. Transform input → universal flat entity
|
||||
2. Call `validateBuildAndRunWorkspaceMigration`
|
||||
3. Throw if validation errors
|
||||
4. **Return flat entity** (not DTO)
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Create Resolver Layer
|
||||
|
||||
**File**: `src/engine/metadata-modules/my-entity/my-entity.resolver.ts`
|
||||
|
||||
```typescript
|
||||
import { UseInterceptors } from '@nestjs/common';
|
||||
import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
||||
|
||||
import { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-graphql-api-exception.interceptor';
|
||||
import { MyEntityService } from 'src/engine/metadata-modules/my-entity/my-entity.service';
|
||||
import { fromFlatMyEntityToMyEntityDto } from 'src/engine/metadata-modules/my-entity/utils/from-flat-my-entity-to-my-entity-dto.util';
|
||||
|
||||
@Resolver(() => MyEntityDto)
|
||||
@UseInterceptors(WorkspaceMigrationGraphqlApiExceptionInterceptor)
|
||||
export class MyEntityResolver {
|
||||
constructor(private readonly myEntityService: MyEntityService) {}
|
||||
|
||||
@Mutation(() => MyEntityDto)
|
||||
async createMyEntity(
|
||||
@Args('input') input: CreateMyEntityInput,
|
||||
@Workspace() { id: workspaceId }: Workspace,
|
||||
): Promise<MyEntityDto> {
|
||||
// Service returns flat entity
|
||||
const flatMyEntity = await this.myEntityService.create(input, workspaceId);
|
||||
|
||||
// Resolver converts flat entity to DTO
|
||||
return fromFlatMyEntityToMyEntityDto(flatMyEntity);
|
||||
}
|
||||
|
||||
@Mutation(() => MyEntityDto)
|
||||
async updateMyEntity(
|
||||
@Args('id') id: string,
|
||||
@Args('input') input: UpdateMyEntityInput,
|
||||
@Workspace() { id: workspaceId }: Workspace,
|
||||
): Promise<MyEntityDto> {
|
||||
const flatMyEntity = await this.myEntityService.update(id, input, workspaceId);
|
||||
return fromFlatMyEntityToMyEntityDto(flatMyEntity);
|
||||
}
|
||||
|
||||
@Mutation(() => Boolean)
|
||||
async deleteMyEntity(
|
||||
@Args('id') id: string,
|
||||
@Workspace() { id: workspaceId }: Workspace,
|
||||
) {
|
||||
await this.myEntityService.delete(id, workspaceId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Resolver responsibilities**:
|
||||
- Receives flat entities from service
|
||||
- **Converts flat → DTO** using conversion utility
|
||||
- Returns DTOs to GraphQL API
|
||||
- Uses exception interceptor for error formatting
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Flat-to-DTO Conversion
|
||||
|
||||
**File**: `src/engine/metadata-modules/my-entity/utils/from-flat-my-entity-to-my-entity-dto.util.ts`
|
||||
|
||||
```typescript
|
||||
import { type FlatMyEntity } from 'src/engine/metadata-modules/flat-my-entity/types/flat-my-entity.type';
|
||||
import { type MyEntityDto } from 'src/engine/metadata-modules/my-entity/dtos/my-entity.dto';
|
||||
|
||||
export const fromFlatMyEntityToMyEntityDto = (
|
||||
flatMyEntity: FlatMyEntity,
|
||||
): MyEntityDto => {
|
||||
return {
|
||||
id: flatMyEntity.id,
|
||||
name: flatMyEntity.name,
|
||||
label: flatMyEntity.label,
|
||||
description: flatMyEntity.description,
|
||||
isCustom: flatMyEntity.isCustom,
|
||||
createdAt: flatMyEntity.createdAt,
|
||||
updatedAt: flatMyEntity.updatedAt,
|
||||
// Convert foreign key IDs to relation objects if needed
|
||||
// parentEntity: flatMyEntity.parentEntityId ? { id: flatMyEntity.parentEntityId } : null,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Layer Responsibilities
|
||||
|
||||
| Layer | Input | Output | Responsibility |
|
||||
|-------|-------|--------|----------------|
|
||||
| **Service** | Input DTO | Flat Entity | Business logic, validation orchestration |
|
||||
| **Resolver** | Service result | DTO | Flat → DTO conversion, GraphQL exposure |
|
||||
|
||||
**Service Layer**:
|
||||
- Works with flat entities internally
|
||||
- Returns `FlatMyEntity` type
|
||||
- No knowledge of DTOs or GraphQL types
|
||||
|
||||
**Resolver Layer**:
|
||||
- Receives flat entities from service
|
||||
- Converts flat entities to DTOs
|
||||
- Returns DTOs to GraphQL API
|
||||
|
||||
---
|
||||
|
||||
## Exception Interceptor
|
||||
|
||||
The `WorkspaceMigrationGraphqlApiExceptionInterceptor` automatically handles:
|
||||
|
||||
1. `FlatEntityMapsException` → Converts to GraphQL errors (NotFoundError, etc.)
|
||||
2. `WorkspaceMigrationBuilderException` → Formats validation errors with i18n
|
||||
3. `WorkspaceMigrationRunnerException` → Formats runner errors
|
||||
|
||||
**What it does**:
|
||||
- Catches exceptions and formats for API responses
|
||||
- Translates error messages based on user locale
|
||||
- Ensures consistent error structure for frontend
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
Before moving to Step 6 (Testing):
|
||||
|
||||
- [ ] Builder registered in builder module (providers + exports)
|
||||
- [ ] Validator registered in validators module (providers + exports)
|
||||
- [ ] All 3 action handlers registered in action handlers module (providers)
|
||||
- [ ] Service layer created
|
||||
- [ ] Service returns flat entities (not DTOs)
|
||||
- [ ] Resolver layer created
|
||||
- [ ] Resolver uses exception interceptor
|
||||
- [ ] Resolver converts flat → DTO
|
||||
- [ ] Flat-to-DTO conversion utility created
|
||||
|
||||
---
|
||||
|
||||
## Next Step
|
||||
|
||||
Once integration is complete, proceed to (**MANDATORY**):
|
||||
**[Syncable Entity: Integration Testing (Step 6/6)](../syncable-entity-testing/SKILL.md)**
|
||||
|
||||
For complete workflow, see `@creating-syncable-entity` rule.
|
||||
@@ -0,0 +1,355 @@
|
||||
---
|
||||
name: syncable-entity-runner-and-actions
|
||||
description: Implement action handlers for executing workspace migrations in Twenty. Use when creating database operations for syncable entities, implementing universal-to-flat entity transpilation, or handling create/update/delete actions in the runner layer.
|
||||
---
|
||||
|
||||
# Syncable Entity: Runner & Actions (Step 4/6)
|
||||
|
||||
**Purpose**: Execute migration actions against the database with proper transpilation from universal to flat entities.
|
||||
|
||||
**When to use**: After completing Steps 1-3 (Types, Cache, Builder). Required before integration.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
This step creates:
|
||||
1. Create action handler
|
||||
2. Update action handler
|
||||
3. Delete action handler
|
||||
4. Universal-to-flat conversion utilities
|
||||
|
||||
**Key pattern**: Each handler has two phases:
|
||||
1. **Transpilation**: Universal action → Flat action
|
||||
2. **Execution**: Flat action → Database operation
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Create Action Handler
|
||||
|
||||
**File**: `src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/my-entity/services/create-my-entity-action-handler.service.ts`
|
||||
|
||||
```typescript
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { WorkspaceCreateActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/workspace-create-action-handler.service';
|
||||
import { MyEntityEntity } from 'src/engine/metadata-modules/my-entity/entities/my-entity.entity';
|
||||
import { fromUniversalFlatMyEntityToFlatMyEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/my-entity/utils/from-universal-flat-my-entity-to-flat-my-entity.util';
|
||||
import {
|
||||
type UniversalCreateMyEntityAction,
|
||||
type FlatCreateMyEntityAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/my-entity/types/workspace-migration-my-entity-action.type';
|
||||
|
||||
@Injectable()
|
||||
export class CreateMyEntityActionHandlerService extends WorkspaceCreateActionHandlerService<
|
||||
'myEntity',
|
||||
UniversalCreateMyEntityAction,
|
||||
FlatCreateMyEntityAction
|
||||
> {
|
||||
constructor(
|
||||
@InjectRepository(MyEntityEntity, 'metadata')
|
||||
private readonly myEntityRepository: Repository<MyEntityEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
// Phase 1: Transpile universal action to flat action
|
||||
protected transpileUniversalActionToFlatAction(
|
||||
universalAction: UniversalCreateMyEntityAction,
|
||||
flatEntityMaps: AllFlatEntityMapsByMetadataName,
|
||||
): FlatCreateMyEntityAction {
|
||||
return {
|
||||
type: 'create',
|
||||
metadataName: 'myEntity',
|
||||
flatEntity: fromUniversalFlatMyEntityToFlatMyEntity(
|
||||
universalAction.universalFlatEntity,
|
||||
flatEntityMaps,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
// Phase 2: Execute flat action against database
|
||||
protected async executeForMetadata(
|
||||
flatActions: FlatCreateMyEntityAction[],
|
||||
): Promise<void> {
|
||||
const flatEntities = flatActions.map((action) => action.flatEntity);
|
||||
|
||||
await this.insertFlatEntitiesInRepository({
|
||||
repository: this.myEntityRepository,
|
||||
flatEntities,
|
||||
});
|
||||
}
|
||||
|
||||
protected async executeForWorkspaceSchema(): Promise<void> {
|
||||
// No workspace schema changes needed for metadata-only entity
|
||||
return;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Key helper methods**:
|
||||
- `transpileUniversalActionToFlatAction`: Converts universal → flat
|
||||
- `insertFlatEntitiesInRepository`: Base class helper for inserts
|
||||
- `executeForMetadata`: Metadata database operations
|
||||
- `executeForWorkspaceSchema`: Workspace schema changes (if needed)
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Update Action Handler
|
||||
|
||||
**File**: `src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/my-entity/services/update-my-entity-action-handler.service.ts`
|
||||
|
||||
```typescript
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { WorkspaceUpdateActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/workspace-update-action-handler.service';
|
||||
import { MyEntityEntity } from 'src/engine/metadata-modules/my-entity/entities/my-entity.entity';
|
||||
import { fromUniversalFlatMyEntityToFlatMyEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/my-entity/utils/from-universal-flat-my-entity-to-flat-my-entity.util';
|
||||
import { resolveUniversalUpdateRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
|
||||
|
||||
@Injectable()
|
||||
export class UpdateMyEntityActionHandlerService extends WorkspaceUpdateActionHandlerService<
|
||||
'myEntity',
|
||||
UniversalUpdateMyEntityAction,
|
||||
FlatUpdateMyEntityAction
|
||||
> {
|
||||
constructor(
|
||||
@InjectRepository(MyEntityEntity, 'metadata')
|
||||
private readonly myEntityRepository: Repository<MyEntityEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected transpileUniversalActionToFlatAction(
|
||||
universalAction: UniversalUpdateMyEntityAction,
|
||||
flatEntityMaps: AllFlatEntityMapsByMetadataName,
|
||||
): FlatUpdateMyEntityAction {
|
||||
const flatEntity = fromUniversalFlatMyEntityToFlatMyEntity(
|
||||
universalAction.universalFlatEntity,
|
||||
flatEntityMaps,
|
||||
);
|
||||
|
||||
// Resolve universal foreign keys in updates to regular IDs
|
||||
const flatUpdates = resolveUniversalUpdateRelationIdentifiersToIds({
|
||||
metadataName: 'myEntity',
|
||||
universalUpdates: universalAction.universalUpdates,
|
||||
flatEntityMaps,
|
||||
});
|
||||
|
||||
return {
|
||||
type: 'update',
|
||||
metadataName: 'myEntity',
|
||||
flatEntity,
|
||||
updates: flatUpdates,
|
||||
};
|
||||
}
|
||||
|
||||
protected async executeForMetadata(
|
||||
flatActions: FlatUpdateMyEntityAction[],
|
||||
): Promise<void> {
|
||||
for (const action of flatActions) {
|
||||
await this.myEntityRepository.update(
|
||||
{ id: action.flatEntity.id },
|
||||
action.updates,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected async executeForWorkspaceSchema(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Update-specific helper**:
|
||||
- `resolveUniversalUpdateRelationIdentifiersToIds`: Maps universal identifiers back to regular IDs in the updates object
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Delete Action Handler
|
||||
|
||||
**File**: `src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/my-entity/services/delete-my-entity-action-handler.service.ts`
|
||||
|
||||
```typescript
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { WorkspaceDeleteActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/workspace-delete-action-handler.service';
|
||||
import { MyEntityEntity } from 'src/engine/metadata-modules/my-entity/entities/my-entity.entity';
|
||||
import { fromUniversalFlatMyEntityToFlatMyEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/my-entity/utils/from-universal-flat-my-entity-to-flat-my-entity.util';
|
||||
|
||||
@Injectable()
|
||||
export class DeleteMyEntityActionHandlerService extends WorkspaceDeleteActionHandlerService<
|
||||
'myEntity',
|
||||
UniversalDeleteMyEntityAction,
|
||||
FlatDeleteMyEntityAction
|
||||
> {
|
||||
constructor(
|
||||
@InjectRepository(MyEntityEntity, 'metadata')
|
||||
private readonly myEntityRepository: Repository<MyEntityEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected transpileUniversalActionToFlatAction(
|
||||
universalAction: UniversalDeleteMyEntityAction,
|
||||
flatEntityMaps: AllFlatEntityMapsByMetadataName,
|
||||
): FlatDeleteMyEntityAction {
|
||||
// Use base class helper for delete transpilation
|
||||
return this.transpileUniversalDeleteActionToFlatDeleteAction({
|
||||
universalAction,
|
||||
flatEntityMaps,
|
||||
fromUniversalFlatEntityToFlatEntity: fromUniversalFlatMyEntityToFlatMyEntity,
|
||||
});
|
||||
}
|
||||
|
||||
protected async executeForMetadata(
|
||||
flatActions: FlatDeleteMyEntityAction[],
|
||||
): Promise<void> {
|
||||
const ids = flatActions.map((action) => action.flatEntity.id);
|
||||
|
||||
await this.myEntityRepository.delete(ids);
|
||||
}
|
||||
|
||||
protected async executeForWorkspaceSchema(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Delete-specific helper**:
|
||||
- `transpileUniversalDeleteActionToFlatDeleteAction`: Base class helper that handles standard delete transpilation
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Universal-to-Flat Conversion
|
||||
|
||||
**File**: `src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/my-entity/utils/from-universal-flat-my-entity-to-flat-my-entity.util.ts`
|
||||
|
||||
```typescript
|
||||
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
|
||||
import { type UniversalFlatMyEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-my-entity.type';
|
||||
import { type FlatMyEntity } from 'src/engine/metadata-modules/flat-my-entity/types/flat-my-entity.type';
|
||||
import { type AllFlatEntityMapsByMetadataName } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps-by-metadata-name.type';
|
||||
|
||||
export const fromUniversalFlatMyEntityToFlatMyEntity = (
|
||||
universalFlatMyEntity: UniversalFlatMyEntity,
|
||||
flatEntityMaps: AllFlatEntityMapsByMetadataName,
|
||||
): FlatMyEntity => {
|
||||
// Resolve universal foreign keys back to regular IDs
|
||||
return resolveUniversalRelationIdentifiersToIds({
|
||||
metadataName: 'myEntity',
|
||||
universalFlatEntity: universalFlatMyEntity,
|
||||
flatEntityMaps,
|
||||
}) as FlatMyEntity;
|
||||
};
|
||||
```
|
||||
|
||||
**Key utility**:
|
||||
- `resolveUniversalRelationIdentifiersToIds`: Maps universal identifiers → regular IDs (reverse of `resolveEntityRelationUniversalIdentifiers`)
|
||||
|
||||
---
|
||||
|
||||
## Action Handler Patterns
|
||||
|
||||
### Pattern: Create Handler
|
||||
```typescript
|
||||
// 1. Transpile: Universal → Flat
|
||||
protected transpileUniversalActionToFlatAction(
|
||||
universalAction,
|
||||
flatEntityMaps,
|
||||
) {
|
||||
return {
|
||||
type: 'create',
|
||||
metadataName: 'myEntity',
|
||||
flatEntity: fromUniversalFlatMyEntityToFlatMyEntity(
|
||||
universalAction.universalFlatEntity,
|
||||
flatEntityMaps,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
// 2. Execute: Flat → Database
|
||||
protected async executeForMetadata(flatActions) {
|
||||
await this.insertFlatEntitiesInRepository({
|
||||
repository: this.myEntityRepository,
|
||||
flatEntities: flatActions.map(a => a.flatEntity),
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern: Update Handler
|
||||
```typescript
|
||||
// Transpile with update-specific resolution
|
||||
protected transpileUniversalActionToFlatAction(
|
||||
universalAction,
|
||||
flatEntityMaps,
|
||||
) {
|
||||
const flatEntity = fromUniversalFlatMyEntityToFlatMyEntity(
|
||||
universalAction.universalFlatEntity,
|
||||
flatEntityMaps,
|
||||
);
|
||||
|
||||
const flatUpdates = resolveUniversalUpdateRelationIdentifiersToIds({
|
||||
metadataName: 'myEntity',
|
||||
universalUpdates: universalAction.universalUpdates,
|
||||
flatEntityMaps,
|
||||
});
|
||||
|
||||
return { type: 'update', metadataName: 'myEntity', flatEntity, updates: flatUpdates };
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern: Delete Handler
|
||||
```typescript
|
||||
// Use base class helper
|
||||
protected transpileUniversalActionToFlatAction(
|
||||
universalAction,
|
||||
flatEntityMaps,
|
||||
) {
|
||||
return this.transpileUniversalDeleteActionToFlatDeleteAction({
|
||||
universalAction,
|
||||
flatEntityMaps,
|
||||
fromUniversalFlatEntityToFlatEntity: fromUniversalFlatMyEntityToFlatMyEntity,
|
||||
});
|
||||
}
|
||||
|
||||
// Delete
|
||||
protected async executeForMetadata(flatActions) {
|
||||
const ids = flatActions.map(a => a.flatEntity.id);
|
||||
await this.myEntityRepository.delete(ids);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
Before moving to Step 5:
|
||||
|
||||
- [ ] Create action handler implemented
|
||||
- [ ] Update action handler implemented
|
||||
- [ ] Delete action handler implemented
|
||||
- [ ] All handlers extend appropriate base class
|
||||
- [ ] `transpileUniversalActionToFlatAction` implemented in all handlers
|
||||
- [ ] `executeForMetadata` implemented in all handlers
|
||||
- [ ] `executeForWorkspaceSchema` implemented (or returns empty)
|
||||
- [ ] Universal-to-flat conversion utility created
|
||||
- [ ] Create handler uses `insertFlatEntitiesInRepository`
|
||||
- [ ] Update handler uses `resolveUniversalUpdateRelationIdentifiersToIds`
|
||||
- [ ] Delete handler uses `transpileUniversalDeleteActionToFlatDeleteAction`
|
||||
- [ ] Delete handler uses hard delete (`delete()`)
|
||||
|
||||
---
|
||||
|
||||
## Next Step
|
||||
|
||||
Once action handlers are complete, proceed to:
|
||||
**[Syncable Entity: Integration (Step 5/6)](../syncable-entity-integration/SKILL.md)**
|
||||
|
||||
For complete workflow, see `@creating-syncable-entity` rule.
|
||||
@@ -0,0 +1,494 @@
|
||||
---
|
||||
name: syncable-entity-testing
|
||||
description: Create comprehensive integration tests for syncable entities in Twenty. Use when writing integration tests for metadata entities, covering validator exceptions, input transpilation errors, and CRUD operations. Tests are MANDATORY for all syncable entities.
|
||||
---
|
||||
|
||||
# Syncable Entity: Integration Testing (Step 6/6 - MANDATORY)
|
||||
|
||||
**Purpose**: Create comprehensive test suite covering all validation scenarios, input transpilation exceptions, and successful use cases.
|
||||
|
||||
**When to use**: After completing Steps 1-5. Integration tests are **REQUIRED** for all syncable entities.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
Tests must cover:
|
||||
1. **Failing scenarios** - All validator exceptions and input transpilation errors
|
||||
2. **Successful scenarios** - All CRUD operations and edge cases
|
||||
3. **Test utilities** - Reusable query factories and helper functions
|
||||
|
||||
**Test pattern**: Two-file pattern (query factory + wrapper) for each operation.
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Create Test Utilities
|
||||
|
||||
### Pattern: Query Factory
|
||||
|
||||
**File**: `test/integration/metadata/suites/my-entity/utils/create-my-entity-query-factory.util.ts`
|
||||
|
||||
```typescript
|
||||
import gql from 'graphql-tag';
|
||||
import { type PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
|
||||
import { type CreateMyEntityInput } from 'src/engine/metadata-modules/my-entity/dtos/create-my-entity.input';
|
||||
|
||||
export type CreateMyEntityFactoryInput = CreateMyEntityInput;
|
||||
|
||||
const DEFAULT_MY_ENTITY_GQL_FIELDS = `
|
||||
id
|
||||
name
|
||||
label
|
||||
description
|
||||
isCustom
|
||||
createdAt
|
||||
updatedAt
|
||||
`;
|
||||
|
||||
export const createMyEntityQueryFactory = ({
|
||||
input,
|
||||
gqlFields = DEFAULT_MY_ENTITY_GQL_FIELDS,
|
||||
}: PerformMetadataQueryParams<CreateMyEntityFactoryInput>) => ({
|
||||
query: gql`
|
||||
mutation CreateMyEntity($input: CreateMyEntityInput!) {
|
||||
createMyEntity(input: $input) {
|
||||
${gqlFields}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
input,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Pattern: Wrapper Utility
|
||||
|
||||
**File**: `test/integration/metadata/suites/my-entity/utils/create-my-entity.util.ts`
|
||||
|
||||
```typescript
|
||||
import {
|
||||
type CreateMyEntityFactoryInput,
|
||||
createMyEntityQueryFactory,
|
||||
} from 'test/integration/metadata/suites/my-entity/utils/create-my-entity-query-factory.util';
|
||||
import { makeMetadataAPIRequest } from 'test/integration/metadata/suites/utils/make-metadata-api-request.util';
|
||||
import { type CommonResponseBody } from 'test/integration/metadata/types/common-response-body.type';
|
||||
import { type PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
|
||||
import { warnIfErrorButNotExpectedToFail } from 'test/integration/metadata/utils/warn-if-error-but-not-expected-to-fail.util';
|
||||
import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util';
|
||||
import { type MyEntityDto } from 'src/engine/metadata-modules/my-entity/dtos/my-entity.dto';
|
||||
|
||||
export const createMyEntity = async ({
|
||||
input,
|
||||
gqlFields,
|
||||
expectToFail = false,
|
||||
token,
|
||||
}: PerformMetadataQueryParams<CreateMyEntityFactoryInput>): CommonResponseBody<{
|
||||
createMyEntity: MyEntityDto;
|
||||
}> => {
|
||||
const graphqlOperation = createMyEntityQueryFactory({
|
||||
input,
|
||||
gqlFields,
|
||||
});
|
||||
|
||||
const response = await makeMetadataAPIRequest(graphqlOperation, token);
|
||||
|
||||
if (expectToFail === true) {
|
||||
warnIfNoErrorButExpectedToFail({
|
||||
response,
|
||||
errorMessage: 'My entity creation should have failed but did not',
|
||||
});
|
||||
}
|
||||
|
||||
if (expectToFail === false) {
|
||||
warnIfErrorButNotExpectedToFail({
|
||||
response,
|
||||
errorMessage: 'My entity creation has failed but should not',
|
||||
});
|
||||
}
|
||||
|
||||
return { data: response.body.data, errors: response.body.errors };
|
||||
};
|
||||
```
|
||||
|
||||
**Required utilities** (follow same pattern):
|
||||
- `update-my-entity-query-factory.util.ts` + `update-my-entity.util.ts`
|
||||
- `delete-my-entity-query-factory.util.ts` + `delete-my-entity.util.ts`
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Failing Creation Tests
|
||||
|
||||
**File**: `test/integration/metadata/suites/my-entity/failing-my-entity-creation.integration-spec.ts`
|
||||
|
||||
```typescript
|
||||
import { expectOneNotInternalServerErrorSnapshot } from 'test/integration/graphql/utils/expect-one-not-internal-server-error-snapshot.util';
|
||||
import { createMyEntity } from 'test/integration/metadata/suites/my-entity/utils/create-my-entity.util';
|
||||
import { deleteMyEntity } from 'test/integration/metadata/suites/my-entity/utils/delete-my-entity.util';
|
||||
import {
|
||||
eachTestingContextFilter,
|
||||
type EachTestingContext,
|
||||
} from 'twenty-shared/testing';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type CreateMyEntityInput } from 'src/engine/metadata-modules/my-entity/dtos/create-my-entity.input';
|
||||
|
||||
type TestContext = {
|
||||
input: CreateMyEntityInput;
|
||||
};
|
||||
|
||||
type GlobalTestContext = {
|
||||
existingEntityLabel: string;
|
||||
existingEntityName: string;
|
||||
};
|
||||
|
||||
const globalTestContext: GlobalTestContext = {
|
||||
existingEntityLabel: 'Existing Test Entity',
|
||||
existingEntityName: 'existingTestEntity',
|
||||
};
|
||||
|
||||
type CreateMyEntityTestingContext = EachTestingContext<TestContext>[];
|
||||
|
||||
describe('My entity creation should fail', () => {
|
||||
let existingEntityId: string | undefined;
|
||||
|
||||
beforeAll(async () => {
|
||||
// Setup: Create entity for uniqueness tests
|
||||
const { data } = await createMyEntity({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
name: globalTestContext.existingEntityName,
|
||||
label: globalTestContext.existingEntityLabel,
|
||||
},
|
||||
});
|
||||
|
||||
existingEntityId = data.createMyEntity.id;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
// Cleanup
|
||||
if (isDefined(existingEntityId)) {
|
||||
await deleteMyEntity({
|
||||
expectToFail: false,
|
||||
input: { id: existingEntityId },
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const failingMyEntityCreationTestCases: CreateMyEntityTestingContext = [
|
||||
// Input transpilation validation
|
||||
{
|
||||
title: 'when name is missing',
|
||||
context: {
|
||||
input: {
|
||||
label: 'Entity Missing Name',
|
||||
} as CreateMyEntityInput,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'when label is missing',
|
||||
context: {
|
||||
input: {
|
||||
name: 'entityMissingLabel',
|
||||
} as CreateMyEntityInput,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'when name is empty string',
|
||||
context: {
|
||||
input: {
|
||||
name: '',
|
||||
label: 'Empty Name Entity',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Validator business logic
|
||||
{
|
||||
title: 'when name already exists (uniqueness)',
|
||||
context: {
|
||||
input: {
|
||||
name: globalTestContext.existingEntityName,
|
||||
label: 'Duplicate Name Entity',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'when trying to create standard entity',
|
||||
context: {
|
||||
input: {
|
||||
name: 'myEntity',
|
||||
label: 'Standard Entity',
|
||||
isCustom: false,
|
||||
} as CreateMyEntityInput,
|
||||
},
|
||||
},
|
||||
|
||||
// Foreign key validation
|
||||
{
|
||||
title: 'when parentEntityId does not exist',
|
||||
context: {
|
||||
input: {
|
||||
name: 'invalidParentEntity',
|
||||
label: 'Invalid Parent Entity',
|
||||
parentEntityId: '00000000-0000-0000-0000-000000000000',
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
it.each(eachTestingContextFilter(failingMyEntityCreationTestCases))(
|
||||
'$title',
|
||||
async ({ context }) => {
|
||||
const { errors } = await createMyEntity({
|
||||
expectToFail: true,
|
||||
input: context.input,
|
||||
});
|
||||
|
||||
expectOneNotInternalServerErrorSnapshot({
|
||||
errors,
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
**Test coverage requirements**:
|
||||
- ✅ Missing required fields
|
||||
- ✅ Empty strings
|
||||
- ✅ Invalid format
|
||||
- ✅ Uniqueness violations
|
||||
- ✅ Standard entity protection
|
||||
- ✅ Foreign key validation
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Successful Creation Tests
|
||||
|
||||
**File**: `test/integration/metadata/suites/my-entity/successful-my-entity-creation.integration-spec.ts`
|
||||
|
||||
```typescript
|
||||
import { createMyEntity } from 'test/integration/metadata/suites/my-entity/utils/create-my-entity.util';
|
||||
import { deleteMyEntity } from 'test/integration/metadata/suites/my-entity/utils/delete-my-entity.util';
|
||||
import { type CreateMyEntityInput } from 'src/engine/metadata-modules/my-entity/dtos/create-my-entity.input';
|
||||
|
||||
describe('My entity creation should succeed', () => {
|
||||
let createdEntityId: string;
|
||||
|
||||
afterEach(async () => {
|
||||
if (createdEntityId) {
|
||||
await deleteMyEntity({
|
||||
expectToFail: false,
|
||||
input: { id: createdEntityId },
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('should create entity with minimal required input', async () => {
|
||||
const { data } = await createMyEntity({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
name: 'minimalEntity',
|
||||
label: 'Minimal Entity',
|
||||
},
|
||||
});
|
||||
|
||||
createdEntityId = data?.createMyEntity?.id;
|
||||
|
||||
expect(data.createMyEntity).toMatchObject({
|
||||
id: expect.any(String),
|
||||
name: 'minimalEntity',
|
||||
label: 'Minimal Entity',
|
||||
description: null,
|
||||
isCustom: true,
|
||||
createdAt: expect.any(String),
|
||||
updatedAt: expect.any(String),
|
||||
});
|
||||
});
|
||||
|
||||
it('should create entity with all optional fields', async () => {
|
||||
const input = {
|
||||
name: 'fullEntity',
|
||||
label: 'Full Entity',
|
||||
description: 'Entity with all fields specified',
|
||||
} as const satisfies CreateMyEntityInput;
|
||||
|
||||
const { data } = await createMyEntity({
|
||||
expectToFail: false,
|
||||
input,
|
||||
});
|
||||
|
||||
createdEntityId = data?.createMyEntity?.id;
|
||||
|
||||
expect(data.createMyEntity).toMatchObject({
|
||||
id: expect.any(String),
|
||||
name: 'fullEntity',
|
||||
label: 'Full Entity',
|
||||
description: 'Entity with all fields specified',
|
||||
isCustom: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should sanitize input by trimming whitespace', async () => {
|
||||
const { data } = await createMyEntity({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
name: ' entityWithSpaces ',
|
||||
label: ' Entity With Spaces ',
|
||||
description: ' Description with spaces ',
|
||||
},
|
||||
});
|
||||
|
||||
createdEntityId = data?.createMyEntity?.id;
|
||||
|
||||
expect(data.createMyEntity).toMatchObject({
|
||||
id: expect.any(String),
|
||||
name: 'entityWithSpaces',
|
||||
label: 'Entity With Spaces',
|
||||
description: 'Description with spaces',
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle long text content', async () => {
|
||||
const longDescription = 'A'.repeat(1000);
|
||||
|
||||
const { data } = await createMyEntity({
|
||||
expectToFail: false,
|
||||
input: {
|
||||
name: 'longDescEntity',
|
||||
label: 'Long Description Entity',
|
||||
description: longDescription,
|
||||
},
|
||||
});
|
||||
|
||||
createdEntityId = data?.createMyEntity?.id;
|
||||
|
||||
expect(data.createMyEntity).toMatchObject({
|
||||
id: expect.any(String),
|
||||
description: longDescription,
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
**Test coverage requirements**:
|
||||
- ✅ Minimal required input
|
||||
- ✅ All optional fields
|
||||
- ✅ Input sanitization
|
||||
- ✅ Long text content
|
||||
- ✅ Special characters
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Update and Delete Tests
|
||||
|
||||
Create similar test files for update and delete operations:
|
||||
|
||||
**Required files**:
|
||||
- `failing-my-entity-update.integration-spec.ts`
|
||||
- `successful-my-entity-update.integration-spec.ts`
|
||||
- `failing-my-entity-deletion.integration-spec.ts`
|
||||
- `successful-my-entity-deletion.integration-spec.ts`
|
||||
|
||||
---
|
||||
|
||||
## Testing Best Practices
|
||||
|
||||
### Pattern: Cleanup
|
||||
```typescript
|
||||
afterEach(async () => {
|
||||
if (createdEntityId) {
|
||||
await deleteMyEntity({
|
||||
expectToFail: false,
|
||||
input: { id: createdEntityId },
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Pattern: Type-Safe Inputs
|
||||
```typescript
|
||||
const input = {
|
||||
name: 'myEntity',
|
||||
label: 'My Entity',
|
||||
} as const satisfies CreateMyEntityInput;
|
||||
```
|
||||
|
||||
### Pattern: Snapshot Testing
|
||||
```typescript
|
||||
expectOneNotInternalServerErrorSnapshot({
|
||||
errors,
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running Tests
|
||||
|
||||
```bash
|
||||
# Run all entity tests
|
||||
npx jest test/integration/metadata/suites/my-entity --config=packages/twenty-server/jest.config.mjs
|
||||
|
||||
# Run specific test file
|
||||
npx jest test/integration/metadata/suites/my-entity/failing-my-entity-creation.integration-spec.ts --config=packages/twenty-server/jest.config.mjs
|
||||
|
||||
# Update snapshots
|
||||
npx jest test/integration/metadata/suites/my-entity --updateSnapshot --config=packages/twenty-server/jest.config.mjs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Test Checklist
|
||||
|
||||
### Test Utilities
|
||||
- [ ] `create-my-entity-query-factory.util.ts` created
|
||||
- [ ] `create-my-entity.util.ts` created
|
||||
- [ ] `update-my-entity-query-factory.util.ts` created
|
||||
- [ ] `update-my-entity.util.ts` created
|
||||
- [ ] `delete-my-entity-query-factory.util.ts` created
|
||||
- [ ] `delete-my-entity.util.ts` created
|
||||
|
||||
### Failing Tests Coverage
|
||||
- [ ] Missing required fields
|
||||
- [ ] Empty string validation
|
||||
- [ ] Uniqueness violations
|
||||
- [ ] Standard entity protection
|
||||
- [ ] Foreign key validation
|
||||
- [ ] JSONB property validation (if applicable)
|
||||
|
||||
### Successful Tests Coverage
|
||||
- [ ] Create with minimal input
|
||||
- [ ] Create with all optional fields
|
||||
- [ ] Input sanitization (whitespace)
|
||||
- [ ] Long text content
|
||||
- [ ] Update single field
|
||||
- [ ] Update multiple fields
|
||||
- [ ] Successful deletion
|
||||
|
||||
### Snapshot Tests
|
||||
- [ ] All failing tests use `expectOneNotInternalServerErrorSnapshot`
|
||||
- [ ] Snapshots committed to `__snapshots__/` directory
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
Your integration tests are complete when:
|
||||
|
||||
✅ All test utilities created (minimum 6 files)
|
||||
✅ Failing creation tests cover all validators
|
||||
✅ Failing update tests cover business rules
|
||||
✅ Failing deletion tests cover protection rules
|
||||
✅ Successful tests cover all use cases
|
||||
✅ All snapshots generated and committed
|
||||
✅ All tests pass consistently
|
||||
✅ Test coverage meets requirements (>80%)
|
||||
|
||||
---
|
||||
|
||||
## Final Step
|
||||
|
||||
✅ **Step 6 Complete!** → Your syncable entity is fully tested and production-ready!
|
||||
|
||||
**Congratulations!** You've successfully created a new syncable entity in Twenty's workspace migration system.
|
||||
|
||||
For complete workflow, see `@creating-syncable-entity` rule.
|
||||
@@ -0,0 +1,340 @@
|
||||
---
|
||||
name: syncable-entity-types-and-constants
|
||||
description: Define types, entities, and central constant registrations for syncable entities in Twenty's workspace migration system. Use when creating new syncable entities, defining TypeORM entities, flat entity types, or registering in central constants (ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME, ALL_ONE_TO_MANY_METADATA_RELATIONS, ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY, ALL_MANY_TO_ONE_METADATA_RELATIONS).
|
||||
---
|
||||
|
||||
# Syncable Entity: Types & Constants (Step 1/6)
|
||||
|
||||
**Purpose**: Define all types, entities, and register in central constants. This is the foundation - everything else depends on these types being correct.
|
||||
|
||||
**When to use**: First step when creating any new syncable entity. Must be completed before other steps.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
This step creates:
|
||||
1. Metadata name constant (twenty-shared)
|
||||
2. TypeORM entity (extends `SyncableEntity`)
|
||||
3. Flat entity types
|
||||
4. Action types (universal + flat)
|
||||
5. Central constant registrations (5 constants)
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Add Metadata Name
|
||||
|
||||
**File**: `packages/twenty-shared/src/metadata/all-metadata-name.constant.ts`
|
||||
|
||||
```typescript
|
||||
export const ALL_METADATA_NAME = {
|
||||
// ... existing entries
|
||||
myEntity: 'myEntity',
|
||||
} as const;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Create TypeORM Entity
|
||||
|
||||
**File**: `src/engine/metadata-modules/my-entity/entities/my-entity.entity.ts`
|
||||
|
||||
```typescript
|
||||
import { Entity, Column, ManyToOne, JoinColumn } from 'typeorm';
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
|
||||
@Entity({ name: 'myEntity' })
|
||||
export class MyEntityEntity extends SyncableEntity {
|
||||
@Column({ type: 'varchar' })
|
||||
name: string;
|
||||
|
||||
@Column({ type: 'varchar' })
|
||||
label: string;
|
||||
|
||||
@Column({ type: 'boolean', default: true })
|
||||
isCustom: boolean;
|
||||
|
||||
// Foreign key example (optional)
|
||||
@Column({ type: 'uuid', nullable: true })
|
||||
parentEntityId: string | null;
|
||||
|
||||
@ManyToOne(() => ParentEntityEntity, { nullable: true })
|
||||
@JoinColumn({ name: 'parentEntityId' })
|
||||
parentEntity: ParentEntityEntity | null;
|
||||
|
||||
// JSONB column example (optional)
|
||||
@Column({ type: 'jsonb', nullable: true })
|
||||
settings: Record<string, any> | null;
|
||||
}
|
||||
```
|
||||
|
||||
**Key rules**:
|
||||
- Must extend `SyncableEntity` (provides `id`, `universalIdentifier`, `applicationId`, etc.)
|
||||
- Must have `isCustom` boolean column
|
||||
- Use `@Column({ type: 'jsonb' })` for JSON data
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Define Flat Entity Types
|
||||
|
||||
**File**: `src/engine/metadata-modules/flat-my-entity/types/flat-my-entity.type.ts`
|
||||
|
||||
```typescript
|
||||
import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type';
|
||||
import { type MyEntityEntity } from 'src/engine/metadata-modules/my-entity/entities/my-entity.entity';
|
||||
|
||||
export type FlatMyEntity = FlatEntityFrom<MyEntityEntity>;
|
||||
```
|
||||
|
||||
**Maps file** (if entity has indexed lookups):
|
||||
|
||||
```typescript
|
||||
// flat-my-entity-maps.type.ts
|
||||
export type FlatMyEntityMaps = {
|
||||
byId: Record<string, FlatMyEntity>;
|
||||
byName: Record<string, FlatMyEntity>;
|
||||
// Add other indexes as needed
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Define Editable Properties
|
||||
|
||||
**File**: `src/engine/metadata-modules/flat-my-entity/constants/editable-flat-my-entity-properties.constant.ts`
|
||||
|
||||
```typescript
|
||||
export const EDITABLE_FLAT_MY_ENTITY_PROPERTIES = [
|
||||
'name',
|
||||
'label',
|
||||
'description',
|
||||
'parentEntityId',
|
||||
'settings',
|
||||
] as const satisfies ReadonlyArray<keyof FlatMyEntity>;
|
||||
```
|
||||
|
||||
**Rule**: Only include properties that can be updated (exclude `id`, `createdAt`, `universalIdentifier`, etc.)
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Define Action Types
|
||||
|
||||
**File**: `src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/my-entity/types/workspace-migration-my-entity-action.type.ts`
|
||||
|
||||
```typescript
|
||||
import { type FlatMyEntity } from 'src/engine/metadata-modules/flat-my-entity/types/flat-my-entity.type';
|
||||
import { type UniversalFlatMyEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-my-entity.type';
|
||||
|
||||
// Universal actions (used by builder/runner)
|
||||
export type UniversalCreateMyEntityAction = {
|
||||
type: 'create';
|
||||
metadataName: 'myEntity';
|
||||
universalFlatEntity: UniversalFlatMyEntity;
|
||||
};
|
||||
|
||||
export type UniversalUpdateMyEntityAction = {
|
||||
type: 'update';
|
||||
metadataName: 'myEntity';
|
||||
universalFlatEntity: UniversalFlatMyEntity;
|
||||
universalUpdates: Partial<UniversalFlatMyEntity>;
|
||||
};
|
||||
|
||||
export type UniversalDeleteMyEntityAction = {
|
||||
type: 'delete';
|
||||
metadataName: 'myEntity';
|
||||
universalFlatEntity: UniversalFlatMyEntity;
|
||||
};
|
||||
|
||||
// Flat actions (internal to runner)
|
||||
export type FlatCreateMyEntityAction = {
|
||||
type: 'create';
|
||||
metadataName: 'myEntity';
|
||||
flatEntity: FlatMyEntity;
|
||||
};
|
||||
|
||||
export type FlatUpdateMyEntityAction = {
|
||||
type: 'update';
|
||||
metadataName: 'myEntity';
|
||||
flatEntity: FlatMyEntity;
|
||||
updates: Partial<FlatMyEntity>;
|
||||
};
|
||||
|
||||
export type FlatDeleteMyEntityAction = {
|
||||
type: 'delete';
|
||||
metadataName: 'myEntity';
|
||||
flatEntity: FlatMyEntity;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Register in Central Constants
|
||||
|
||||
### 6a. AllFlatEntityTypesByMetadataName
|
||||
|
||||
**File**: `src/engine/metadata-modules/flat-entity/types/all-flat-entity-types-by-metadata-name.ts`
|
||||
|
||||
```typescript
|
||||
export type AllFlatEntityTypesByMetadataName = {
|
||||
// ... existing entries
|
||||
myEntity: {
|
||||
flatEntityMaps: FlatMyEntityMaps;
|
||||
universalActions: {
|
||||
create: UniversalCreateMyEntityAction;
|
||||
update: UniversalUpdateMyEntityAction;
|
||||
delete: UniversalDeleteMyEntityAction;
|
||||
};
|
||||
flatActions: {
|
||||
create: FlatCreateMyEntityAction;
|
||||
update: FlatUpdateMyEntityAction;
|
||||
delete: FlatDeleteMyEntityAction;
|
||||
};
|
||||
flatEntity: FlatMyEntity;
|
||||
universalFlatEntity: UniversalFlatMyEntity;
|
||||
entity: MyEntityEntity;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### 6b. ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME
|
||||
|
||||
**File**: `src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant.ts`
|
||||
|
||||
```typescript
|
||||
export const ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME = {
|
||||
// ... existing entries
|
||||
myEntity: {
|
||||
name: { toCompare: true },
|
||||
label: { toCompare: true },
|
||||
description: { toCompare: true },
|
||||
parentEntityId: {
|
||||
toCompare: true,
|
||||
universalProperty: 'parentEntityUniversalIdentifier',
|
||||
},
|
||||
settings: {
|
||||
toCompare: true,
|
||||
toStringify: true,
|
||||
universalProperty: 'universalSettings',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
```
|
||||
|
||||
**Rules**:
|
||||
- `toCompare: true` → Editable property (checked for changes)
|
||||
- `toStringify: true` → JSONB/object property (needs JSON serialization)
|
||||
- `universalProperty` → Maps to universal version (for foreign keys & JSONB with `SerializedRelation`)
|
||||
|
||||
### 6c. ALL_ONE_TO_MANY_METADATA_RELATIONS
|
||||
|
||||
**File**: `src/engine/metadata-modules/flat-entity/constant/all-one-to-many-metadata-relations.constant.ts`
|
||||
|
||||
This constant is **type-checked** — values for `metadataName`, `flatEntityForeignKeyAggregator`, and `universalFlatEntityForeignKeyAggregator` are derived from entity type definitions. The aggregator names follow the pattern: remove trailing `'s'` from the relation property name, then append `Ids` or `UniversalIdentifiers`.
|
||||
|
||||
```typescript
|
||||
export const ALL_ONE_TO_MANY_METADATA_RELATIONS = {
|
||||
// ... existing entries
|
||||
myEntity: {
|
||||
// If myEntity has a `childEntities: ChildEntityEntity[]` property:
|
||||
childEntities: {
|
||||
metadataName: 'childEntity',
|
||||
flatEntityForeignKeyAggregator: 'childEntityIds',
|
||||
universalFlatEntityForeignKeyAggregator: 'childEntityUniversalIdentifiers',
|
||||
},
|
||||
// null for relations to non-syncable entities
|
||||
someNonSyncableRelation: null,
|
||||
},
|
||||
} as const;
|
||||
```
|
||||
|
||||
### 6d. ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY
|
||||
|
||||
**File**: `src/engine/metadata-modules/flat-entity/constant/all-many-to-one-metadata-foreign-key.constant.ts`
|
||||
|
||||
Low-level primitive constant. Only contains `foreignKey` — the column name ending in `Id` that stores the foreign key. Type-checked against entity properties.
|
||||
|
||||
```typescript
|
||||
export const ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY = {
|
||||
// ... existing entries
|
||||
myEntity: {
|
||||
workspace: null,
|
||||
application: null,
|
||||
parentEntity: {
|
||||
foreignKey: 'parentEntityId',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
```
|
||||
|
||||
### 6e. ALL_MANY_TO_ONE_METADATA_RELATIONS
|
||||
|
||||
**File**: `src/engine/metadata-modules/flat-entity/constant/all-many-to-one-metadata-relations.constant.ts`
|
||||
|
||||
Derived from both `ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY` (for `foreignKey` type and `universalForeignKey` derivation) and `ALL_ONE_TO_MANY_METADATA_RELATIONS` (for `inverseOneToManyProperty` key constraint). This is the main constant consumed by utils and optimistic tooling.
|
||||
|
||||
```typescript
|
||||
export const ALL_MANY_TO_ONE_METADATA_RELATIONS = {
|
||||
// ... existing entries
|
||||
myEntity: {
|
||||
workspace: null,
|
||||
application: null,
|
||||
parentEntity: {
|
||||
metadataName: 'parentEntity',
|
||||
foreignKey: 'parentEntityId',
|
||||
inverseOneToManyProperty: 'myEntities', // key in ALL_ONE_TO_MANY_METADATA_RELATIONS['parentEntity'], or null if no inverse
|
||||
isNullable: false,
|
||||
universalForeignKey: 'parentEntityUniversalIdentifier',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
```
|
||||
|
||||
**Derivation dependency graph**:
|
||||
|
||||
```
|
||||
ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY ALL_ONE_TO_MANY_METADATA_RELATIONS
|
||||
(foreignKey only) (metadataName, aggregators)
|
||||
│ │
|
||||
│ FK type + universalFK derivation │ inverseOneToManyProperty keys
|
||||
│ │
|
||||
└────────────────┬───────────────────────┘
|
||||
▼
|
||||
ALL_MANY_TO_ONE_METADATA_RELATIONS
|
||||
(metadataName, foreignKey, inverseOneToManyProperty,
|
||||
isNullable, universalForeignKey)
|
||||
```
|
||||
|
||||
**Rules**:
|
||||
- `workspace: null`, `application: null` — always present, always null (non-syncable relations)
|
||||
- `inverseOneToManyProperty` — must be a key in `ALL_ONE_TO_MANY_METADATA_RELATIONS[targetMetadataName]`, or `null` if the target entity doesn't expose an inverse one-to-many relation
|
||||
- `universalForeignKey` — derived from `foreignKey` by replacing the `Id` suffix with `UniversalIdentifier`
|
||||
- Optimistic utils resolve `flatEntityForeignKeyAggregator` / `universalFlatEntityForeignKeyAggregator` at runtime by looking up `inverseOneToManyProperty` in `ALL_ONE_TO_MANY_METADATA_RELATIONS`
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
Before moving to Step 2:
|
||||
|
||||
- [ ] Metadata name added to `ALL_METADATA_NAME`
|
||||
- [ ] TypeORM entity created (extends `SyncableEntity`)
|
||||
- [ ] `isCustom` column added
|
||||
- [ ] Flat entity type defined
|
||||
- [ ] Flat entity maps type defined (if needed)
|
||||
- [ ] Editable properties constant defined
|
||||
- [ ] Universal and flat action types defined
|
||||
- [ ] Registered in `AllFlatEntityTypesByMetadataName`
|
||||
- [ ] Registered in `ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME`
|
||||
- [ ] Registered in `ALL_ONE_TO_MANY_METADATA_RELATIONS` (if entity has one-to-many relations)
|
||||
- [ ] Registered in `ALL_MANY_TO_ONE_METADATA_FOREIGN_KEY`
|
||||
- [ ] Registered in `ALL_MANY_TO_ONE_METADATA_RELATIONS`
|
||||
- [ ] TypeScript compiles without errors
|
||||
|
||||
---
|
||||
|
||||
## Next Step
|
||||
|
||||
Once all types and constants are defined, proceed to:
|
||||
**[Syncable Entity: Cache & Transform (Step 2/6)](../syncable-entity-cache-and-transform/SKILL.md)**
|
||||
|
||||
For complete workflow, see `@creating-syncable-entity` rule.
|
||||
@@ -20,6 +20,7 @@ jobs:
|
||||
with:
|
||||
files: |
|
||||
packages/create-twenty-app/**
|
||||
!packages/create-twenty-app/package.json
|
||||
create-app-test:
|
||||
needs: changed-files-check
|
||||
if: needs.changed-files-check.outputs.any_changed == 'true'
|
||||
|
||||
@@ -28,11 +28,14 @@ jobs:
|
||||
packages/twenty-ui/**
|
||||
packages/twenty-shared/**
|
||||
packages/twenty-sdk/**
|
||||
!packages/twenty-sdk/package.json
|
||||
changed-files-check-e2e:
|
||||
uses: ./.github/workflows/changed-files.yaml
|
||||
with:
|
||||
files: |
|
||||
packages/**
|
||||
!packages/create-twenty-app/package.json
|
||||
!packages/twenty-sdk/package.json
|
||||
playwright.config.ts
|
||||
.github/workflows/ci-front.yaml
|
||||
front-sb-build:
|
||||
@@ -194,10 +197,19 @@ jobs:
|
||||
tag: scope:frontend
|
||||
tasks: reset:env
|
||||
- name: Run ${{ matrix.task }} task
|
||||
id: run-task
|
||||
uses: ./.github/actions/nx-affected
|
||||
with:
|
||||
tag: scope:frontend
|
||||
tasks: ${{ matrix.task }}
|
||||
- name: Check for coverage threshold failure
|
||||
if: always() && steps.run-task.outcome == 'failure' && matrix.task == 'test'
|
||||
shell: bash
|
||||
run: |
|
||||
echo "::error::The test task failed. If no individual test is failing, this is likely a coverage threshold not being met."
|
||||
echo ""
|
||||
echo "To debug locally, run: npx nx run twenty-front:test:ci"
|
||||
exit 1
|
||||
- name: Save ${{ matrix.task }} cache
|
||||
uses: ./.github/actions/save-cache
|
||||
with:
|
||||
|
||||
@@ -18,6 +18,7 @@ jobs:
|
||||
with:
|
||||
files: |
|
||||
packages/twenty-sdk/**
|
||||
!packages/twenty-sdk/package.json
|
||||
sdk-test:
|
||||
needs: changed-files-check
|
||||
if: needs.changed-files-check.outputs.any_changed == 'true'
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
.nx/installation
|
||||
.nx/cache
|
||||
.nx/workspace-data
|
||||
.nx/nxw.js
|
||||
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
@@ -49,3 +50,4 @@ dump.rdb
|
||||
mcp.json
|
||||
/.junie/
|
||||
TRANSLATION_QA_REPORT.md
|
||||
.playwright-mcp/
|
||||
|
||||
-115
@@ -1,115 +0,0 @@
|
||||
"use strict";
|
||||
// This file should be committed to your repository! It wraps Nx and ensures
|
||||
// that your local installation matches nx.json.
|
||||
// See: https://nx.dev/recipes/installation/install-non-javascript for more info.
|
||||
|
||||
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const cp = require('child_process');
|
||||
const installationPath = path.join(__dirname, 'installation', 'package.json');
|
||||
function matchesCurrentNxInstall(currentInstallation, nxJsonInstallation) {
|
||||
if (!currentInstallation.devDependencies ||
|
||||
!Object.keys(currentInstallation.devDependencies).length) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (currentInstallation.devDependencies['nx'] !==
|
||||
nxJsonInstallation.version ||
|
||||
require(path.join(path.dirname(installationPath), 'node_modules', 'nx', 'package.json')).version !== nxJsonInstallation.version) {
|
||||
return false;
|
||||
}
|
||||
for (const [plugin, desiredVersion] of Object.entries(nxJsonInstallation.plugins || {})) {
|
||||
if (currentInstallation.devDependencies[plugin] !== desiredVersion) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function ensureDir(p) {
|
||||
if (!fs.existsSync(p)) {
|
||||
fs.mkdirSync(p, { recursive: true });
|
||||
}
|
||||
}
|
||||
function getCurrentInstallation() {
|
||||
try {
|
||||
return require(installationPath);
|
||||
}
|
||||
catch {
|
||||
return {
|
||||
name: 'nx-installation',
|
||||
version: '0.0.0',
|
||||
devDependencies: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
function performInstallation(currentInstallation, nxJson) {
|
||||
fs.writeFileSync(installationPath, JSON.stringify({
|
||||
name: 'nx-installation',
|
||||
devDependencies: {
|
||||
nx: nxJson.installation.version,
|
||||
...nxJson.installation.plugins,
|
||||
},
|
||||
}));
|
||||
try {
|
||||
cp.execSync('npm i', {
|
||||
cwd: path.dirname(installationPath),
|
||||
stdio: 'inherit',
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
// revert possible changes to the current installation
|
||||
fs.writeFileSync(installationPath, JSON.stringify(currentInstallation));
|
||||
// rethrow
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
function ensureUpToDateInstallation() {
|
||||
const nxJsonPath = path.join(__dirname, '..', 'nx.json');
|
||||
let nxJson;
|
||||
try {
|
||||
nxJson = require(nxJsonPath);
|
||||
if (!nxJson.installation) {
|
||||
console.error('[NX]: The "installation" entry in the "nx.json" file is required when running the nx wrapper. See https://nx.dev/recipes/installation/install-non-javascript');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
catch {
|
||||
console.error('[NX]: The "nx.json" file is required when running the nx wrapper. See https://nx.dev/recipes/installation/install-non-javascript');
|
||||
process.exit(1);
|
||||
}
|
||||
try {
|
||||
ensureDir(path.join(__dirname, 'installation'));
|
||||
const currentInstallation = getCurrentInstallation();
|
||||
if (!matchesCurrentNxInstall(currentInstallation, nxJson.installation)) {
|
||||
performInstallation(currentInstallation, nxJson);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
const messageLines = [
|
||||
'[NX]: Nx wrapper failed to synchronize installation.',
|
||||
];
|
||||
if (e instanceof Error) {
|
||||
messageLines.push('');
|
||||
messageLines.push(e.message);
|
||||
messageLines.push(e.stack);
|
||||
}
|
||||
else {
|
||||
messageLines.push(e.toString());
|
||||
}
|
||||
console.error(messageLines.join('\n'));
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
if (!process.env.NX_WRAPPER_SKIP_INSTALL) {
|
||||
ensureUpToDateInstallation();
|
||||
}
|
||||
|
||||
require('./installation/node_modules/nx/bin/nx');
|
||||
@@ -118,6 +118,7 @@
|
||||
"outputs": ["{projectRoot}/coverage"],
|
||||
"options": {
|
||||
"jestConfig": "{projectRoot}/jest.config.mjs",
|
||||
"silent": true,
|
||||
"coverage": true,
|
||||
"coverageReporters": ["text-summary"],
|
||||
"cacheDirectory": "../../.cache/jest/{projectRoot}"
|
||||
@@ -272,9 +273,6 @@
|
||||
"inputs": ["default", "^default"]
|
||||
}
|
||||
},
|
||||
"installation": {
|
||||
"version": "22.3.3"
|
||||
},
|
||||
"generators": {
|
||||
"@nx/react": {
|
||||
"application": {
|
||||
|
||||
@@ -183,6 +183,7 @@
|
||||
"ts-jest": "^29.1.1",
|
||||
"ts-loader": "^9.2.3",
|
||||
"ts-node": "10.9.1",
|
||||
"tsc-alias": "^1.8.16",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"tsx": "^4.17.0",
|
||||
"vite": "^7.0.0",
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
Create Twenty App is the official scaffolding CLI for building apps on top of [Twenty CRM](https://twenty.com). It sets up a ready‑to‑run project that works seamlessly with the [twenty-sdk](https://www.npmjs.com/package/twenty-sdk).
|
||||
|
||||
- Zero‑config project bootstrap
|
||||
- Preconfigured scripts for auth, dev mode (watch & sync), generate, uninstall, and function management
|
||||
- Preconfigured scripts for auth, dev mode (watch & sync), uninstall, and function management
|
||||
- Strong TypeScript support and typed client generation
|
||||
|
||||
## Documentation
|
||||
@@ -35,45 +35,84 @@ cd my-twenty-app
|
||||
corepack enable
|
||||
yarn install
|
||||
|
||||
# Get help
|
||||
yarn run help
|
||||
# Get help and list all available commands
|
||||
yarn twenty help
|
||||
|
||||
# Authenticate using your API key (you'll be prompted)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Add a new entity to your application (guided)
|
||||
yarn entity:add
|
||||
|
||||
# Generate a typed Twenty client and workspace entity types
|
||||
yarn app:generate
|
||||
yarn twenty entity:add
|
||||
|
||||
# Start dev mode: watches, builds, and syncs local changes to your workspace
|
||||
yarn app:dev
|
||||
# (also auto-generates a typed API client in node_modules/twenty-sdk/generated)
|
||||
yarn twenty app:dev
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn function:logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function with a JSON payload
|
||||
yarn function:execute -n my-function -p '{"key": "value"}'
|
||||
yarn twenty function:execute -n my-function -p '{"key": "value"}'
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn app:uninstall
|
||||
yarn twenty app:uninstall
|
||||
```
|
||||
|
||||
## Scaffolding modes
|
||||
|
||||
Control which example files are included when creating a new app:
|
||||
|
||||
| Flag | Behavior |
|
||||
|------|----------|
|
||||
| `-e, --exhaustive` | **(default)** Creates all example files without prompting |
|
||||
| `-m, --minimal` | Creates only core files (`application-config.ts` and `default-role.ts`) |
|
||||
| `-i, --interactive` | Prompts you to select which examples to include |
|
||||
|
||||
```bash
|
||||
# Default: all examples included
|
||||
npx create-twenty-app@latest my-app
|
||||
|
||||
# Minimal: only core files
|
||||
npx create-twenty-app@latest my-app -m
|
||||
|
||||
# Interactive: choose which examples to include
|
||||
npx create-twenty-app@latest my-app -i
|
||||
```
|
||||
|
||||
In interactive mode, you can pick from:
|
||||
- **Example object** — a custom CRM object definition (`objects/example-object.ts`)
|
||||
- **Example field** — a custom field on the example object (`fields/example-field.ts`)
|
||||
- **Example logic function** — a server-side handler with HTTP trigger (`logic-functions/hello-world.ts`)
|
||||
- **Example front component** — a React UI component (`front-components/hello-world.tsx`)
|
||||
- **Example view** — a saved view for the example object (`views/example-view.ts`)
|
||||
- **Example navigation menu item** — a sidebar link (`navigation-menu-items/example-navigation-menu-item.ts`)
|
||||
|
||||
## What gets scaffolded
|
||||
- A minimal app structure ready for Twenty with example files:
|
||||
- `application-config.ts` - Application metadata configuration
|
||||
- `roles/default-role.ts` - Default role for logic functions
|
||||
- `logic-functions/hello-world.ts` - Example logic function with HTTP trigger
|
||||
- `front-components/hello-world.tsx` - Example front component
|
||||
- TypeScript configuration
|
||||
- Prewired scripts that wrap the `twenty` CLI from twenty-sdk
|
||||
|
||||
**Core files (always created):**
|
||||
- `application-config.ts` — Application metadata configuration
|
||||
- `roles/default-role.ts` — Default role for logic functions
|
||||
- `logic-functions/post-install.ts` — Post-install logic function (runs after app installation)
|
||||
- TypeScript configuration, ESLint, package.json, .gitignore
|
||||
- A prewired `twenty` script that delegates to the `twenty` CLI from twenty-sdk
|
||||
|
||||
**Example files (controlled by scaffolding mode):**
|
||||
- `objects/example-object.ts` — Example custom object with a text field
|
||||
- `fields/example-field.ts` — Example standalone field extending the example object
|
||||
- `logic-functions/hello-world.ts` — Example logic function with HTTP trigger
|
||||
- `front-components/hello-world.tsx` — Example front component
|
||||
- `views/example-view.ts` — Example saved view for the example object
|
||||
- `navigation-menu-items/example-navigation-menu-item.ts` — Example sidebar navigation link
|
||||
|
||||
## Next steps
|
||||
- Use `yarn auth:login` to authenticate with your Twenty workspace.
|
||||
- Explore the generated project and add your first entity with `yarn entity:add` (logic functions, front components, objects, roles).
|
||||
- Use `yarn app:dev` while you iterate — it watches, builds, and syncs changes to your workspace in real time.
|
||||
- Keep your types up‑to‑date using `yarn app:generate`.
|
||||
- Run `yarn twenty help` to see all available commands.
|
||||
- Use `yarn twenty auth:login` to authenticate with your Twenty workspace.
|
||||
- Explore the generated project and add your first entity with `yarn twenty entity:add` (logic functions, front components, objects, roles, views, navigation menu items).
|
||||
- Use `yarn twenty app:dev` while you iterate — it watches, builds, and syncs changes to your workspace in real time.
|
||||
- Types are auto‑generated by `yarn twenty app:dev` and stored in `node_modules/twenty-sdk/generated`.
|
||||
|
||||
|
||||
## Publish your application
|
||||
@@ -101,8 +140,8 @@ git push
|
||||
Our team reviews contributions for quality, security, and reusability before merging.
|
||||
|
||||
## Troubleshooting
|
||||
- Auth prompts not appearing: run `yarn auth:login` again and verify the API key permissions.
|
||||
- Types not generated: ensure `yarn app:generate` runs without errors, then re‑start `yarn app:dev`.
|
||||
- Auth prompts not appearing: run `yarn twenty auth:login` again and verify the API key permissions.
|
||||
- Types not generated: ensure `yarn twenty app:dev` is running — it auto‑generates the typed client.
|
||||
|
||||
## Contributing
|
||||
- See our [GitHub](https://github.com/twentyhq/twenty)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-twenty-app",
|
||||
"version": "0.5.2",
|
||||
"version": "0.6.0",
|
||||
"description": "Command-line interface to create Twenty application",
|
||||
"main": "dist/cli.cjs",
|
||||
"bin": "dist/cli.cjs",
|
||||
@@ -10,9 +10,7 @@
|
||||
"package.json"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "npx rimraf dist && npx vite build",
|
||||
"prepublishOnly": "tsx ../twenty-utils/pack-scripts/pre-publish-only.ts",
|
||||
"postpublish": "tsx ../twenty-utils/pack-scripts/post-publish.ts"
|
||||
"build": "npx rimraf dist && npx vite build"
|
||||
},
|
||||
"keywords": [
|
||||
"twenty",
|
||||
@@ -38,7 +36,6 @@
|
||||
"lodash.camelcase": "^4.3.0",
|
||||
"lodash.kebabcase": "^4.1.1",
|
||||
"lodash.startcase": "^4.4.0",
|
||||
"twenty-shared": "workspace:*",
|
||||
"uuid": "^13.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -48,6 +45,8 @@
|
||||
"@types/lodash.kebabcase": "^4.1.7",
|
||||
"@types/lodash.startcase": "^4",
|
||||
"@types/node": "^20.0.0",
|
||||
"twenty-sdk": "workspace:*",
|
||||
"twenty-shared": "workspace:*",
|
||||
"typescript": "^5.9.2",
|
||||
"vite": "^7.0.0",
|
||||
"vite-plugin-dts": "^4.5.4",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import chalk from 'chalk';
|
||||
import { Command, CommanderError } from 'commander';
|
||||
import { CreateAppCommand } from '@/create-app.command';
|
||||
import { type ScaffoldingMode } from '@/types/scaffolding-options';
|
||||
import packageJson from '../package.json';
|
||||
|
||||
const program = new Command(packageJson.name)
|
||||
@@ -12,18 +13,58 @@ const program = new Command(packageJson.name)
|
||||
'Output the current version of create-twenty-app.',
|
||||
)
|
||||
.argument('[directory]')
|
||||
.option('-e, --exhaustive', 'Create all example entities (default)')
|
||||
.option(
|
||||
'-m, --minimal',
|
||||
'Create only core entities (application-config and default-role)',
|
||||
)
|
||||
.option(
|
||||
'-i, --interactive',
|
||||
'Interactively choose which entity examples to include',
|
||||
)
|
||||
.helpOption('-h, --help', 'Display this help message.')
|
||||
.action(async (directory?: string) => {
|
||||
if (directory && !/^[a-z0-9-]+$/.test(directory)) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
`Invalid directory "${directory}". Must contain only lowercase letters, numbers, and hyphens`,
|
||||
),
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
await new CreateAppCommand().execute(directory);
|
||||
});
|
||||
.action(
|
||||
async (
|
||||
directory?: string,
|
||||
options?: {
|
||||
exhaustive?: boolean;
|
||||
minimal?: boolean;
|
||||
interactive?: boolean;
|
||||
},
|
||||
) => {
|
||||
const modeFlags = [
|
||||
options?.exhaustive,
|
||||
options?.minimal,
|
||||
options?.interactive,
|
||||
].filter(Boolean);
|
||||
|
||||
if (modeFlags.length > 1) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
'Error: --exhaustive, --minimal, and --interactive are mutually exclusive.',
|
||||
),
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (directory && !/^[a-z0-9-]+$/.test(directory)) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
`Invalid directory "${directory}". Must contain only lowercase letters, numbers, and hyphens`,
|
||||
),
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const mode: ScaffoldingMode = options?.minimal
|
||||
? 'minimal'
|
||||
: options?.interactive
|
||||
? 'interactive'
|
||||
: 'exhaustive';
|
||||
|
||||
await new CreateAppCommand().execute(directory, mode);
|
||||
},
|
||||
);
|
||||
|
||||
program.exitOverride();
|
||||
|
||||
|
||||
@@ -5,34 +5,35 @@ This is a [Twenty](https://twenty.com) application project bootstrapped with [`c
|
||||
First, authenticate to your workspace:
|
||||
|
||||
```bash
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
```
|
||||
|
||||
Then, start development mode to sync your app and watch for changes:
|
||||
|
||||
```bash
|
||||
yarn app:dev
|
||||
yarn twenty app:dev
|
||||
```
|
||||
|
||||
Open your Twenty instance and go to `/settings/applications` section to see the result.
|
||||
|
||||
## Available Commands
|
||||
|
||||
Run `yarn twenty help` to list all available commands. Common commands:
|
||||
|
||||
```bash
|
||||
# Authentication
|
||||
yarn auth:login # Authenticate with Twenty
|
||||
yarn auth:logout # Remove credentials
|
||||
yarn auth:status # Check auth status
|
||||
yarn auth:switch # Switch default workspace
|
||||
yarn auth:list # List all configured workspaces
|
||||
yarn twenty auth:login # Authenticate with Twenty
|
||||
yarn twenty auth:logout # Remove credentials
|
||||
yarn twenty auth:status # Check auth status
|
||||
yarn twenty auth:switch # Switch default workspace
|
||||
yarn twenty auth:list # List all configured workspaces
|
||||
|
||||
# Application
|
||||
yarn app:dev # Start dev mode (watch, build, and sync)
|
||||
yarn entity:add # Add a new entity (function, front-component, object, role)
|
||||
yarn app:generate # Generate typed Twenty client
|
||||
yarn function:logs # Stream function logs
|
||||
yarn function:execute # Execute a function with JSON payload
|
||||
yarn app:uninstall # Uninstall app from workspace
|
||||
yarn twenty app:dev # Start dev mode (watch, build, sync, and auto-generate typed client)
|
||||
yarn twenty entity:add # Add a new entity (object, field, function, front-component, role, view, navigation-menu-item)
|
||||
yarn twenty function:logs # Stream function logs
|
||||
yarn twenty function:execute # Execute a function with JSON payload
|
||||
yarn twenty app:uninstall # Uninstall app from workspace
|
||||
```
|
||||
|
||||
## Learn More
|
||||
|
||||
@@ -8,14 +8,24 @@ import inquirer from 'inquirer';
|
||||
import kebabCase from 'lodash.kebabcase';
|
||||
import * as path from 'path';
|
||||
|
||||
import {
|
||||
type ExampleOptions,
|
||||
type ScaffoldingMode,
|
||||
} from '@/types/scaffolding-options';
|
||||
|
||||
const CURRENT_EXECUTION_DIRECTORY = process.env.INIT_CWD || process.cwd();
|
||||
|
||||
export class CreateAppCommand {
|
||||
async execute(directory?: string): Promise<void> {
|
||||
async execute(
|
||||
directory?: string,
|
||||
mode: ScaffoldingMode = 'exhaustive',
|
||||
): Promise<void> {
|
||||
try {
|
||||
const { appName, appDisplayName, appDirectory, appDescription } =
|
||||
await this.getAppInfos(directory);
|
||||
|
||||
const exampleOptions = await this.resolveExampleOptions(mode);
|
||||
|
||||
await this.validateDirectory(appDirectory);
|
||||
|
||||
this.logCreationInfo({ appDirectory, appName });
|
||||
@@ -27,6 +37,7 @@ export class CreateAppCommand {
|
||||
appDisplayName,
|
||||
appDescription,
|
||||
appDirectory,
|
||||
exampleOptions,
|
||||
});
|
||||
|
||||
await install(appDirectory);
|
||||
@@ -92,6 +103,95 @@ export class CreateAppCommand {
|
||||
return { appName, appDisplayName, appDirectory, appDescription };
|
||||
}
|
||||
|
||||
private async resolveExampleOptions(
|
||||
mode: ScaffoldingMode,
|
||||
): Promise<ExampleOptions> {
|
||||
if (mode === 'minimal') {
|
||||
return {
|
||||
includeExampleObject: false,
|
||||
includeExampleField: false,
|
||||
includeExampleLogicFunction: false,
|
||||
includeExampleFrontComponent: false,
|
||||
includeExampleView: false,
|
||||
includeExampleNavigationMenuItem: false,
|
||||
};
|
||||
}
|
||||
|
||||
if (mode === 'exhaustive') {
|
||||
return {
|
||||
includeExampleObject: true,
|
||||
includeExampleField: true,
|
||||
includeExampleLogicFunction: true,
|
||||
includeExampleFrontComponent: true,
|
||||
includeExampleView: true,
|
||||
includeExampleNavigationMenuItem: true,
|
||||
};
|
||||
}
|
||||
|
||||
const { selectedExamples } = await inquirer.prompt([
|
||||
{
|
||||
type: 'checkbox',
|
||||
name: 'selectedExamples',
|
||||
message: 'Select which example files to include:',
|
||||
choices: [
|
||||
{
|
||||
name: 'Example object (custom object definition)',
|
||||
value: 'object',
|
||||
checked: true,
|
||||
},
|
||||
{
|
||||
name: 'Example field (custom field on the example object)',
|
||||
value: 'field',
|
||||
checked: true,
|
||||
},
|
||||
{
|
||||
name: 'Example logic function (server-side handler)',
|
||||
value: 'logicFunction',
|
||||
checked: true,
|
||||
},
|
||||
{
|
||||
name: 'Example front component (React UI component)',
|
||||
value: 'frontComponent',
|
||||
checked: true,
|
||||
},
|
||||
{
|
||||
name: 'Example view (saved view for the example object)',
|
||||
value: 'view',
|
||||
checked: true,
|
||||
},
|
||||
{
|
||||
name: 'Example navigation menu item (sidebar link)',
|
||||
value: 'navigationMenuItem',
|
||||
checked: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
const includeField = selectedExamples.includes('field');
|
||||
const includeView = selectedExamples.includes('view');
|
||||
const includeObject =
|
||||
selectedExamples.includes('object') || includeField || includeView;
|
||||
|
||||
if ((includeField || includeView) && !selectedExamples.includes('object')) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Note: Example object auto-included because example field/view depends on it.',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
includeExampleObject: includeObject,
|
||||
includeExampleField: includeField,
|
||||
includeExampleLogicFunction: selectedExamples.includes('logicFunction'),
|
||||
includeExampleFrontComponent: selectedExamples.includes('frontComponent'),
|
||||
includeExampleView: includeView,
|
||||
includeExampleNavigationMenuItem:
|
||||
selectedExamples.includes('navigationMenuItem'),
|
||||
};
|
||||
}
|
||||
|
||||
private async validateDirectory(appDirectory: string): Promise<void> {
|
||||
if (!(await fs.pathExists(appDirectory))) {
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
export type ScaffoldingMode = 'exhaustive' | 'minimal' | 'interactive';
|
||||
|
||||
export type ExampleOptions = {
|
||||
includeExampleObject: boolean;
|
||||
includeExampleField: boolean;
|
||||
includeExampleLogicFunction: boolean;
|
||||
includeExampleFrontComponent: boolean;
|
||||
includeExampleView: boolean;
|
||||
includeExampleNavigationMenuItem: boolean;
|
||||
};
|
||||
@@ -2,6 +2,7 @@ import * as fs from 'fs-extra';
|
||||
import { join } from 'path';
|
||||
import { tmpdir } from 'os';
|
||||
import { copyBaseApplicationProject } from '@/utils/app-template';
|
||||
import { type ExampleOptions } from '@/types/scaffolding-options';
|
||||
|
||||
// Mock fs-extra's copy function to skip copying base template (not available during tests)
|
||||
jest.mock('fs-extra', () => {
|
||||
@@ -15,6 +16,24 @@ jest.mock('fs-extra', () => {
|
||||
const APPLICATION_FILE_NAME = 'application-config.ts';
|
||||
const DEFAULT_ROLE_FILE_NAME = 'default-role.ts';
|
||||
|
||||
const ALL_EXAMPLES: ExampleOptions = {
|
||||
includeExampleObject: true,
|
||||
includeExampleField: true,
|
||||
includeExampleLogicFunction: true,
|
||||
includeExampleFrontComponent: true,
|
||||
includeExampleView: true,
|
||||
includeExampleNavigationMenuItem: true,
|
||||
};
|
||||
|
||||
const NO_EXAMPLES: ExampleOptions = {
|
||||
includeExampleObject: false,
|
||||
includeExampleField: false,
|
||||
includeExampleLogicFunction: false,
|
||||
includeExampleFrontComponent: false,
|
||||
includeExampleView: false,
|
||||
includeExampleNavigationMenuItem: false,
|
||||
};
|
||||
|
||||
describe('copyBaseApplicationProject', () => {
|
||||
let testAppDirectory: string;
|
||||
|
||||
@@ -41,6 +60,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
// Verify src/ folder exists
|
||||
@@ -62,6 +82,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const packageJsonPath = join(testAppDirectory, 'package.json');
|
||||
@@ -70,8 +91,8 @@ describe('copyBaseApplicationProject', () => {
|
||||
const packageJson = await fs.readJson(packageJsonPath);
|
||||
expect(packageJson.name).toBe('my-test-app');
|
||||
expect(packageJson.version).toBe('0.1.0');
|
||||
expect(packageJson.dependencies['twenty-sdk']).toBe('0.5.2');
|
||||
expect(packageJson.scripts['app:dev']).toBe('twenty app:dev');
|
||||
expect(packageJson.dependencies['twenty-sdk']).toBe('latest');
|
||||
expect(packageJson.scripts['twenty']).toBe('twenty');
|
||||
});
|
||||
|
||||
it('should create .gitignore file', async () => {
|
||||
@@ -80,6 +101,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const gitignorePath = join(testAppDirectory, '.gitignore');
|
||||
@@ -96,6 +118,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const yarnLockPath = join(testAppDirectory, 'yarn.lock');
|
||||
@@ -111,6 +134,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const appConfigPath = join(testAppDirectory, 'src', APPLICATION_FILE_NAME);
|
||||
@@ -148,6 +172,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const roleConfigPath = join(
|
||||
@@ -192,6 +217,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
// Verify fs.copy was called with correct destination
|
||||
@@ -208,6 +234,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: '',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const appConfigPath = join(testAppDirectory, 'src', APPLICATION_FILE_NAME);
|
||||
@@ -225,6 +252,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
appDisplayName: 'App One',
|
||||
appDescription: 'First app',
|
||||
appDirectory: firstAppDir,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
// Create second app
|
||||
@@ -235,6 +263,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
appDisplayName: 'App Two',
|
||||
appDescription: 'Second app',
|
||||
appDirectory: secondAppDir,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
// Read both app configs
|
||||
@@ -267,6 +296,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
appDisplayName: 'App One',
|
||||
appDescription: 'First app',
|
||||
appDirectory: firstAppDir,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
// Create second app
|
||||
@@ -277,6 +307,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
appDisplayName: 'App Two',
|
||||
appDescription: 'Second app',
|
||||
appDirectory: secondAppDir,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const firstRoleConfig = await fs.readFile(
|
||||
@@ -299,4 +330,345 @@ describe('copyBaseApplicationProject', () => {
|
||||
expect(secondUuid).toBeDefined();
|
||||
expect(firstUuid).not.toBe(secondUuid);
|
||||
});
|
||||
|
||||
describe('scaffolding modes', () => {
|
||||
describe('exhaustive mode (all examples)', () => {
|
||||
it('should create all example files when all options are enabled', async () => {
|
||||
await copyBaseApplicationProject({
|
||||
appName: 'my-test-app',
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const srcPath = join(testAppDirectory, 'src');
|
||||
|
||||
expect(
|
||||
await fs.pathExists(join(srcPath, 'objects', 'example-object.ts')),
|
||||
).toBe(true);
|
||||
expect(
|
||||
await fs.pathExists(join(srcPath, 'fields', 'example-field.ts')),
|
||||
).toBe(true);
|
||||
expect(
|
||||
await fs.pathExists(
|
||||
join(srcPath, 'logic-functions', 'hello-world.ts'),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
await fs.pathExists(
|
||||
join(srcPath, 'front-components', 'hello-world.tsx'),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
await fs.pathExists(join(srcPath, 'views', 'example-view.ts')),
|
||||
).toBe(true);
|
||||
expect(
|
||||
await fs.pathExists(
|
||||
join(
|
||||
srcPath,
|
||||
'navigation-menu-items',
|
||||
'example-navigation-menu-item.ts',
|
||||
),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('minimal mode (no examples)', () => {
|
||||
it('should create only core files when no examples are enabled', async () => {
|
||||
await copyBaseApplicationProject({
|
||||
appName: 'my-test-app',
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: NO_EXAMPLES,
|
||||
});
|
||||
|
||||
const srcPath = join(testAppDirectory, 'src');
|
||||
|
||||
// Core files should exist
|
||||
expect(await fs.pathExists(join(srcPath, APPLICATION_FILE_NAME))).toBe(
|
||||
true,
|
||||
);
|
||||
expect(
|
||||
await fs.pathExists(join(srcPath, 'roles', DEFAULT_ROLE_FILE_NAME)),
|
||||
).toBe(true);
|
||||
|
||||
// Example files should not exist
|
||||
expect(
|
||||
await fs.pathExists(join(srcPath, 'objects', 'example-object.ts')),
|
||||
).toBe(false);
|
||||
expect(
|
||||
await fs.pathExists(join(srcPath, 'fields', 'example-field.ts')),
|
||||
).toBe(false);
|
||||
expect(
|
||||
await fs.pathExists(
|
||||
join(srcPath, 'logic-functions', 'hello-world.ts'),
|
||||
),
|
||||
).toBe(false);
|
||||
expect(
|
||||
await fs.pathExists(
|
||||
join(srcPath, 'front-components', 'hello-world.tsx'),
|
||||
),
|
||||
).toBe(false);
|
||||
expect(
|
||||
await fs.pathExists(join(srcPath, 'views', 'example-view.ts')),
|
||||
).toBe(false);
|
||||
expect(
|
||||
await fs.pathExists(
|
||||
join(
|
||||
srcPath,
|
||||
'navigation-menu-items',
|
||||
'example-navigation-menu-item.ts',
|
||||
),
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('selective examples', () => {
|
||||
it('should create only front component when only that option is enabled', async () => {
|
||||
await copyBaseApplicationProject({
|
||||
appName: 'my-test-app',
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: {
|
||||
includeExampleObject: false,
|
||||
includeExampleField: false,
|
||||
includeExampleLogicFunction: false,
|
||||
includeExampleFrontComponent: true,
|
||||
includeExampleView: false,
|
||||
includeExampleNavigationMenuItem: false,
|
||||
},
|
||||
});
|
||||
|
||||
const srcPath = join(testAppDirectory, 'src');
|
||||
|
||||
expect(
|
||||
await fs.pathExists(
|
||||
join(srcPath, 'front-components', 'hello-world.tsx'),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
await fs.pathExists(join(srcPath, 'objects', 'example-object.ts')),
|
||||
).toBe(false);
|
||||
expect(
|
||||
await fs.pathExists(join(srcPath, 'fields', 'example-field.ts')),
|
||||
).toBe(false);
|
||||
expect(
|
||||
await fs.pathExists(
|
||||
join(srcPath, 'logic-functions', 'hello-world.ts'),
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('should create only logic function when only that option is enabled', async () => {
|
||||
await copyBaseApplicationProject({
|
||||
appName: 'my-test-app',
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: {
|
||||
includeExampleObject: false,
|
||||
includeExampleField: false,
|
||||
includeExampleLogicFunction: true,
|
||||
includeExampleFrontComponent: false,
|
||||
includeExampleView: false,
|
||||
includeExampleNavigationMenuItem: false,
|
||||
},
|
||||
});
|
||||
|
||||
const srcPath = join(testAppDirectory, 'src');
|
||||
|
||||
expect(
|
||||
await fs.pathExists(
|
||||
join(srcPath, 'logic-functions', 'hello-world.ts'),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
await fs.pathExists(join(srcPath, 'objects', 'example-object.ts')),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('example object', () => {
|
||||
it('should create example-object.ts with defineObject and correct structure', async () => {
|
||||
await copyBaseApplicationProject({
|
||||
appName: 'my-test-app',
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const objectPath = join(
|
||||
testAppDirectory,
|
||||
'src',
|
||||
'objects',
|
||||
'example-object.ts',
|
||||
);
|
||||
|
||||
expect(await fs.pathExists(objectPath)).toBe(true);
|
||||
|
||||
const content = await fs.readFile(objectPath, 'utf8');
|
||||
|
||||
expect(content).toContain(
|
||||
"import { defineObject, FieldType } from 'twenty-sdk'",
|
||||
);
|
||||
expect(content).toContain('export default defineObject({');
|
||||
expect(content).toContain(
|
||||
'export const EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER',
|
||||
);
|
||||
expect(content).toContain('export const NAME_FIELD_UNIVERSAL_IDENTIFIER');
|
||||
expect(content).toContain("nameSingular: 'exampleItem'");
|
||||
expect(content).toContain("namePlural: 'exampleItems'");
|
||||
expect(content).toContain('FieldType.TEXT');
|
||||
expect(content).toContain(
|
||||
'labelIdentifierFieldMetadataUniversalIdentifier: NAME_FIELD_UNIVERSAL_IDENTIFIER',
|
||||
);
|
||||
});
|
||||
|
||||
it('should generate unique UUIDs for example objects across apps', async () => {
|
||||
const firstAppDir = join(testAppDirectory, 'app1');
|
||||
await fs.ensureDir(firstAppDir);
|
||||
await copyBaseApplicationProject({
|
||||
appName: 'app-one',
|
||||
appDisplayName: 'App One',
|
||||
appDescription: 'First app',
|
||||
appDirectory: firstAppDir,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const secondAppDir = join(testAppDirectory, 'app2');
|
||||
await fs.ensureDir(secondAppDir);
|
||||
await copyBaseApplicationProject({
|
||||
appName: 'app-two',
|
||||
appDisplayName: 'App Two',
|
||||
appDescription: 'Second app',
|
||||
appDirectory: secondAppDir,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const firstContent = await fs.readFile(
|
||||
join(firstAppDir, 'src', 'objects', 'example-object.ts'),
|
||||
'utf8',
|
||||
);
|
||||
const secondContent = await fs.readFile(
|
||||
join(secondAppDir, 'src', 'objects', 'example-object.ts'),
|
||||
'utf8',
|
||||
);
|
||||
|
||||
const uuidRegex =
|
||||
/EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER =\s*'([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})'/;
|
||||
const firstUuid = firstContent.match(uuidRegex)?.[1];
|
||||
const secondUuid = secondContent.match(uuidRegex)?.[1];
|
||||
|
||||
expect(firstUuid).toBeDefined();
|
||||
expect(secondUuid).toBeDefined();
|
||||
expect(firstUuid).not.toBe(secondUuid);
|
||||
});
|
||||
});
|
||||
|
||||
describe('example field', () => {
|
||||
it('should create example-field.ts with defineField referencing the object', async () => {
|
||||
await copyBaseApplicationProject({
|
||||
appName: 'my-test-app',
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const fieldPath = join(
|
||||
testAppDirectory,
|
||||
'src',
|
||||
'fields',
|
||||
'example-field.ts',
|
||||
);
|
||||
|
||||
expect(await fs.pathExists(fieldPath)).toBe(true);
|
||||
|
||||
const content = await fs.readFile(fieldPath, 'utf8');
|
||||
|
||||
expect(content).toContain(
|
||||
"import { defineField, FieldType } from 'twenty-sdk'",
|
||||
);
|
||||
expect(content).toContain(
|
||||
"import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/objects/example-object'",
|
||||
);
|
||||
expect(content).toContain('export default defineField({');
|
||||
expect(content).toContain(
|
||||
'objectUniversalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER',
|
||||
);
|
||||
expect(content).toContain('FieldType.NUMBER');
|
||||
expect(content).toContain("name: 'priority'");
|
||||
});
|
||||
});
|
||||
|
||||
describe('example view', () => {
|
||||
it('should create example-view.ts with defineView referencing the object', async () => {
|
||||
await copyBaseApplicationProject({
|
||||
appName: 'my-test-app',
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const viewPath = join(
|
||||
testAppDirectory,
|
||||
'src',
|
||||
'views',
|
||||
'example-view.ts',
|
||||
);
|
||||
|
||||
expect(await fs.pathExists(viewPath)).toBe(true);
|
||||
|
||||
const content = await fs.readFile(viewPath, 'utf8');
|
||||
|
||||
expect(content).toContain("import { defineView } from 'twenty-sdk'");
|
||||
expect(content).toContain(
|
||||
"import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/objects/example-object'",
|
||||
);
|
||||
expect(content).toContain('export default defineView({');
|
||||
expect(content).toContain(
|
||||
'objectUniversalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER',
|
||||
);
|
||||
expect(content).toContain("name: 'example-view'");
|
||||
});
|
||||
});
|
||||
|
||||
describe('example navigation menu item', () => {
|
||||
it('should create example-navigation-menu-item.ts with defineNavigationMenuItem', async () => {
|
||||
await copyBaseApplicationProject({
|
||||
appName: 'my-test-app',
|
||||
appDisplayName: 'My Test App',
|
||||
appDescription: 'A test application',
|
||||
appDirectory: testAppDirectory,
|
||||
exampleOptions: ALL_EXAMPLES,
|
||||
});
|
||||
|
||||
const navPath = join(
|
||||
testAppDirectory,
|
||||
'src',
|
||||
'navigation-menu-items',
|
||||
'example-navigation-menu-item.ts',
|
||||
);
|
||||
|
||||
expect(await fs.pathExists(navPath)).toBe(true);
|
||||
|
||||
const content = await fs.readFile(navPath, 'utf8');
|
||||
|
||||
expect(content).toContain(
|
||||
"import { defineNavigationMenuItem } from 'twenty-sdk'",
|
||||
);
|
||||
expect(content).toContain('export default defineNavigationMenuItem({');
|
||||
expect(content).toContain("name: 'example-navigation-menu-item'");
|
||||
expect(content).toContain("icon: 'IconList'");
|
||||
expect(content).toContain('position: 0');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,8 @@ import { join } from 'path';
|
||||
import { v4 } from 'uuid';
|
||||
import { ASSETS_DIR } from 'twenty-shared/application';
|
||||
|
||||
import { type ExampleOptions } from '@/types/scaffolding-options';
|
||||
|
||||
const SRC_FOLDER = 'src';
|
||||
|
||||
export const copyBaseApplicationProject = async ({
|
||||
@@ -10,11 +12,13 @@ export const copyBaseApplicationProject = async ({
|
||||
appDisplayName,
|
||||
appDescription,
|
||||
appDirectory,
|
||||
exampleOptions,
|
||||
}: {
|
||||
appName: string;
|
||||
appDisplayName: string;
|
||||
appDescription: string;
|
||||
appDirectory: string;
|
||||
exampleOptions: ExampleOptions;
|
||||
}) => {
|
||||
await fs.copy(join(__dirname, './constants/base-application'), appDirectory);
|
||||
|
||||
@@ -37,16 +41,58 @@ export const copyBaseApplicationProject = async ({
|
||||
fileName: 'default-role.ts',
|
||||
});
|
||||
|
||||
await createDefaultFrontComponent({
|
||||
appDirectory: sourceFolderPath,
|
||||
fileFolder: 'front-components',
|
||||
fileName: 'hello-world.tsx',
|
||||
});
|
||||
if (exampleOptions.includeExampleObject) {
|
||||
await createExampleObject({
|
||||
appDirectory: sourceFolderPath,
|
||||
fileFolder: 'objects',
|
||||
fileName: 'example-object.ts',
|
||||
});
|
||||
}
|
||||
|
||||
await createDefaultFunction({
|
||||
if (exampleOptions.includeExampleField) {
|
||||
await createExampleField({
|
||||
appDirectory: sourceFolderPath,
|
||||
fileFolder: 'fields',
|
||||
fileName: 'example-field.ts',
|
||||
});
|
||||
}
|
||||
|
||||
if (exampleOptions.includeExampleLogicFunction) {
|
||||
await createDefaultFunction({
|
||||
appDirectory: sourceFolderPath,
|
||||
fileFolder: 'logic-functions',
|
||||
fileName: 'hello-world.ts',
|
||||
});
|
||||
}
|
||||
|
||||
if (exampleOptions.includeExampleFrontComponent) {
|
||||
await createDefaultFrontComponent({
|
||||
appDirectory: sourceFolderPath,
|
||||
fileFolder: 'front-components',
|
||||
fileName: 'hello-world.tsx',
|
||||
});
|
||||
}
|
||||
|
||||
if (exampleOptions.includeExampleView) {
|
||||
await createExampleView({
|
||||
appDirectory: sourceFolderPath,
|
||||
fileFolder: 'views',
|
||||
fileName: 'example-view.ts',
|
||||
});
|
||||
}
|
||||
|
||||
if (exampleOptions.includeExampleNavigationMenuItem) {
|
||||
await createExampleNavigationMenuItem({
|
||||
appDirectory: sourceFolderPath,
|
||||
fileFolder: 'navigation-menu-items',
|
||||
fileName: 'example-navigation-menu-item.ts',
|
||||
});
|
||||
}
|
||||
|
||||
await createDefaultPostInstallFunction({
|
||||
appDirectory: sourceFolderPath,
|
||||
fileFolder: 'logic-functions',
|
||||
fileName: 'hello-world.ts',
|
||||
fileName: 'post-install.ts',
|
||||
});
|
||||
|
||||
await createApplicationConfig({
|
||||
@@ -196,7 +242,6 @@ const handler = async (): Promise<{ message: string }> => {
|
||||
return { message: 'Hello, World!' };
|
||||
};
|
||||
|
||||
// Logic function handler - rename and implement your logic
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: '${universalIdentifier}',
|
||||
name: 'hello-world-logic-function',
|
||||
@@ -215,6 +260,170 @@ export default defineLogicFunction({
|
||||
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
|
||||
};
|
||||
|
||||
const createDefaultPostInstallFunction = async ({
|
||||
appDirectory,
|
||||
fileFolder,
|
||||
fileName,
|
||||
}: {
|
||||
appDirectory: string;
|
||||
fileFolder?: string;
|
||||
fileName: string;
|
||||
}) => {
|
||||
const universalIdentifier = v4();
|
||||
|
||||
const content = `import { defineLogicFunction } from 'twenty-sdk';
|
||||
|
||||
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '${universalIdentifier}';
|
||||
|
||||
const handler = async (): Promise<void> => {
|
||||
console.log('Post install logic function executed successfully!');
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
name: 'post-install',
|
||||
description: 'Runs after installation to set up the application.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
`;
|
||||
|
||||
await fs.ensureDir(join(appDirectory, fileFolder ?? ''));
|
||||
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
|
||||
};
|
||||
|
||||
const createExampleObject = async ({
|
||||
appDirectory,
|
||||
fileFolder,
|
||||
fileName,
|
||||
}: {
|
||||
appDirectory: string;
|
||||
fileFolder?: string;
|
||||
fileName: string;
|
||||
}) => {
|
||||
const objectUniversalIdentifier = v4();
|
||||
const nameFieldUniversalIdentifier = v4();
|
||||
|
||||
const content = `import { defineObject, FieldType } from 'twenty-sdk';
|
||||
|
||||
export const EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER =
|
||||
'${objectUniversalIdentifier}';
|
||||
|
||||
export const NAME_FIELD_UNIVERSAL_IDENTIFIER =
|
||||
'${nameFieldUniversalIdentifier}';
|
||||
|
||||
export default defineObject({
|
||||
universalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER,
|
||||
nameSingular: 'exampleItem',
|
||||
namePlural: 'exampleItems',
|
||||
labelSingular: 'Example item',
|
||||
labelPlural: 'Example items',
|
||||
description: 'A sample custom object',
|
||||
icon: 'IconBox',
|
||||
labelIdentifierFieldMetadataUniversalIdentifier: NAME_FIELD_UNIVERSAL_IDENTIFIER,
|
||||
fields: [
|
||||
{
|
||||
universalIdentifier: NAME_FIELD_UNIVERSAL_IDENTIFIER,
|
||||
type: FieldType.TEXT,
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
description: 'Name of the example item',
|
||||
icon: 'IconAbc',
|
||||
},
|
||||
],
|
||||
});
|
||||
`;
|
||||
|
||||
await fs.ensureDir(join(appDirectory, fileFolder ?? ''));
|
||||
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
|
||||
};
|
||||
|
||||
const createExampleField = async ({
|
||||
appDirectory,
|
||||
fileFolder,
|
||||
fileName,
|
||||
}: {
|
||||
appDirectory: string;
|
||||
fileFolder?: string;
|
||||
fileName: string;
|
||||
}) => {
|
||||
const universalIdentifier = v4();
|
||||
|
||||
const content = `import { defineField, FieldType } from 'twenty-sdk';
|
||||
import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/objects/example-object';
|
||||
|
||||
export default defineField({
|
||||
objectUniversalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER,
|
||||
universalIdentifier: '${universalIdentifier}',
|
||||
type: FieldType.NUMBER,
|
||||
name: 'priority',
|
||||
label: 'Priority',
|
||||
description: 'Priority level for the example item (1-10)',
|
||||
});
|
||||
`;
|
||||
|
||||
await fs.ensureDir(join(appDirectory, fileFolder ?? ''));
|
||||
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
|
||||
};
|
||||
|
||||
const createExampleView = async ({
|
||||
appDirectory,
|
||||
fileFolder,
|
||||
fileName,
|
||||
}: {
|
||||
appDirectory: string;
|
||||
fileFolder?: string;
|
||||
fileName: string;
|
||||
}) => {
|
||||
const universalIdentifier = v4();
|
||||
|
||||
const content = `import { defineView } from 'twenty-sdk';
|
||||
import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/objects/example-object';
|
||||
|
||||
export default defineView({
|
||||
universalIdentifier: '${universalIdentifier}',
|
||||
name: 'example-view',
|
||||
objectUniversalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER,
|
||||
icon: 'IconList',
|
||||
position: 0,
|
||||
});
|
||||
`;
|
||||
|
||||
await fs.ensureDir(join(appDirectory, fileFolder ?? ''));
|
||||
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
|
||||
};
|
||||
|
||||
const createExampleNavigationMenuItem = async ({
|
||||
appDirectory,
|
||||
fileFolder,
|
||||
fileName,
|
||||
}: {
|
||||
appDirectory: string;
|
||||
fileFolder?: string;
|
||||
fileName: string;
|
||||
}) => {
|
||||
const universalIdentifier = v4();
|
||||
|
||||
const content = `import { defineNavigationMenuItem } from 'twenty-sdk';
|
||||
|
||||
export default defineNavigationMenuItem({
|
||||
universalIdentifier: '${universalIdentifier}',
|
||||
name: 'example-navigation-menu-item',
|
||||
icon: 'IconList',
|
||||
position: 0,
|
||||
// Link to a view:
|
||||
// viewUniversalIdentifier: '...',
|
||||
// Or link to an object:
|
||||
// targetObjectUniversalIdentifier: '...',
|
||||
// Or link to an external URL:
|
||||
// link: 'https://example.com',
|
||||
});
|
||||
`;
|
||||
|
||||
await fs.ensureDir(join(appDirectory, fileFolder ?? ''));
|
||||
await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content);
|
||||
};
|
||||
|
||||
const createApplicationConfig = async ({
|
||||
displayName,
|
||||
description,
|
||||
@@ -230,12 +439,14 @@ const createApplicationConfig = async ({
|
||||
}) => {
|
||||
const content = `import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '${v4()}',
|
||||
displayName: '${displayName}',
|
||||
description: '${description ?? ''}',
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
`;
|
||||
|
||||
@@ -261,23 +472,12 @@ const createPackageJson = async ({
|
||||
},
|
||||
packageManager: 'yarn@4.9.2',
|
||||
scripts: {
|
||||
'auth:login': 'twenty auth:login',
|
||||
'auth:logout': 'twenty auth:logout',
|
||||
'auth:status': 'twenty auth:status',
|
||||
'auth:switch': 'twenty auth:switch',
|
||||
'auth:list': 'twenty auth:list',
|
||||
'app:dev': 'twenty app:dev',
|
||||
'entity:add': 'twenty entity:add',
|
||||
'app:generate': 'twenty app:generate',
|
||||
'function:logs': 'twenty function:logs',
|
||||
'function:execute': 'twenty function:execute',
|
||||
'app:uninstall': 'twenty app:uninstall',
|
||||
help: 'twenty help',
|
||||
twenty: 'twenty',
|
||||
lint: 'eslint',
|
||||
'lint:fix': 'eslint --fix',
|
||||
},
|
||||
dependencies: {
|
||||
'twenty-sdk': '0.5.2',
|
||||
'twenty-sdk': 'latest',
|
||||
},
|
||||
devDependencies: {
|
||||
typescript: '^5.9.3',
|
||||
|
||||
@@ -82,13 +82,11 @@ export default defineConfig(() => {
|
||||
return true;
|
||||
}
|
||||
|
||||
const deps = Object.entries(
|
||||
const deps = Object.keys(
|
||||
(packageJson as PackageJson).dependencies || {},
|
||||
).filter(([_, version]) => !version?.startsWith('workspace:'));
|
||||
|
||||
return deps.some(
|
||||
([dep, _]) => id === dep || id.startsWith(dep + '/'),
|
||||
);
|
||||
|
||||
return deps.some((dep) => id === dep || id.startsWith(dep + '/'));
|
||||
},
|
||||
output: [
|
||||
{
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
},
|
||||
"scripts": {
|
||||
"auth": "twenty auth login",
|
||||
"generate": "twenty app generate",
|
||||
"dev": "twenty app dev",
|
||||
"sync": "twenty app sync",
|
||||
"uninstall": "twenty app uninstall",
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
},
|
||||
"scripts": {
|
||||
"auth": "twenty auth login",
|
||||
"generate": "twenty app generate",
|
||||
"dev": "twenty app dev",
|
||||
"sync": "twenty app sync",
|
||||
"uninstall": "twenty app uninstall",
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
},
|
||||
"scripts": {
|
||||
"auth": "twenty auth login",
|
||||
"generate": "twenty app generate",
|
||||
"dev": "twenty app dev",
|
||||
"sync": "twenty app sync",
|
||||
"uninstall": "twenty app uninstall",
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"scripts": {
|
||||
"create-entity": "twenty app add",
|
||||
"dev": "twenty app dev",
|
||||
"generate": "twenty app generate",
|
||||
"sync": "twenty app sync",
|
||||
"uninstall": "twenty app uninstall",
|
||||
"auth": "twenty auth login"
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
"app:dev": "twenty app dev",
|
||||
"app:sync": "twenty app sync",
|
||||
"entity:add": "twenty entity add",
|
||||
"app:generate": "twenty app generate",
|
||||
"function:logs": "twenty function logs",
|
||||
"function:execute": "twenty function execute",
|
||||
"app:uninstall": "twenty app uninstall",
|
||||
|
||||
@@ -26,7 +26,7 @@ Apps let you build and manage Twenty customizations **as code**. Instead of conf
|
||||
Create a new app using the official scaffolder, then authenticate and start developing:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Scaffold a new app
|
||||
# Scaffold a new app (includes all examples by default)
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
cd my-twenty-app
|
||||
|
||||
@@ -35,32 +35,45 @@ corepack enable
|
||||
yarn install
|
||||
|
||||
# Authenticate using your API key (you'll be prompted)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Start dev mode: automatically syncs local changes to your workspace
|
||||
yarn app:dev
|
||||
yarn twenty app:dev
|
||||
```
|
||||
|
||||
The scaffolder supports three modes for controlling which example files are included:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Default (exhaustive): all examples (object, field, logic function, front component, view, navigation menu item)
|
||||
npx create-twenty-app@latest my-app
|
||||
|
||||
# Minimal: only core files (application-config.ts and default-role.ts)
|
||||
npx create-twenty-app@latest my-app --minimal
|
||||
|
||||
# Interactive: select which examples to include
|
||||
npx create-twenty-app@latest my-app --interactive
|
||||
```
|
||||
|
||||
From here you can:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn entity:add
|
||||
|
||||
# Generate a typed Twenty client and workspace entity types
|
||||
yarn app:generate
|
||||
yarn twenty entity:add
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn function:logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function by name
|
||||
yarn function:execute -n my-function -p '{"name": "test"}'
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn app:uninstall
|
||||
yarn twenty app:uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn help
|
||||
yarn twenty 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).
|
||||
@@ -72,9 +85,9 @@ When you run `npx create-twenty-app@latest my-twenty-app`, the scaffolder:
|
||||
- Copies a minimal base application into `my-twenty-app/`
|
||||
- Adds a local `twenty-sdk` dependency and Yarn 4 configuration
|
||||
- Creates config files and scripts wired to the `twenty` CLI
|
||||
- Generates a default application config and a default function role
|
||||
- Generates core files (application config, default function role, post-install function) plus example files based on the scaffolding mode
|
||||
|
||||
A freshly scaffolded app looks like this:
|
||||
A freshly scaffolded app with the default `--exhaustive` mode looks like this:
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -93,15 +106,26 @@ my-twenty-app/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── objects/
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
├── fields/
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
├── logic-functions/
|
||||
│ └── hello-world.ts # Example logic function
|
||||
└── front-components/
|
||||
└── hello-world.tsx # Example front component
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
└── navigation-menu-items/
|
||||
└── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
```
|
||||
|
||||
With `--minimal`, only the core files are created (`application-config.ts`, `roles/default-role.ts`, and `logic-functions/post-install.ts`). With `--interactive`, you choose which example files to include.
|
||||
|
||||
At a high level:
|
||||
|
||||
- **package.json**: Declares the app name, version, engines (Node 24+, Yarn 4), and adds `twenty-sdk` plus scripts like `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall`, and authentication commands that delegate to the local `twenty` CLI.
|
||||
- **package.json**: Declares the app name, version, engines (Node 24+, Yarn 4), and adds `twenty-sdk` plus a `twenty` script that delegates to the local `twenty` CLI. Run `yarn twenty help` to list all available commands.
|
||||
- **.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.
|
||||
@@ -121,6 +145,8 @@ The SDK detects entities by parsing your TypeScript files for **`export default
|
||||
| `defineFrontComponent()` | Front component definitions |
|
||||
| `defineRole()` | Role definitions |
|
||||
| `defineField()` | Field extensions for existing objects |
|
||||
| `defineView()` | Saved view definitions |
|
||||
| `defineNavigationMenuItem()` | Navigation menu item definitions |
|
||||
|
||||
<Note>
|
||||
**File naming is flexible.** Entity detection is AST-based — the SDK scans your source files for the `export default define<Entity>({...})` pattern. You can organize your files and folders however you like. Grouping by entity type (e.g., `logic-functions/`, `roles/`) is just a convention for code organization, not a requirement.
|
||||
@@ -140,12 +166,12 @@ export default defineObject({
|
||||
|
||||
Later commands will add more files and folders:
|
||||
|
||||
- `yarn app:generate` will create a `generated/` folder (typed Twenty client + workspace types).
|
||||
- `yarn entity:add` will add entity definition files under `src/` for your custom objects, functions, front components, or roles.
|
||||
- `yarn twenty app:dev` will auto-generate a typed API client in `node_modules/twenty-sdk/generated` (typed Twenty client + workspace types).
|
||||
- `yarn twenty entity:add` will add entity definition files under `src/` for your custom objects, functions, front components, or roles.
|
||||
|
||||
## Authentication
|
||||
|
||||
The first time you run `yarn auth:login`, you'll be prompted for:
|
||||
The first time you run `yarn twenty auth:login`, you'll be prompted for:
|
||||
|
||||
- API URL (defaults to http://localhost:3000 or your current workspace profile)
|
||||
- API key
|
||||
@@ -156,25 +182,25 @@ Your credentials are stored per-user in `~/.twenty/config.json`. You can maintai
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn auth:login --workspace my-custom-workspace
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
|
||||
# List all configured workspaces
|
||||
yarn auth:list
|
||||
yarn twenty auth:list
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn auth:switch
|
||||
yarn twenty auth:switch
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn auth:switch production
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn auth:status
|
||||
yarn twenty auth:status
|
||||
```
|
||||
|
||||
Once you've switched workspaces with `auth:switch`, all subsequent commands will use that workspace by default. You can still override it temporarily with `--workspace <name>`.
|
||||
Once you've switched workspaces with `yarn twenty auth:switch`, all subsequent commands will use that workspace by default. You can still override it temporarily with `--workspace <name>`.
|
||||
|
||||
## Use the SDK resources (types & config)
|
||||
|
||||
@@ -192,6 +218,8 @@ The SDK provides helper functions for defining your app entities. As described i
|
||||
| `defineFrontComponent()` | Define front components for custom UI |
|
||||
| `defineRole()` | Configure role permissions and object access |
|
||||
| `defineField()` | Extend existing objects with additional fields |
|
||||
| `defineView()` | Define saved views for objects |
|
||||
| `defineNavigationMenuItem()` | Define sidebar navigation links |
|
||||
|
||||
These functions validate your configuration at build time and provide IDE autocompletion and type safety.
|
||||
|
||||
@@ -274,10 +302,14 @@ Key points:
|
||||
- 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 entity:add`, which guides you through naming, fields, and relationships.
|
||||
- You can scaffold new objects using `yarn twenty entity:add`, which guides you through naming, fields, and relationships.
|
||||
|
||||
<Note>
|
||||
**Base fields are created automatically.** When you define a custom object, Twenty automatically adds standard fields such as `name`, `createdAt`, `updatedAt`, `createdBy`, `position`, and `deletedAt`. You don't need to define these in your `fields` array — only add your custom fields.
|
||||
**Base fields are created automatically.** When you define a custom object, Twenty automatically adds standard fields
|
||||
such as `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` and `deletedAt`.
|
||||
You don't need to define these in your `fields` array — only add your custom fields.
|
||||
You can override default fields by defining a field with the same name in your `fields` array,
|
||||
but this is not recommended.
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -288,6 +320,7 @@ Every app has a single `application-config.ts` file that describes:
|
||||
- **Who the app is**: identifiers, display name, and description.
|
||||
- **How its functions run**: which role they use for permissions.
|
||||
- **(Optional) variables**: key–value pairs exposed to your functions as environment variables.
|
||||
- **(Optional) post-install function**: a logic function that runs after the app is installed.
|
||||
|
||||
Use `defineApplication()` to define your application configuration:
|
||||
|
||||
@@ -295,6 +328,7 @@ Use `defineApplication()` to define your application configuration:
|
||||
// src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
@@ -310,6 +344,7 @@ export default defineApplication({
|
||||
},
|
||||
},
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -317,6 +352,7 @@ Notes:
|
||||
- `universalIdentifier` fields are deterministic IDs you own; generate them once and keep them stable across syncs.
|
||||
- `applicationVariables` become environment variables for your functions (for example, `DEFAULT_RECIPIENT_NAME` is available as `process.env.DEFAULT_RECIPIENT_NAME`).
|
||||
- `defaultRoleUniversalIdentifier` must match the role file (see below).
|
||||
- `postInstallLogicFunctionUniversalIdentifier` (optional) points to a logic function that runs automatically after the app is installed. See [Post-install functions](#post-install-functions).
|
||||
|
||||
#### Roles and permissions
|
||||
|
||||
@@ -449,6 +485,54 @@ Notes:
|
||||
- The `triggers` array is optional. Functions without triggers can be used as utility functions called by other functions.
|
||||
- You can mix multiple trigger types in a single function.
|
||||
|
||||
### Post-install functions
|
||||
|
||||
A post-install function is a logic function that runs automatically after your app is installed on a workspace. This is useful for one-time setup tasks such as seeding default data, creating initial records, or configuring workspace settings.
|
||||
|
||||
When you scaffold a new app with `create-twenty-app`, a post-install function is generated for you at `src/logic-functions/post-install.ts`:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/post-install.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
|
||||
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
|
||||
|
||||
const handler = async (): Promise<void> => {
|
||||
console.log('Post install logic function executed successfully!');
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
name: 'post-install',
|
||||
description: 'Runs after installation to set up the application.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
The function is wired into your app by referencing its universal identifier in `application-config.ts`:
|
||||
|
||||
```typescript
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
// ...
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
You can also manually execute the post-install function at any time using the CLI:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty function:execute --postInstall
|
||||
```
|
||||
|
||||
Key points:
|
||||
- Post-install functions are standard logic functions — they use `defineLogicFunction()` like any other function.
|
||||
- The `postInstallLogicFunctionUniversalIdentifier` field in `defineApplication()` is optional. If omitted, no function runs after installation.
|
||||
- The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
|
||||
- Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `function:execute --postInstall`.
|
||||
|
||||
### Route trigger payload
|
||||
|
||||
<Warning>
|
||||
@@ -541,9 +625,74 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
You can create new functions in two ways:
|
||||
|
||||
- **Scaffolded**: Run `yarn entity:add` and choose the option to add a new logic function. This generates a starter file with a handler and config.
|
||||
- **Scaffolded**: Run `yarn twenty entity:add` and choose the option to add a new logic function. This generates a starter file with a handler and config.
|
||||
- **Manual**: Create a new `*.logic-function.ts` file and use `defineLogicFunction()`, following the same pattern.
|
||||
|
||||
### Marking a logic function as a tool
|
||||
|
||||
Logic functions can be exposed as **tools** for AI agents and workflows. When a function is marked as a tool, it becomes discoverable by Twenty's AI features and can be selected as a step in workflow automations.
|
||||
|
||||
To mark a logic function as a tool, set `isTool: true` and provide a `toolInputSchema` describing the expected input parameters using [JSON Schema](https://json-schema.org/):
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/enrich-company.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import Twenty from '~/generated';
|
||||
|
||||
const handler = async (params: { companyName: string; domain?: string }) => {
|
||||
const client = new Twenty();
|
||||
|
||||
const result = await client.mutation({
|
||||
createTask: {
|
||||
__args: {
|
||||
data: {
|
||||
title: `Enrich data for ${params.companyName}`,
|
||||
body: `Domain: ${params.domain ?? 'unknown'}`,
|
||||
},
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
return { taskId: result.createTask.id };
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
|
||||
name: 'enrich-company',
|
||||
description: 'Enrich a company record with external data',
|
||||
timeoutSeconds: 10,
|
||||
handler,
|
||||
isTool: true,
|
||||
toolInputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
companyName: {
|
||||
type: 'string',
|
||||
description: 'The name of the company to enrich',
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
description: 'The company website domain (optional)',
|
||||
},
|
||||
},
|
||||
required: ['companyName'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Key points:
|
||||
|
||||
- **`isTool`** (`boolean`, default: `false`): When set to `true`, the function is registered as a tool and becomes available to AI agents and workflow automations.
|
||||
- **`toolInputSchema`** (`object`, optional): A JSON Schema object that describes the parameters your function accepts. AI agents use this schema to understand what inputs the tool expects and to validate calls. If omitted, the schema defaults to `{ type: 'object', properties: {} }` (no parameters).
|
||||
- Functions with `isTool: false` (or unset) are **not** exposed as tools. They can still be executed directly or called by other functions, but will not appear in tool discovery.
|
||||
- **Tool naming**: When exposed as a tool, the function name is automatically normalized to `logic_function_<name>` (lowercased, non-alphanumeric characters replaced with underscores). For example, `enrich-company` becomes `logic_function_enrich_company`.
|
||||
- You can combine `isTool` with triggers — a function can be both a tool (callable by AI agents) and triggered by events (cron, database events, routes) at the same time.
|
||||
|
||||
<Note>
|
||||
**Write a good `description`.** AI agents rely on the function's `description` field to decide when to use the tool. Be specific about what the tool does and when it should be called.
|
||||
</Note>
|
||||
|
||||
### Front components
|
||||
|
||||
Front components let you build custom React components that render within Twenty's UI. Use `defineFrontComponent()` to define components with built-in validation:
|
||||
@@ -573,16 +722,16 @@ Key points:
|
||||
- Front components are React components that render in isolated contexts within Twenty.
|
||||
- Use the `*.front-component.tsx` file suffix for automatic detection.
|
||||
- The `component` field references your React component.
|
||||
- Components are built and synced automatically during `yarn app:dev`.
|
||||
- Components are built and synced automatically during `yarn twenty app:dev`.
|
||||
|
||||
You can create new front components in two ways:
|
||||
|
||||
- **Scaffolded**: Run `yarn entity:add` and choose the option to add a new front component.
|
||||
- **Scaffolded**: Run `yarn twenty entity:add` and choose the option to add a new front component.
|
||||
- **Manual**: Create a new `*.front-component.tsx` file and use `defineFrontComponent()`.
|
||||
|
||||
### Generated typed client
|
||||
|
||||
Run yarn app:generate to create a local typed client in generated/ based on your workspace schema. Use it in your functions:
|
||||
The typed client is auto-generated by `yarn twenty app:dev` and stored in `node_modules/twenty-sdk/generated` based on your workspace schema. Use it in your functions:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -591,7 +740,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
The client is re-generated by `yarn app:generate`. Re-run after changing your objects or when onboarding to a new workspace.
|
||||
The client is re-generated automatically by `yarn twenty app:dev` whenever your objects or fields change.
|
||||
|
||||
#### Runtime credentials in logic functions
|
||||
|
||||
@@ -612,40 +761,29 @@ Explore a minimal, end-to-end example that demonstrates objects, logic functions
|
||||
|
||||
## Manual setup (without the scaffolder)
|
||||
|
||||
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:
|
||||
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 a single script in your package.json:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
```
|
||||
|
||||
Then add scripts like these:
|
||||
Then add a `twenty` script:
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
"auth:login": "twenty auth:login",
|
||||
"auth:logout": "twenty auth:logout",
|
||||
"auth:status": "twenty auth:status",
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
"function:execute": "twenty function:execute",
|
||||
"help": "twenty help"
|
||||
"twenty": "twenty"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now you can run the same commands via Yarn, e.g. `yarn app:dev`, `yarn app:generate`, etc.
|
||||
Now you can run all commands via `yarn twenty <command>`, e.g. `yarn twenty app:dev`, `yarn twenty help`, etc.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Authentication errors: run `yarn auth:login` and ensure your API key has the required permissions.
|
||||
- Authentication errors: run `yarn twenty auth:login` and ensure your API key has the required permissions.
|
||||
- Cannot connect to server: verify the API URL and that the Twenty server is reachable.
|
||||
- Types or client missing/outdated: run `yarn app:generate`.
|
||||
- Dev mode not syncing: ensure `yarn app:dev` is running and that changes are not ignored by your environment.
|
||||
- Types or client missing/outdated: restart `yarn twenty app:dev` — it auto-generates the typed client.
|
||||
- Dev mode not syncing: ensure `yarn twenty app:dev` is running and that changes are not ignored by your environment.
|
||||
|
||||
Discord Help Channel: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -36,32 +36,32 @@ corepack enable
|
||||
yarn install
|
||||
|
||||
# قم بالمصادقة باستخدام مفتاح واجهة برمجة التطبيقات الخاص بك (سيُطلب منك ذلك)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# ابدأ وضع التطوير: يُزامن التغييرات المحلية تلقائيًا مع مساحة العمل الخاصة بك
|
||||
yarn app:dev
|
||||
yarn twenty app:dev
|
||||
```
|
||||
|
||||
من هنا يمكنك:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn entity:add
|
||||
|
||||
# Generate a typed Twenty client and workspace entity types
|
||||
yarn app:generate
|
||||
yarn twenty entity:add
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn function:logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function by name
|
||||
yarn function:execute -n my-function -p '{"name": "test"}'
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn app:uninstall
|
||||
yarn twenty app:uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn help
|
||||
yarn twenty help
|
||||
```
|
||||
|
||||
راجع أيضًا: صفحات مرجع CLI لـ [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) و[twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
@@ -73,7 +73,7 @@ yarn help
|
||||
* ينسخ تطبيقًا أساسيًا مصغّرًا إلى `my-twenty-app/`
|
||||
* يضيف اعتمادًا محليًا `twenty-sdk` وتهيئة Yarn 4
|
||||
* ينشئ ملفات ضبط ونصوصًا مرتبطة بـ `twenty` CLI
|
||||
* يُولّد ضبطًا افتراضيًا للتطبيق ودورًا افتراضيًا للوظيفة
|
||||
* Generates a default application config, a default function role, and a post-install function
|
||||
|
||||
يبدو التطبيق المُنشأ حديثًا بالقالب كما يلي:
|
||||
|
||||
@@ -89,20 +89,21 @@ my-twenty-app/
|
||||
eslint.config.mjs
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # مجلد الأصول العامة (صور، خطوط، إلخ)
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # مطلوب - التكوين الرئيسي للتطبيق
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── roles/
|
||||
│ └── default-role.ts # الدور الافتراضي لوظائف المنطق
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── logic-functions/
|
||||
│ └── hello-world.ts # مثال لوظيفة منطقية
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
└── front-components/
|
||||
└── hello-world.tsx # مثال لمكوّن الواجهة الأمامية
|
||||
└── hello-world.tsx # Example front component
|
||||
```
|
||||
|
||||
بشكل عام:
|
||||
|
||||
* **package.json**: يصرّح باسم التطبيق والإصدار والمحرّكات (Node 24+، Yarn 4)، ويضيف `twenty-sdk` فضلًا عن نصوص مثل `app:dev` و`app:generate` و`entity:add` و`function:logs` و`function:execute` و`app:uninstall` وأوامر المصادقة التي تُفوِّض إلى `twenty` CLI المحلي.
|
||||
* **package.json**: يصرّح باسم التطبيق والإصدار والمحرّكات (Node 24+، Yarn 4)، ويضيف `twenty-sdk` بالإضافة إلى نص برمجي `twenty` يفوِّض إلى `twenty` CLI المحلي. شغِّل `yarn twenty help` لعرض جميع الأوامر المتاحة.
|
||||
* **.gitignore**: يتجاهل العناصر الشائعة مثل `node_modules` و`.yarn` و`generated/` (عميل مضبوط الأنواع) و`dist/` و`build/` ومجلدات التغطية وملفات السجلات وملفات `.env*`.
|
||||
* **yarn.lock**، **.yarnrc.yml**، **.yarn/**: تقوم بقفل وتكوين حزمة أدوات Yarn 4 المستخدمة في المشروع.
|
||||
* **.nvmrc**: يثبّت إصدار Node.js المتوقع للمشروع.
|
||||
@@ -142,12 +143,12 @@ export default defineObject({
|
||||
|
||||
ستضيف الأوامر اللاحقة مزيدًا من الملفات والمجلدات:
|
||||
|
||||
* `yarn app:generate` سيُنشئ مجلدًا `generated/` (عميل Twenty مضبوط الأنواع + أنواع مساحة العمل).
|
||||
* `yarn entity:add` سيضيف ملفات تعريف الكيانات تحت `src/` لكائناتك المخصصة أو الوظائف أو المكونات الواجهية أو الأدوار.
|
||||
* `yarn twenty app:dev` سيولّد تلقائيًا عميل API مضبوط الأنواع في `node_modules/twenty-sdk/generated` (عميل Twenty مضبوط الأنواع + أنواع مساحة العمل).
|
||||
* `yarn twenty entity:add` سيضيف ملفات تعريف الكيانات تحت `src/` لكائناتك المخصصة أو الوظائف أو المكونات الواجهية أو الأدوار.
|
||||
|
||||
## المصادقة
|
||||
|
||||
في المرة الأولى التي تشغّل فيها `yarn auth:login`، سيُطلب منك إدخال:
|
||||
في المرة الأولى التي تشغّل فيها `yarn twenty auth:login`، سيُطلب منك إدخال:
|
||||
|
||||
* عنوان URL لواجهة برمجة التطبيقات (الافتراضي http://localhost:3000 أو ملف تعريف مساحة العمل الحالية لديك)
|
||||
* مفتاح واجهة برمجة التطبيقات
|
||||
@@ -157,26 +158,26 @@ export default defineObject({
|
||||
### Managing workspaces
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn auth:login
|
||||
# تسجيل الدخول تفاعليًا (مُوصى به)
|
||||
yarn twenty auth:login
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn auth:login --workspace my-custom-workspace
|
||||
# تسجيل الدخول إلى ملف تعريف لمساحة عمل محددة
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
|
||||
# List all configured workspaces
|
||||
yarn auth:list
|
||||
# عرض جميع مساحات العمل المُكوَّنة
|
||||
yarn twenty auth:list
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn auth:switch
|
||||
# تبديل مساحة العمل الافتراضية (تفاعليًا)
|
||||
yarn twenty auth:switch
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn auth:switch production
|
||||
# التبديل إلى مساحة عمل محددة
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn auth:status
|
||||
# التحقق من حالة المصادقة الحالية
|
||||
yarn twenty auth:status
|
||||
```
|
||||
|
||||
Once you've switched workspaces with `auth:switch`, all subsequent commands will use that workspace by default. You can still override it temporarily with `--workspace <name>`.
|
||||
بمجرد أن تقوم بالتبديل بين مساحات العمل باستخدام `yarn twenty auth:switch`، ستستخدم جميع الأوامر اللاحقة تلك المساحة افتراضيًا. You can still override it temporarily with `--workspace <name>`.
|
||||
|
||||
## استخدم موارد SDK (الأنواع والتكوين)
|
||||
|
||||
@@ -276,10 +277,14 @@ export default defineObject({
|
||||
* `universalIdentifier` يجب أن يكون فريدًا وثابتًا عبر عمليات النشر.
|
||||
* يتطلب كل حقل `name` و`type` و`label` ومعرّف `universalIdentifier` ثابتًا خاصًا به.
|
||||
* المصفوفة `fields` اختيارية — يمكنك تعريف كائنات بدون حقول مخصصة.
|
||||
* يمكنك إنشاء كائنات جديدة باستخدام `yarn entity:add`، والذي يرشدك خلال التسمية والحقول والعلاقات.
|
||||
* يمكنك إنشاء كائنات جديدة باستخدام `yarn twenty entity:add`، والذي يرشدك خلال التسمية والحقول والعلاقات.
|
||||
|
||||
<Note>
|
||||
**يتم إنشاء الحقول الأساسية تلقائيًا.** عند تعريف كائن مخصص، يضيف Twenty تلقائيًا حقولًا قياسية مثل `name` و`createdAt` و`updatedAt` و`createdBy` و`position` و`deletedAt`. لا تحتاج إلى تعريف هذه في مصفوفة `fields` — أضف فقط حقولك المخصصة.
|
||||
**يتم إنشاء الحقول الأساسية تلقائيًا.** عند تعريف كائن مخصص، يضيف Twenty تلقائيًا حقولًا قياسية
|
||||
مثل `id` و`name` و`createdAt` و`updatedAt` و`createdBy` و`updatedBy` و`deletedAt`.
|
||||
لا تحتاج إلى تعريف هذه في مصفوفة `fields` — أضف فقط حقولك المخصصة.
|
||||
يمكنك تجاوز الحقول الافتراضية من خلال تعريف حقل بالاسم نفسه في مصفوفة `fields` الخاصة بك،
|
||||
لكن هذا غير مستحسن.
|
||||
</Note>
|
||||
|
||||
### تكوين التطبيق (application-config.ts)
|
||||
@@ -289,6 +294,7 @@ export default defineObject({
|
||||
* **هوية التطبيق**: المعرفات، اسم العرض، والوصف.
|
||||
* **كيفية تشغيل وظائفه**: الدور الذي تستخدمه للأذونات.
|
||||
* **متغيرات (اختياري)**: أزواج مفتاح-قيمة تُعرض لوظائفك كمتغيرات بيئة.
|
||||
* **(Optional) post-install function**: a logic function that runs after the app is installed.
|
||||
|
||||
Use `defineApplication()` to define your application configuration:
|
||||
|
||||
@@ -296,6 +302,7 @@ Use `defineApplication()` to define your application configuration:
|
||||
// src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
@@ -311,6 +318,7 @@ export default defineApplication({
|
||||
},
|
||||
},
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -319,6 +327,7 @@ export default defineApplication({
|
||||
* حقول `universalIdentifier` هي معرّفات حتمية تخصك؛ أنشئها مرة واحدة واحتفظ بها ثابتة عبر عمليات المزامنة.
|
||||
* `applicationVariables` تصبح متغيرات بيئة لوظائفك (على سبيل المثال، `DEFAULT_RECIPIENT_NAME` متاح كـ `process.env.DEFAULT_RECIPIENT_NAME`).
|
||||
* `defaultRoleUniversalIdentifier` يجب أن يطابق ملف الدور (انظر أدناه).
|
||||
* `postInstallLogicFunctionUniversalIdentifier` (optional) points to a logic function that runs automatically after the app is installed. See [Post-install functions](#post-install-functions).
|
||||
|
||||
#### الأدوار والصلاحيات
|
||||
|
||||
@@ -457,6 +466,55 @@ export default defineLogicFunction({
|
||||
* المصفوفة `triggers` اختيارية. يمكن استخدام الوظائف بدون مشغلات كوظائف مساعدة تُستدعى بواسطة وظائف أخرى.
|
||||
* يمكنك مزج أنواع متعددة من المشغلات في وظيفة واحدة.
|
||||
|
||||
### Post-install functions
|
||||
|
||||
A post-install function is a logic function that runs automatically after your app is installed on a workspace. This is useful for one-time setup tasks such as seeding default data, creating initial records, or configuring workspace settings.
|
||||
|
||||
When you scaffold a new app with `create-twenty-app`, a post-install function is generated for you at `src/logic-functions/post-install.ts`:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/post-install.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
|
||||
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
|
||||
|
||||
const handler = async (): Promise<void> => {
|
||||
console.log('Post install logic function executed successfully!');
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
name: 'post-install',
|
||||
description: 'Runs after installation to set up the application.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
The function is wired into your app by referencing its universal identifier in `application-config.ts`:
|
||||
|
||||
```typescript
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
// ...
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
You can also manually execute the post-install function at any time using the CLI:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty function:execute --postInstall
|
||||
```
|
||||
|
||||
النقاط الرئيسية:
|
||||
|
||||
* Post-install functions are standard logic functions — they use `defineLogicFunction()` like any other function.
|
||||
* The `postInstallLogicFunctionUniversalIdentifier` field in `defineApplication()` is optional. If omitted, no function runs after installation.
|
||||
* The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `function:execute --postInstall`.
|
||||
|
||||
### حمولة مشغل المسار
|
||||
|
||||
<Warning>
|
||||
@@ -551,9 +609,74 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
يمكنك إنشاء وظائف جديدة بطريقتين:
|
||||
|
||||
* **مُنشأ بالقالب**: شغّل `yarn entity:add` واختر خيار إضافة وظيفة منطقية جديدة. يُولّد هذا ملفًا مبدئيًا مع معالج وتكوين.
|
||||
* **مُنشأ بالقالب**: شغّل `yarn twenty entity:add` واختر خيار إضافة وظيفة منطقية جديدة. يُولّد هذا ملفًا مبدئيًا مع معالج وتكوين.
|
||||
* **يدوي**: أنشئ ملفًا جديدًا `*.logic-function.ts` واستخدم `defineLogicFunction()` مع اتباع النمط نفسه.
|
||||
|
||||
### تمييز دالة منطقية كأداة
|
||||
|
||||
يمكن إتاحة الدوال المنطقية بوصفها **أدوات** لوكلاء الذكاء الاصطناعي وسير العمل. عندما يتم تمييز دالة كأداة، تصبح قابلة للاكتشاف بواسطة ميزات الذكاء الاصطناعي الخاصة بـ Twenty ويمكن اختيارها كخطوة في أتمتة سير العمل.
|
||||
|
||||
لتمييز دالة منطقية كأداة، عيّن `isTool: true` وقدّم `toolInputSchema` يصف معاملات الإدخال المتوقعة باستخدام [مخطط JSON](https://json-schema.org/):
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/enrich-company.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import Twenty from '~/generated';
|
||||
|
||||
const handler = async (params: { companyName: string; domain?: string }) => {
|
||||
const client = new Twenty();
|
||||
|
||||
const result = await client.mutation({
|
||||
createTask: {
|
||||
__args: {
|
||||
data: {
|
||||
title: `Enrich data for ${params.companyName}`,
|
||||
body: `Domain: ${params.domain ?? 'unknown'}`,
|
||||
},
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
return { taskId: result.createTask.id };
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
|
||||
name: 'enrich-company',
|
||||
description: 'Enrich a company record with external data',
|
||||
timeoutSeconds: 10,
|
||||
handler,
|
||||
isTool: true,
|
||||
toolInputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
companyName: {
|
||||
type: 'string',
|
||||
description: 'The name of the company to enrich',
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
description: 'The company website domain (optional)',
|
||||
},
|
||||
},
|
||||
required: ['companyName'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
النقاط الرئيسية:
|
||||
|
||||
* **`isTool`** (`boolean`, الافتراضي: `false`): عند ضبطه على `true`، يتم تسجيل الدالة كأداة وتصبح متاحة لوكلاء الذكاء الاصطناعي ولأتمتة سير العمل.
|
||||
* **`toolInputSchema`** (`object`, اختياري): كائن JSON Schema يصف المعلمات التي تقبلها دالتك. يستخدم وكلاء الذكاء الاصطناعي هذا المخطط لفهم المدخلات التي تتوقعها الأداة وللتحقق من صحة الاستدعاءات. إذا تم إغفاله، فالقيمة الافتراضية للمخطط هي `{ type: 'object', properties: {} }` (من دون معلمات).
|
||||
* الدوال التي لديها `isTool: false` (أو غير معيَّنة) **غير** معروضة كأدوات. لا يزال بالإمكان تنفيذها مباشرةً أو استدعاؤها بواسطة دوال أخرى، لكنها لن تظهر في اكتشاف الأدوات.
|
||||
* **تسمية الأداة**: عند كشفها كأداة، يتم تطبيع اسم الدالة تلقائيًا إلى `logic_function_<name>` (تحويله إلى أحرف صغيرة، واستبدال المحارف غير الأبجدية الرقمية بشرطات سفلية). على سبيل المثال، `enrich-company` تصبح `logic_function_enrich_company`.
|
||||
* يمكنك دمج `isTool` مع المشغِّلات — إذ يمكن للدالة أن تكون أداة (قابلة للاستدعاء من قِبل وكلاء الذكاء الاصطناعي) وأن تُشغَّل بواسطة أحداث (cron، وأحداث قاعدة البيانات، والمسارات) في الوقت نفسه.
|
||||
|
||||
<Note>
|
||||
**اكتب `description` جيدًا.** يعتمد وكلاء الذكاء الاصطناعي على حقل `description` الخاص بالدالة لتحديد وقت استخدام الأداة. كن محددًا بشأن ما تفعله الأداة ومتى ينبغي استدعاؤها.
|
||||
</Note>
|
||||
|
||||
### المكوّنات الأمامية
|
||||
|
||||
تتيح لك المكوّنات الأمامية إنشاء مكوّنات React مخصّصة تُعرَض داخل واجهة مستخدم Twenty. استخدم `defineFrontComponent()` لتعريف مكوّنات مع تحقّق مدمج:
|
||||
@@ -584,16 +707,16 @@ export default defineFrontComponent({
|
||||
* المكوّنات الأمامية هي مكوّنات React تُعرَض ضمن سياقات معزولة داخل Twenty.
|
||||
* استخدم لاحقة الملف `*.front-component.tsx` للاكتشاف التلقائي.
|
||||
* يشير الحقل `component` إلى مكوّن React الخاص بك.
|
||||
* يتم بناء المكوّنات ومزامنتها تلقائيًا أثناء `yarn app:dev`.
|
||||
* يتم بناء المكوّنات ومزامنتها تلقائيًا أثناء `yarn twenty app:dev`.
|
||||
|
||||
يمكنك إنشاء مكوّنات أمامية جديدة بطريقتين:
|
||||
|
||||
* **مُنشأ بالقالب**: شغّل `yarn entity:add` واختر خيار إضافة مكوّن أمامي جديد.
|
||||
* **مُنشأ بالقالب**: شغّل `yarn twenty entity:add` واختر خيار إضافة مكوّن أمامي جديد.
|
||||
* **يدوي**: أنشئ ملفًا جديدًا `*.front-component.tsx` واستخدم `defineFrontComponent()`.
|
||||
|
||||
### عميل مُولَّد مضبوط الأنواع
|
||||
|
||||
شغّل yarn app:generate لإنشاء عميل محلي مضبوط الأنواع في generated/ استنادًا إلى مخطط مساحة العمل لديك. استخدمه في وظائفك:
|
||||
يُولَّد العميل مضبوط الأنواع تلقائيًا بواسطة `yarn twenty app:dev` ويُخزَّن في `node_modules/twenty-sdk/generated` استنادًا إلى مخطط مساحة العمل لديك. استخدمه في وظائفك:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -602,7 +725,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
يُعاد توليد العميل بواسطة `yarn app:generate`. أعِد التشغيل بعد تغيير كائناتك أو عند الانضمام إلى مساحة عمل جديدة.
|
||||
يُعاد توليد العميل تلقائيًا بواسطة `yarn twenty app:dev` كلما تغيّرت كائناتك أو حقولك.
|
||||
|
||||
#### بيانات الاعتماد وقت التشغيل في الوظائف المنطقية
|
||||
|
||||
@@ -623,40 +746,29 @@ const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
|
||||
## إعداد يدوي (بدون المهيئ)
|
||||
|
||||
بينما نوصي باستخدام `create-twenty-app` للحصول على أفضل تجربة للبدء، يمكنك أيضًا إعداد مشروع يدويًا. لا تثبّت CLI عالميًا. بدل ذلك، أضف `twenty-sdk` كاعتماد محلي ووصل السكربتات في ملف package.json لديك:
|
||||
بينما نوصي باستخدام `create-twenty-app` للحصول على أفضل تجربة للبدء، يمكنك أيضًا إعداد مشروع يدويًا. لا تثبّت CLI عالميًا. بدل ذلك، أضف `twenty-sdk` كاعتماد محلي واربط سكربتًا واحدًا في ملف package.json لديك:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
```
|
||||
|
||||
ثم أضف نصوصًا مثل هذه:
|
||||
ثم أضف سكربتًا باسم `twenty`:
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
"auth:login": "twenty auth:login",
|
||||
"auth:logout": "twenty auth:logout",
|
||||
"auth:status": "twenty auth:status",
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
"function:execute": "twenty function:execute",
|
||||
"help": "twenty help"
|
||||
"twenty": "twenty"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
يمكنك الآن تشغيل الأوامر نفسها عبر Yarn، مثل `yarn app:dev` و`yarn app:generate`، إلخ.
|
||||
الآن يمكنك تشغيل جميع الأوامر عبر `yarn twenty <command>`، مثلًا: `yarn twenty app:dev`، `yarn twenty help`، إلخ.
|
||||
|
||||
## استكشاف الأخطاء وإصلاحها
|
||||
|
||||
* أخطاء المصادقة: شغّل `yarn auth:login` وتأكد من أن مفتاح واجهة برمجة التطبيقات لديك يمتلك الأذونات المطلوبة.
|
||||
* أخطاء المصادقة: شغّل `yarn twenty auth:login` وتأكد من أن مفتاح واجهة برمجة التطبيقات لديك يمتلك الأذونات المطلوبة.
|
||||
* يتعذّر الاتصال بالخادم: تحقق من عنوان URL لواجهة البرمجة وأن خادم Twenty قابل للوصول.
|
||||
* الأنواع أو العميل مفقود/قديم: شغّل `yarn app:generate`.
|
||||
* وضع التطوير لا يزامن: تأكد من أن `yarn app:dev` قيد التشغيل وأن التغييرات ليست متجاهلة من بيئتك.
|
||||
* الأنواع أو العميل مفقود/قديم: أعد تشغيل `yarn twenty app:dev` — فهو ينشئ العميل مضبوط الأنواع بشكل تلقائي.
|
||||
* وضع التطوير لا يزامن: تأكد من أن `yarn twenty app:dev` قيد التشغيل وأن التغييرات ليست متجاهلة من بيئتك.
|
||||
|
||||
قناة المساعدة على Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -36,32 +36,32 @@ corepack enable
|
||||
yarn install
|
||||
|
||||
# Přihlaste se pomocí svého API klíče (budete vyzváni)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Spusťte vývojový režim: automaticky synchronizuje místní změny s vaším pracovním prostorem
|
||||
yarn app:dev
|
||||
yarn twenty app:dev
|
||||
```
|
||||
|
||||
Odtud můžete:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Přidejte do vaší aplikace novou entitu (s průvodcem)
|
||||
yarn entity:add
|
||||
|
||||
# Vygenerujte typovaného klienta Twenty a typy entit pracovního prostoru
|
||||
yarn app:generate
|
||||
yarn twenty entity:add
|
||||
|
||||
# Sledujte logy funkcí vaší aplikace
|
||||
yarn function:logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Spusťte funkci podle názvu
|
||||
yarn function:execute -n my-function -p '{"name": "test"}'
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Spusťte postinstalační funkci
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Odinstalujte aplikaci z aktuálního pracovního prostoru
|
||||
yarn app:uninstall
|
||||
yarn twenty app:uninstall
|
||||
|
||||
# Zobrazte nápovědu k příkazům
|
||||
yarn help
|
||||
yarn twenty help
|
||||
```
|
||||
|
||||
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).
|
||||
@@ -73,7 +73,7 @@ Když spustíte `npx create-twenty-app@latest my-twenty-app`, scaffolder:
|
||||
* Zkopíruje minimální základní aplikaci do `my-twenty-app/`
|
||||
* Přidá lokální závislost `twenty-sdk` a konfiguraci pro Yarn 4
|
||||
* Vytvoří konfigurační soubory a skripty napojené na `twenty` CLI
|
||||
* Vygeneruje výchozí konfiguraci aplikace a výchozí roli funkcí
|
||||
* Vygeneruje výchozí konfiguraci aplikace, výchozí roli funkcí a postinstalační funkci.
|
||||
|
||||
Čerstvě vytvořená aplikace vypadá takto:
|
||||
|
||||
@@ -95,14 +95,15 @@ my-twenty-app/
|
||||
├── roles/
|
||||
│ └── default-role.ts # Výchozí role pro logické funkce
|
||||
├── logic-functions/
|
||||
│ └── hello-world.ts # Ukázková logická funkce
|
||||
│ ├── hello-world.ts # Ukázková logická funkce
|
||||
│ └── post-install.ts # Postinstalační logická funkce
|
||||
└── front-components/
|
||||
└── hello-world.tsx # Ukázková front-endová komponenta
|
||||
```
|
||||
|
||||
V kostce:
|
||||
|
||||
* **package.json**: Deklaruje název aplikace, verzi, engines (Node 24+, Yarn 4) a přidává `twenty-sdk` plus skripty jako `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` a autentizační příkazy, které delegují na lokální `twenty` CLI.
|
||||
* **package.json**: Deklaruje název aplikace, verzi, engines (Node 24+, Yarn 4) a přidává `twenty-sdk` plus skript `twenty`, který deleguje na lokální `twenty` CLI. Spusťte `yarn twenty help` pro výpis všech dostupných příkazů.
|
||||
* **.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.
|
||||
@@ -142,12 +143,12 @@ export default defineObject({
|
||||
|
||||
Pozdější příkazy přidají další soubory a složky:
|
||||
|
||||
* `yarn app:generate` vytvoří složku `generated/` (typovaný klient Twenty + typy pracovního prostoru).
|
||||
* `yarn entity:add` přidá soubory s definicemi entit do `src/` pro vaše vlastní objekty, funkce, frontové komponenty nebo role.
|
||||
* `yarn twenty app:dev` automaticky vygeneruje typovaného klienta API v `node_modules/twenty-sdk/generated` (typovaný klient Twenty + typy pracovního prostoru).
|
||||
* `yarn twenty entity:add` přidá soubory s definicemi entit do `src/` pro vaše vlastní objekty, funkce, frontové komponenty nebo role.
|
||||
|
||||
## Ověření
|
||||
|
||||
Při prvním spuštění `yarn auth:login` budete vyzváni k zadání:
|
||||
Při prvním spuštění `yarn twenty auth:login` budete vyzváni k zadání:
|
||||
|
||||
* URL API (výchozí je http://localhost:3000 nebo váš aktuální profil pracovního prostoru)
|
||||
* Klíč API
|
||||
@@ -158,25 +159,25 @@ Vaše přihlašovací údaje se ukládají pro jednotlivé uživatele do `~/.twe
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn auth:login --workspace my-custom-workspace
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
|
||||
# List all configured workspaces
|
||||
yarn auth:list
|
||||
yarn twenty auth:list
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn auth:switch
|
||||
yarn twenty auth:switch
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn auth:switch production
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn auth:status
|
||||
yarn twenty auth:status
|
||||
```
|
||||
|
||||
Jakmile přepnete pracovní prostor pomocí `auth:switch`, všechny následující příkazy budou tento pracovní prostor používat jako výchozí. Můžete jej stále dočasně přepsat pomocí `--workspace <name>`.
|
||||
Jakmile přepnete pracovní prostor pomocí `yarn twenty auth:switch`, všechny následující příkazy budou tento pracovní prostor používat jako výchozí. Můžete jej stále dočasně přepsat pomocí `--workspace <name>`.
|
||||
|
||||
## Používejte zdroje SDK (typy a konfiguraci)
|
||||
|
||||
@@ -276,10 +277,14 @@ Hlavní body:
|
||||
* 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 entity:add`, který vás provede pojmenováním, poli a vztahy.
|
||||
* Nové objekty můžete vygenerovat pomocí `yarn twenty entity:add`, který vás provede pojmenováním, poli a vztahy.
|
||||
|
||||
<Note>
|
||||
**Základní pole jsou vytvořena automaticky.** Když definujete vlastní objekt, Twenty automaticky přidá standardní pole jako `name`, `createdAt`, `updatedAt`, `createdBy`, `position` a `deletedAt`. Nemusíte je definovat v poli `fields` — přidejte pouze svá vlastní pole.
|
||||
**Základní pole jsou vytvořena automaticky.** Když definujete vlastní objekt, Twenty automaticky přidá standardní pole
|
||||
jako `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` a `deletedAt`.
|
||||
Nemusíte je definovat v poli `fields` — přidejte pouze svá vlastní pole.
|
||||
Výchozí pole můžete přepsat definováním pole se stejným názvem v poli `fields`,
|
||||
ale to se nedoporučuje.
|
||||
</Note>
|
||||
|
||||
### Konfigurace aplikace (application-config.ts)
|
||||
@@ -289,6 +294,7 @@ Každá aplikace má jeden soubor `application-config.ts`, který popisuje:
|
||||
* **Identitu aplikace**: identifikátory, zobrazovaný název a popis.
|
||||
* **Jak běží její funkce**: kterou roli používají pro oprávnění.
|
||||
* **(Volitelné) proměnné**: dvojice klíč–hodnota zpřístupněné vašim funkcím jako proměnné prostředí.
|
||||
* **(Volitelná) postinstalační funkce**: logická funkce, která se spouští po instalaci aplikace.
|
||||
|
||||
Use `defineApplication()` to define your application configuration:
|
||||
|
||||
@@ -296,6 +302,7 @@ Use `defineApplication()` to define your application configuration:
|
||||
// src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
@@ -311,6 +318,7 @@ export default defineApplication({
|
||||
},
|
||||
},
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -319,6 +327,7 @@ Poznámky:
|
||||
* Pole `universalIdentifier` jsou deterministická ID, která vlastníte; vygenerujte je jednou a udržujte je stabilní napříč synchronizacemi.
|
||||
* `applicationVariables` se stanou proměnnými prostředí pro vaše funkce (například `DEFAULT_RECIPIENT_NAME` je dostupné jako `process.env.DEFAULT_RECIPIENT_NAME`).
|
||||
* `defaultRoleUniversalIdentifier` se musí shodovat se souborem role (viz níže).
|
||||
* `postInstallLogicFunctionUniversalIdentifier` (volitelné) odkazuje na logickou funkci, která se automaticky spustí po instalaci aplikace. Viz [Postinstalační funkce](#post-install-functions).
|
||||
|
||||
#### Role a oprávnění
|
||||
|
||||
@@ -457,6 +466,55 @@ Poznámky:
|
||||
* Pole `triggers` je volitelné. Funkce bez spouštěčů lze použít jako pomocné funkce volané jinými funkcemi.
|
||||
* V jedné funkci můžete kombinovat více typů spouštěčů.
|
||||
|
||||
### Postinstalační funkce
|
||||
|
||||
Postinstalační funkce je logická funkce, která se automaticky spouští po instalaci vaší aplikace do pracovního prostoru. To je užitečné pro jednorázové úlohy nastavení, jako je naplnění výchozími daty, vytvoření počátečních záznamů nebo konfigurace nastavení pracovního prostoru.
|
||||
|
||||
When you scaffold a new app with `create-twenty-app`, a post-install function is generated for you at `src/logic-functions/post-install.ts`:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/post-install.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
|
||||
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
|
||||
|
||||
const handler = async (): Promise<void> => {
|
||||
console.log('Post install logic function executed successfully!');
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
name: 'post-install',
|
||||
description: 'Runs after installation to set up the application.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
The function is wired into your app by referencing its universal identifier in `application-config.ts`:
|
||||
|
||||
```typescript
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
// ...
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
You can also manually execute the post-install function at any time using the CLI:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty function:execute --postInstall
|
||||
```
|
||||
|
||||
Hlavní body:
|
||||
|
||||
* Post-install functions are standard logic functions — they use `defineLogicFunction()` like any other function.
|
||||
* The `postInstallLogicFunctionUniversalIdentifier` field in `defineApplication()` is optional. If omitted, no function runs after installation.
|
||||
* The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `function:execute --postInstall`.
|
||||
|
||||
### Payload spouštěče trasy
|
||||
|
||||
<Warning>
|
||||
@@ -551,9 +609,74 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Nové funkce můžete vytvářet dvěma způsoby:
|
||||
|
||||
* **Vygenerované**: Spusťte `yarn entity:add` a zvolte možnost přidat novou logickou funkci. Tím se vygeneruje startovací soubor s obslužnou funkcí a konfigurací.
|
||||
* **Vygenerované**: Spusťte `yarn twenty entity:add` a zvolte možnost přidat novou logickou funkci. Tím se vygeneruje startovací soubor s obslužnou funkcí a konfigurací.
|
||||
* **Ruční**: Vytvořte nový soubor `*.logic-function.ts` a použijte `defineLogicFunction()` podle stejného vzoru.
|
||||
|
||||
### Označení logické funkce jako nástroje
|
||||
|
||||
Logické funkce lze zpřístupnit jako **nástroje** pro agenty AI a pracovní postupy. Když je funkce označena jako nástroj, stane se dohledatelnou funkcemi AI produktu Twenty a lze ji vybrat jako krok v automatizacích pracovních postupů.
|
||||
|
||||
Chcete-li označit logickou funkci jako nástroj, nastavte `isTool: true` a poskytněte `toolInputSchema` popisující očekávané vstupní parametry pomocí [JSON Schema](https://json-schema.org/):
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/enrich-company.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import Twenty from '~/generated';
|
||||
|
||||
const handler = async (params: { companyName: string; domain?: string }) => {
|
||||
const client = new Twenty();
|
||||
|
||||
const result = await client.mutation({
|
||||
createTask: {
|
||||
__args: {
|
||||
data: {
|
||||
title: `Enrich data for ${params.companyName}`,
|
||||
body: `Domain: ${params.domain ?? 'unknown'}`,
|
||||
},
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
return { taskId: result.createTask.id };
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
|
||||
name: 'enrich-company',
|
||||
description: 'Enrich a company record with external data',
|
||||
timeoutSeconds: 10,
|
||||
handler,
|
||||
isTool: true,
|
||||
toolInputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
companyName: {
|
||||
type: 'string',
|
||||
description: 'The name of the company to enrich',
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
description: 'The company website domain (optional)',
|
||||
},
|
||||
},
|
||||
required: ['companyName'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Hlavní body:
|
||||
|
||||
* **`isTool`** (`boolean`, výchozí: `false`): Když je nastaveno na `true`, funkce je zaregistrována jako nástroj a zpřístupní se agentům AI a automatizacím pracovních postupů.
|
||||
* **`toolInputSchema`** (`object`, volitelné): Objekt JSON Schema, který popisuje parametry, jež vaše funkce přijímá. Agenti AI používají toto schéma k pochopení toho, jaké vstupy nástroj očekává, a k ověřování volání. Pokud je vynecháno, schéma má výchozí podobu `{ type: 'object', properties: {} }` (žádné parametry).
|
||||
* Funkce s `isTool: false` (nebo není nastaveno) **nejsou** zpřístupněny jako nástroje. Stále je lze spouštět přímo nebo volat z jiných funkcí, ale neobjeví se ve vyhledávání nástrojů.
|
||||
* **Pojmenování nástrojů**: Když je funkce zpřístupněna jako nástroj, její název se automaticky normalizuje na `logic_function_<name>` (převedeno na malá písmena, nealfanumerické znaky jsou nahrazeny podtržítky). Například `enrich-company` se změní na `logic_function_enrich_company`.
|
||||
* Můžete kombinovat `isTool` se spouštěči — funkce může být zároveň nástrojem (volatelným agenty AI) i spouštěna událostmi (cron, databázové události, routes).
|
||||
|
||||
<Note>
|
||||
**Napište kvalitní `description`.** Agenti AI se spoléhají na pole funkce `description` při rozhodování, kdy nástroj použít. Buďte konkrétní ohledně toho, co nástroj dělá a kdy se má volat.
|
||||
</Note>
|
||||
|
||||
### Frontendové komponenty
|
||||
|
||||
Frontendové komponenty vám umožňují vytvářet vlastní React komponenty, které se vykreslují v rozhraní Twenty. K definování komponent s vestavěnou validací použijte `defineFrontComponent()`:
|
||||
@@ -584,16 +707,16 @@ Hlavní body:
|
||||
* Frontendové komponenty jsou React komponenty, které se vykreslují v izolovaných kontextech v rámci Twenty.
|
||||
* Pro automatickou detekci použijte příponu souboru `*.front-component.tsx`.
|
||||
* Pole `component` odkazuje na vaši React komponentu.
|
||||
* Komponenty se během `yarn app:dev` automaticky sestaví a synchronizují.
|
||||
* Komponenty se během `yarn twenty app:dev` automaticky sestaví a synchronizují.
|
||||
|
||||
Nové frontendové komponenty můžete vytvořit dvěma způsoby:
|
||||
|
||||
* **Vygenerované**: Spusťte `yarn entity:add` a zvolte možnost přidat novou frontendovou komponentu.
|
||||
* **Vygenerované**: Spusťte `yarn twenty entity:add` a zvolte možnost přidat novou frontendovou komponentu.
|
||||
* **Ruční**: Vytvořte nový soubor `*.front-component.tsx` a použijte `defineFrontComponent()`.
|
||||
|
||||
### Generovaný typovaný klient
|
||||
|
||||
Spusťte yarn app:generate a vytvořte lokálního typovaného klienta v generated/ na základě schématu vašeho pracovního prostoru. Použijte jej ve svých funkcích:
|
||||
Typovaný klient je automaticky generován pomocí `yarn twenty app:dev` a ukládá se do `node_modules/twenty-sdk/generated` podle schématu vašeho pracovního prostoru. Použijte jej ve svých funkcích:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -602,7 +725,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
Klient je znovu generován příkazem `yarn app:generate`. Spusťte znovu po změně vašich objektů nebo při připojování k novému pracovnímu prostoru.
|
||||
Klient se automaticky znovu generuje pomocí `yarn twenty app:dev` kdykoli se změní vaše objekty nebo pole.
|
||||
|
||||
#### Běhové přihlašovací údaje v logických funkcích
|
||||
|
||||
@@ -623,40 +746,29 @@ Prozkoumejte minimalistický end-to-end příklad, který demonstruje objekty, l
|
||||
|
||||
## Ruční nastavení (bez scaffolderu)
|
||||
|
||||
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:
|
||||
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 přidejte jeden skript do souboru package.json:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
```
|
||||
|
||||
Poté přidejte skripty jako tyto:
|
||||
Poté přidejte skript `twenty`:
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
"auth:login": "twenty auth:login",
|
||||
"auth:logout": "twenty auth:logout",
|
||||
"auth:status": "twenty auth:status",
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
"function:execute": "twenty function:execute",
|
||||
"help": "twenty help"
|
||||
"twenty": "twenty"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Nyní můžete spouštět stejné příkazy přes Yarn, např. `yarn app:dev`, `yarn app:generate` atd.
|
||||
Nyní můžete spouštět všechny příkazy přes `yarn twenty <command>`, např. `yarn twenty app:dev`, `yarn twenty help` atd.
|
||||
|
||||
## Řešení potíží
|
||||
|
||||
* Chyby ověření: spusťte `yarn auth:login` a ujistěte se, že váš klíč API má požadovaná oprávnění.
|
||||
* Chyby ověření: spusťte `yarn twenty auth:login` a ujistěte se, že váš klíč API má požadovaná oprávnění.
|
||||
* Nelze se připojit k serveru: ověřte URL API a že je server Twenty dosažitelný.
|
||||
* Typy nebo klient chybí nebo jsou zastaralé: spusťte `yarn app:generate`.
|
||||
* Režim vývoje nesynchronizuje: ujistěte se, že běží `yarn app:dev` a že vaše prostředí změny neignoruje.
|
||||
* Types or client missing/outdated: restart `yarn twenty app:dev` — it auto-generates the typed client.
|
||||
* Režim vývoje se nesynchronizuje: ujistěte se, že běží `yarn twenty app:dev` a že vaše prostředí změny neignoruje.
|
||||
|
||||
Kanál podpory na Discordu: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -27,41 +27,41 @@ Mit Apps können Sie Twenty-Anpassungen **als Code** erstellen und verwalten. An
|
||||
Erstellen Sie mit dem offiziellen Scaffolder eine neue App, authentifizieren Sie sich und beginnen Sie mit der Entwicklung:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Scaffold a new app
|
||||
# Eine neue App erstellen
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
cd my-twenty-app
|
||||
|
||||
# If you don't use yarn@4
|
||||
# Falls du yarn@4 nicht verwendest
|
||||
corepack enable
|
||||
yarn install
|
||||
|
||||
# Authenticate using your API key (you'll be prompted)
|
||||
yarn auth:login
|
||||
# Mit deinem API-Schlüssel authentifizieren (du wirst dazu aufgefordert)
|
||||
yarn twenty auth:login
|
||||
|
||||
# Start dev mode: automatically syncs local changes to your workspace
|
||||
yarn app:dev
|
||||
# Dev-Modus starten: synchronisiert lokale Änderungen automatisch mit deinem Arbeitsbereich
|
||||
yarn twenty app:dev
|
||||
```
|
||||
|
||||
Von hier aus können Sie:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Eine neue Entität zu deiner Anwendung hinzufügen (geführt)
|
||||
yarn entity:add
|
||||
# Eine neue Entität zu Ihrer Anwendung hinzufügen (geführt)
|
||||
yarn twenty entity:add
|
||||
|
||||
# Einen typisierten Twenty-Client und Entitätstypen für den Arbeitsbereich generieren
|
||||
yarn app:generate
|
||||
|
||||
# Die Funktionsprotokolle deiner Anwendung überwachen
|
||||
yarn function:logs
|
||||
# Die Funktionsprotokolle Ihrer Anwendung überwachen
|
||||
yarn twenty function:logs
|
||||
|
||||
# Eine Funktion anhand ihres Namens ausführen
|
||||
yarn function:execute -n my-function -p '{"name": "test"}'
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Die Post-Installationsfunktion ausführen
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Die Anwendung aus dem aktuellen Arbeitsbereich deinstallieren
|
||||
yarn app:uninstall
|
||||
yarn twenty app:uninstall
|
||||
|
||||
# Hilfe zu Befehlen anzeigen
|
||||
yarn help
|
||||
yarn twenty help
|
||||
```
|
||||
|
||||
Siehe auch: die CLI-Referenzseiten für [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) und [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
@@ -73,7 +73,7 @@ Wenn Sie `npx create-twenty-app@latest my-twenty-app` ausführen, erledigt der S
|
||||
* Kopiert eine minimale Basisanwendung nach `my-twenty-app/`
|
||||
* Fügt eine lokale `twenty-sdk`-Abhängigkeit und die Yarn-4-Konfiguration hinzu
|
||||
* Erstellt Konfigurationsdateien und Skripte, die an die `twenty`-CLI angebunden sind
|
||||
* Generiert eine Standard-Anwendungskonfiguration und eine Standard-Funktionsrolle
|
||||
* Generiert eine Standard-Anwendungskonfiguration, eine Standard-Funktionsrolle und eine Post-Installationsfunktion
|
||||
|
||||
Eine frisch erzeugte App sieht so aus:
|
||||
|
||||
@@ -89,20 +89,21 @@ my-twenty-app/
|
||||
eslint.config.mjs
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
public/ # Ordner für öffentliche Assets (Bilder, Schriftarten usw.)
|
||||
src/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── application-config.ts # Erforderlich – Hauptkonfiguration der Anwendung
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
│ └── default-role.ts # Standardrolle für Logikfunktionen
|
||||
├── logic-functions/
|
||||
│ └── hello-world.ts # Example logic function
|
||||
│ ├── hello-world.ts # Beispiel für eine Logikfunktion
|
||||
│ └── post-install.ts # Post-Installations-Logikfunktion
|
||||
└── front-components/
|
||||
└── hello-world.tsx # Example front component
|
||||
└── hello-world.tsx # Beispiel für eine Frontend-Komponente
|
||||
```
|
||||
|
||||
Auf hoher Ebene:
|
||||
|
||||
* **package.json**: Deklariert den App-Namen, die Version, Engines (Node 24+, Yarn 4) und fügt `twenty-sdk` sowie Skripte wie `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` sowie Authentifizierungsbefehle hinzu, die an die lokale `twenty`-CLI delegieren.
|
||||
* **package.json**: Deklariert den App-Namen, die Version und die Engines (Node 24+, Yarn 4) und fügt `twenty-sdk` sowie ein `twenty`-Skript hinzu, das an die lokale `twenty`-CLI delegiert. Führe `yarn twenty help` aus, um alle verfügbaren Befehle aufzulisten.
|
||||
* **.gitignore**: Ignoriert übliche Artefakte wie `node_modules`, `.yarn`, `generated/` (typisierter Client), `dist/`, `build/`, Coverage-Ordner, Logdateien und `.env*`-Dateien.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Fixieren und konfigurieren die vom Projekt verwendete Yarn-4-Toolchain.
|
||||
* **.nvmrc**: Legt die vom Projekt erwartete Node.js-Version fest.
|
||||
@@ -142,12 +143,12 @@ export default defineObject({
|
||||
|
||||
Spätere Befehle fügen weitere Dateien und Ordner hinzu:
|
||||
|
||||
* `yarn app:generate` erstellt einen `generated/`-Ordner (typisierter Twenty-Client + Workspace-Typen).
|
||||
* `yarn entity:add` fügt unter `src/` Entitätsdefinitionsdateien für Ihre benutzerdefinierten Objekte, Funktionen, Front-Komponenten oder Rollen hinzu.
|
||||
* `yarn twenty app:dev` generiert automatisch einen typisierten API-Client in `node_modules/twenty-sdk/generated` (typisierter Twenty-Client + Arbeitsbereichs-Typen).
|
||||
* `yarn twenty entity:add` fügt unter `src/` Entitätsdefinitionsdateien für benutzerdefinierte Objekte, Funktionen, Frontend-Komponenten oder Rollen hinzu.
|
||||
|
||||
## Authentifizierung
|
||||
|
||||
Wenn Sie `yarn auth:login` zum ersten Mal ausführen, werden Sie nach Folgendem gefragt:
|
||||
Wenn Sie `yarn twenty auth:login` zum ersten Mal ausführen, werden Sie nach Folgendem gefragt:
|
||||
|
||||
* API-URL (standardmäßig http://localhost:3000 oder Ihr aktuelles Workspace-Profil)
|
||||
* API-Schlüssel
|
||||
@@ -158,25 +159,25 @@ Ihre Anmeldedaten werden pro Benutzer in `~/.twenty/config.json` gespeichert. Si
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn auth:login --workspace my-custom-workspace
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
|
||||
# List all configured workspaces
|
||||
yarn auth:list
|
||||
yarn twenty auth:list
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn auth:switch
|
||||
yarn twenty auth:switch
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn auth:switch production
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn auth:status
|
||||
yarn twenty auth:status
|
||||
```
|
||||
|
||||
Sobald Sie mit `auth:switch` den Arbeitsbereich gewechselt haben, verwenden alle nachfolgenden Befehle standardmäßig diesen Arbeitsbereich. Sie können es weiterhin vorübergehend mit `--workspace <name>` überschreiben.
|
||||
Sobald Sie mit `yarn twenty auth:switch` den Arbeitsbereich gewechselt haben, verwenden alle nachfolgenden Befehle standardmäßig diesen Arbeitsbereich. Sie können es weiterhin vorübergehend mit `--workspace <name>` überschreiben.
|
||||
|
||||
## SDK-Ressourcen verwenden (Typen & Konfiguration)
|
||||
|
||||
@@ -276,10 +277,14 @@ Hauptpunkte:
|
||||
* Der `universalIdentifier` muss eindeutig und über Deployments hinweg stabil sein.
|
||||
* Jedes Feld benötigt `name`, `type`, `label` und einen eigenen stabilen `universalIdentifier`.
|
||||
* Das Array `fields` ist optional — Sie können Objekte ohne benutzerdefinierte Felder definieren.
|
||||
* Sie können mit `yarn entity:add` neue Objekte erzeugen; der Assistent führt Sie durch Benennung, Felder und Beziehungen.
|
||||
* Sie können mit `yarn twenty entity:add` neue Objekte erzeugen; der Assistent führt Sie durch Benennung, Felder und Beziehungen.
|
||||
|
||||
<Note>
|
||||
**Basisfelder werden automatisch erstellt.** Wenn Sie ein benutzerdefiniertes Objekt definieren, fügt Twenty automatisch Standardfelder wie `name`, `createdAt`, `updatedAt`, `createdBy`, `position` und `deletedAt` hinzu. Sie müssen diese nicht in Ihrem `fields`-Array definieren — fügen Sie nur Ihre benutzerdefinierten Felder hinzu.
|
||||
**Basisfelder werden automatisch erstellt.** Wenn Sie ein benutzerdefiniertes Objekt definieren, fügt Twenty automatisch Standardfelder hinzu
|
||||
wie `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` und `deletedAt`.
|
||||
Sie müssen diese nicht in Ihrem `fields`-Array definieren — fügen Sie nur Ihre benutzerdefinierten Felder hinzu.
|
||||
Sie können Standardfelder überschreiben, indem Sie in Ihrem `fields`-Array ein Feld mit demselben Namen definieren,
|
||||
dies wird jedoch nicht empfohlen.
|
||||
</Note>
|
||||
|
||||
### Anwendungskonfiguration (application-config.ts)
|
||||
@@ -289,6 +294,7 @@ Jede App hat eine einzelne Datei `application-config.ts`, die Folgendes beschrei
|
||||
* **Was die App ist**: Bezeichner, Anzeigename und Beschreibung.
|
||||
* **Wie ihre Funktionen ausgeführt werden**: welche Rolle sie für Berechtigungen verwenden.
|
||||
* **(Optional) Variablen**: Schlüssel–Wert-Paare, die Ihren Funktionen als Umgebungsvariablen zur Verfügung gestellt werden.
|
||||
* **(Optional) Post-Installationsfunktion**: eine Logikfunktion, die nach der Installation der App ausgeführt wird.
|
||||
|
||||
Verwenden Sie `defineApplication()`, um Ihre Anwendungskonfiguration zu definieren:
|
||||
|
||||
@@ -296,6 +302,7 @@ Verwenden Sie `defineApplication()`, um Ihre Anwendungskonfiguration zu definier
|
||||
// src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
@@ -311,6 +318,7 @@ export default defineApplication({
|
||||
},
|
||||
},
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -319,6 +327,7 @@ Notizen:
|
||||
* `universalIdentifier`-Felder sind deterministische IDs, die Sie besitzen; generieren Sie sie einmal und halten Sie sie über Synchronisierungen hinweg stabil.
|
||||
* `applicationVariables` werden zu Umgebungsvariablen für Ihre Funktionen (zum Beispiel ist `DEFAULT_RECIPIENT_NAME` als `process.env.DEFAULT_RECIPIENT_NAME` verfügbar).
|
||||
* `defaultRoleUniversalIdentifier` muss mit der Rollendatei übereinstimmen (siehe unten).
|
||||
* `postInstallLogicFunctionUniversalIdentifier` (optional) verweist auf eine Logikfunktion, die nach der Installation der App automatisch ausgeführt wird. Siehe [Post-Installationsfunktionen](#post-install-functions).
|
||||
|
||||
#### Rollen und Berechtigungen
|
||||
|
||||
@@ -457,6 +466,55 @@ Notizen:
|
||||
* Das Array `triggers` ist optional. Funktionen ohne Trigger können als von anderen Funktionen aufgerufene Utility-Funktionen verwendet werden.
|
||||
* Sie können mehrere Trigger-Typen in einer Funktion kombinieren.
|
||||
|
||||
### Post-Installationsfunktionen
|
||||
|
||||
Eine Post-Installationsfunktion ist eine Logikfunktion, die automatisch ausgeführt wird, nachdem Ihre App in einem Arbeitsbereich installiert wurde. Dies ist nützlich für einmalige Einrichtungsvorgänge wie das Befüllen mit Standarddaten, das Erstellen erster Datensätze oder das Konfigurieren von Arbeitsbereichseinstellungen.
|
||||
|
||||
When you scaffold a new app with `create-twenty-app`, a post-install function is generated for you at `src/logic-functions/post-install.ts`:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/post-install.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
|
||||
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
|
||||
|
||||
const handler = async (): Promise<void> => {
|
||||
console.log('Post install logic function executed successfully!');
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
name: 'post-install',
|
||||
description: 'Runs after installation to set up the application.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
The function is wired into your app by referencing its universal identifier in `application-config.ts`:
|
||||
|
||||
```typescript
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
// ...
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
You can also manually execute the post-install function at any time using the CLI:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty function:execute --postInstall
|
||||
```
|
||||
|
||||
Hauptpunkte:
|
||||
|
||||
* Post-install functions are standard logic functions — they use `defineLogicFunction()` like any other function.
|
||||
* The `postInstallLogicFunctionUniversalIdentifier` field in `defineApplication()` is optional. If omitted, no function runs after installation.
|
||||
* The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `function:execute --postInstall`.
|
||||
|
||||
### Routen-Trigger-Payload
|
||||
|
||||
<Warning>
|
||||
@@ -551,9 +609,74 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Sie können neue Funktionen auf zwei Arten erstellen:
|
||||
|
||||
* **Generiert**: Führen Sie `yarn entity:add` aus und wählen Sie die Option zum Hinzufügen einer neuen Logikfunktion. Dadurch wird eine Starterdatei mit Handler und Konfiguration erzeugt.
|
||||
* **Generiert**: Führen Sie `yarn twenty entity:add` aus und wählen Sie die Option zum Hinzufügen einer neuen Logikfunktion. Dadurch wird eine Starterdatei mit Handler und Konfiguration erzeugt.
|
||||
* **Manuell**: Erstellen Sie eine neue `*.logic-function.ts`-Datei und verwenden Sie `defineLogicFunction()` nach demselben Muster.
|
||||
|
||||
### Eine Logikfunktion als Tool markieren
|
||||
|
||||
Logikfunktionen können als **Tools** für KI-Agenten und Workflows verfügbar gemacht werden. Wenn eine Funktion als Tool markiert ist, wird sie von den KI-Funktionen von Twenty auffindbar und kann als Schritt in Workflow-Automatisierungen ausgewählt werden.
|
||||
|
||||
Um eine Logikfunktion als Tool zu markieren, setzen Sie `isTool: true` und geben Sie ein `toolInputSchema` an, das die erwarteten Eingabeparameter mithilfe von [JSON Schema](https://json-schema.org/) beschreibt:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/enrich-company.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import Twenty from '~/generated';
|
||||
|
||||
const handler = async (params: { companyName: string; domain?: string }) => {
|
||||
const client = new Twenty();
|
||||
|
||||
const result = await client.mutation({
|
||||
createTask: {
|
||||
__args: {
|
||||
data: {
|
||||
title: `Enrich data for ${params.companyName}`,
|
||||
body: `Domain: ${params.domain ?? 'unknown'}`,
|
||||
},
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
return { taskId: result.createTask.id };
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
|
||||
name: 'enrich-company',
|
||||
description: 'Enrich a company record with external data',
|
||||
timeoutSeconds: 10,
|
||||
handler,
|
||||
isTool: true,
|
||||
toolInputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
companyName: {
|
||||
type: 'string',
|
||||
description: 'The name of the company to enrich',
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
description: 'The company website domain (optional)',
|
||||
},
|
||||
},
|
||||
required: ['companyName'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Hauptpunkte:
|
||||
|
||||
* **`isTool`** (`boolean`, Standard: `false`): Wenn auf `true` gesetzt, wird die Funktion als Tool registriert und steht KI-Agenten und Workflow-Automatisierungen zur Verfügung.
|
||||
* **`toolInputSchema`** (`object`, optional): Ein JSON-Schema-Objekt, das die Parameter beschreibt, die Ihre Funktion akzeptiert. KI-Agenten verwenden dieses Schema, um zu verstehen, welche Eingaben das Tool erwartet, und um Aufrufe zu validieren. Falls weggelassen, lautet der Standardwert für das Schema `{ type: 'object', properties: {} }` (keine Parameter).
|
||||
* Funktionen mit `isTool: false` (oder nicht gesetzt) werden **nicht** als Tools bereitgestellt. Sie können weiterhin direkt ausgeführt oder von anderen Funktionen aufgerufen werden, erscheinen jedoch nicht in der Tool-Erkennung.
|
||||
* **Tool-Benennung**: Wenn als Tool bereitgestellt, wird der Funktionsname automatisch zu `logic_function_<name>` normalisiert (in Kleinbuchstaben umgewandelt, nicht alphanumerische Zeichen durch Unterstriche ersetzt). Beispielsweise wird `enrich-company` zu `logic_function_enrich_company`.
|
||||
* Sie können `isTool` mit Triggern kombinieren — eine Funktion kann gleichzeitig sowohl ein Tool (von KI-Agenten aufrufbar) als auch durch Ereignisse (Cron, Datenbankereignisse, Routen) ausgelöst werden.
|
||||
|
||||
<Note>
|
||||
**Schreiben Sie eine gute `description`.** KI-Agenten verlassen sich auf das `description`-Feld der Funktion, um zu entscheiden, wann das Tool verwendet werden soll. Seien Sie konkret darin, was das Tool tut und wann es aufgerufen werden soll.
|
||||
</Note>
|
||||
|
||||
### Frontend-Komponenten
|
||||
|
||||
Frontend-Komponenten ermöglichen es Ihnen, benutzerdefinierte React-Komponenten zu erstellen, die innerhalb der Twenty-UI gerendert werden. Verwenden Sie `defineFrontComponent()`, um Komponenten mit eingebauter Validierung zu definieren:
|
||||
@@ -584,16 +707,16 @@ Hauptpunkte:
|
||||
* Frontend-Komponenten sind React-Komponenten, die in isolierten Kontexten innerhalb von Twenty gerendert werden.
|
||||
* Verwenden Sie die Dateiendung `*.front-component.tsx` für die automatische Erkennung.
|
||||
* Das Feld `component` verweist auf Ihre React-Komponente.
|
||||
* Komponenten werden während `yarn app:dev` automatisch gebaut und synchronisiert.
|
||||
* Komponenten werden während `yarn twenty app:dev` automatisch gebaut und synchronisiert.
|
||||
|
||||
Sie können neue Frontend-Komponenten auf zwei Arten erstellen:
|
||||
|
||||
* **Generiert**: Führen Sie `yarn entity:add` aus und wählen Sie die Option zum Hinzufügen einer neuen Frontend-Komponente.
|
||||
* **Generiert**: Führen Sie `yarn twenty entity:add` aus und wählen Sie die Option zum Hinzufügen einer neuen Frontend-Komponente.
|
||||
* **Manuell**: Erstellen Sie eine neue `*.front-component.tsx`-Datei und verwenden Sie `defineFrontComponent()`.
|
||||
|
||||
### Generierter typisierter Client
|
||||
|
||||
Führen Sie yarn app:generate aus, um einen lokalen typisierten Client in generated/ basierend auf Ihrem Workspace-Schema zu erstellen. Verwenden Sie ihn in Ihren Funktionen:
|
||||
Der typisierte Client wird von `yarn twenty app:dev` automatisch generiert und basierend auf Ihrem Arbeitsbereichs-Schema in `node_modules/twenty-sdk/generated` gespeichert. Verwenden Sie ihn in Ihren Funktionen:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -602,7 +725,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
Der Client wird durch `yarn app:generate` erneut generiert. Führen Sie ihn nach Änderungen an Ihren Objekten oder beim Onboarding in einen neuen Workspace erneut aus.
|
||||
Der Client wird von `yarn twenty app:dev` automatisch neu generiert, sobald sich Ihre Objekte oder Felder ändern.
|
||||
|
||||
#### Laufzeit-Anmeldedaten in Logikfunktionen
|
||||
|
||||
@@ -623,40 +746,29 @@ Ein minimales End-to-End-Beispiel, das Objekte, Logikfunktionen, Frontend-Kompon
|
||||
|
||||
## Manuelle Einrichtung (ohne Scaffolder)
|
||||
|
||||
Wir empfehlen zwar `create-twenty-app` für das beste Einstiegserlebnis, Sie können ein Projekt aber auch manuell einrichten. Installieren Sie die CLI nicht global. Fügen Sie stattdessen `twenty-sdk` als lokale Abhängigkeit hinzu und binden Sie Skripte in Ihrer package.json ein:
|
||||
Wir empfehlen zwar `create-twenty-app` für das beste Einstiegserlebnis, Sie können ein Projekt aber auch manuell einrichten. Installieren Sie die CLI nicht global. Fügen Sie stattdessen `twenty-sdk` als lokale Abhängigkeit hinzu und binden Sie ein einzelnes Skript in Ihrer package.json ein:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
```
|
||||
|
||||
Fügen Sie dann Skripte wie diese hinzu:
|
||||
Fügen Sie dann ein `twenty`-Skript hinzu:
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
"auth:login": "twenty auth:login",
|
||||
"auth:logout": "twenty auth:logout",
|
||||
"auth:status": "twenty auth:status",
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
"function:execute": "twenty function:execute",
|
||||
"help": "twenty help"
|
||||
"twenty": "twenty"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Jetzt können Sie dieselben Befehle über Yarn ausführen, z. B. `yarn app:dev`, `yarn app:generate` usw.
|
||||
Jetzt können Sie alle Befehle über `yarn twenty <command>` ausführen, z. B. `yarn twenty app:dev`, `yarn twenty help` usw.
|
||||
|
||||
## Fehlerbehebung
|
||||
|
||||
* Authentifizierungsfehler: Führen Sie `yarn auth:login` aus und stellen Sie sicher, dass Ihr API-Schlüssel die erforderlichen Berechtigungen hat.
|
||||
* Authentifizierungsfehler: Führen Sie `yarn twenty auth:login` aus und stellen Sie sicher, dass Ihr API-Schlüssel die erforderlichen Berechtigungen hat.
|
||||
* Verbindung zum Server nicht möglich: Überprüfen Sie die API-URL und dass der Twenty-Server erreichbar ist.
|
||||
* Typen oder Client fehlen/veraltet: Führen Sie `yarn app:generate` aus.
|
||||
* Dev-Modus synchronisiert nicht: Stellen Sie sicher, dass `yarn app:dev` läuft und dass Änderungen von Ihrer Umgebung nicht ignoriert werden.
|
||||
* Typen oder Client fehlen/veraltet: Starten Sie `yarn twenty app:dev` neu — der typisierte Client wird automatisch generiert.
|
||||
* Dev-Modus synchronisiert nicht: Stellen Sie sicher, dass `yarn twenty app:dev` läuft und dass Änderungen von Ihrer Umgebung nicht ignoriert werden.
|
||||
|
||||
Discord-Hilfekanal: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -52,9 +52,6 @@ Desde aquí usted puede:
|
||||
# Añade una nueva entidad a tu aplicación (guiado)
|
||||
yarn entity:add
|
||||
|
||||
# Genera un cliente tipado de Twenty y tipos de entidad del espacio de trabajo
|
||||
yarn app:generate
|
||||
|
||||
# Supervisa los registros de funciones de tu aplicación
|
||||
yarn function:logs
|
||||
|
||||
@@ -157,7 +154,7 @@ src/
|
||||
|
||||
A grandes rasgos:
|
||||
|
||||
* **package.json**: Declara el nombre de la aplicación, la versión, los entornos (Node 24+, Yarn 4) y agrega `twenty-sdk` además de scripts como `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` y `auth:login` que delegan en la CLI local `twenty`.
|
||||
* **package.json**: Declara el nombre de la aplicación, la versión, los entornos (Node 24+, Yarn 4) y agrega `twenty-sdk` además de scripts como `app:dev`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` y `auth:login` que delegan en la CLI local `twenty`.
|
||||
* **.gitignore**: Ignora artefactos comunes como `node_modules`, `.yarn`, `generated/` (cliente tipado), `dist/`, `build/`, carpetas de cobertura, archivos de registro y archivos `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Bloquean y configuran la cadena de herramientas Yarn 4 utilizada por el proyecto.
|
||||
* **.nvmrc**: Fija la versión de Node.js esperada por el proyecto.
|
||||
@@ -173,7 +170,7 @@ A grandes rasgos:
|
||||
|
||||
Comandos posteriores añadirán más archivos y carpetas:
|
||||
|
||||
* `yarn app:generate` creará una carpeta `generated/` (cliente tipado de Twenty + tipos del espacio de trabajo).
|
||||
* `yarn app:dev` genera automáticamente el cliente Twenty tipado en `node_modules/twenty-sdk/generated`.
|
||||
* `yarn entity:add` añadirá archivos de definición de entidades en `src/` para tus objetos, funciones, componentes de interfaz o roles personalizados.
|
||||
|
||||
## Autenticación
|
||||
@@ -585,7 +582,7 @@ Puedes crear funciones nuevas de dos maneras:
|
||||
|
||||
### Cliente tipado generado
|
||||
|
||||
Ejecuta yarn app:generate para crear un cliente tipado local en generated/ basado en el esquema de tu espacio de trabajo. Úsalo en tus funciones:
|
||||
`yarn app:dev` genera automáticamente el cliente Twenty tipado en `node_modules/twenty-sdk/generated`. Úsalo en tus funciones:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -594,7 +591,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
El cliente se vuelve a generar con `yarn app:generate`. Vuelve a ejecutarlo después de cambiar tus objetos o al incorporarte a un nuevo espacio de trabajo.
|
||||
El cliente se regenera automáticamente durante la ejecución de `app:dev`. Reinicia `app:dev` después de cambiar tus objetos o al incorporarte a un nuevo espacio de trabajo.
|
||||
|
||||
#### Credenciales en tiempo de ejecución en funciones de lógica
|
||||
|
||||
@@ -632,7 +629,6 @@ Luego agrega scripts como estos:
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
@@ -642,13 +638,13 @@ Luego agrega scripts como estos:
|
||||
}
|
||||
```
|
||||
|
||||
Ahora puedes ejecutar los mismos comandos mediante Yarn, p. ej., `yarn app:dev`, `yarn app:generate`, etc.
|
||||
Ahora puedes ejecutar los mismos comandos mediante Yarn, p. ej., `yarn app:dev`, etc.
|
||||
|
||||
## Solución de problemas
|
||||
|
||||
* Errores de autenticación: ejecuta `yarn auth:login` y asegúrate de que tu clave de API tenga los permisos necesarios.
|
||||
* No se puede conectar al servidor: verifica la URL de la API y que el servidor de Twenty sea accesible.
|
||||
* Tipos o cliente faltantes/obsoletos: ejecuta `yarn app:generate`.
|
||||
* Tipos o cliente faltantes/obsoletos: reinicia `yarn app:dev`.
|
||||
* El modo de desarrollo no sincroniza: asegúrate de que `yarn app:dev` esté ejecutándose y de que los cambios no sean ignorados por tu entorno.
|
||||
|
||||
Canal de ayuda en Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -52,9 +52,6 @@ yarn app:dev
|
||||
# Ajouter une nouvelle entité à votre application (assisté)
|
||||
yarn entity:add
|
||||
|
||||
# Générer un client Twenty typé et les types d'entité de l'espace de travail
|
||||
yarn app:generate
|
||||
|
||||
# Surveiller les journaux des fonctions de votre application
|
||||
yarn function:logs
|
||||
|
||||
@@ -157,7 +154,7 @@ src/
|
||||
|
||||
Dans les grandes lignes :
|
||||
|
||||
* **package.json** : Déclare le nom de l’application, la version, les moteurs (Node 24+, Yarn 4), et ajoute `twenty-sdk` ainsi que des scripts comme `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` et `auth:login` qui délèguent à la CLI locale `twenty`.
|
||||
* **package.json** : Déclare le nom de l’application, la version, les moteurs (Node 24+, Yarn 4), et ajoute `twenty-sdk` ainsi que des scripts comme `app:dev`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` et `auth:login` qui délèguent à la CLI locale `twenty`.
|
||||
* **.gitignore** : Ignore les artefacts courants tels que `node_modules`, `.yarn`, `generated/` (client typé), `dist/`, `build/`, les dossiers de couverture, les fichiers journaux et les fichiers `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/** : Verrouillent et configurent la chaîne d’outils Yarn 4 utilisée par le projet.
|
||||
* **.nvmrc** : Fige la version de Node.js attendue par le projet.
|
||||
@@ -173,7 +170,7 @@ Dans les grandes lignes :
|
||||
|
||||
Des commandes ultérieures ajouteront d’autres fichiers et dossiers :
|
||||
|
||||
* `yarn app:generate` créera un dossier `generated/` (client Twenty typé + types de l’espace de travail).
|
||||
* `yarn app:dev` génère automatiquement le client Twenty typé dans `node_modules/twenty-sdk/generated`.
|
||||
* `yarn entity:add` ajoutera des fichiers de définition d’entité sous `src/` pour vos objets, fonctions, composants front-end ou rôles personnalisés.
|
||||
|
||||
## Authentification
|
||||
@@ -585,7 +582,7 @@ Vous pouvez créer de nouvelles fonctions de deux façons :
|
||||
|
||||
### Client typé généré
|
||||
|
||||
Exécutez yarn app:generate pour créer un client typé local dans generated/ basé sur le schéma de votre espace de travail. Utilisez-le dans vos fonctions :
|
||||
`yarn app:dev` génère automatiquement le client Twenty typé dans `node_modules/twenty-sdk/generated`. Utilisez-le dans vos fonctions :
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -594,7 +591,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
Le client est régénéré par `yarn app:generate`. Relancez après avoir modifié vos objets ou lors de l’intégration à un nouvel espace de travail.
|
||||
Le client est régénéré automatiquement pendant l'exécution de `app:dev`. Redémarrez `app:dev` après avoir modifié vos objets ou lors de l’intégration à un nouvel espace de travail.
|
||||
|
||||
#### Identifiants d’exécution dans les fonctions logiques
|
||||
|
||||
@@ -632,7 +629,6 @@ Ajoutez ensuite des scripts comme ceux-ci :
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
@@ -642,13 +638,13 @@ Ajoutez ensuite des scripts comme ceux-ci :
|
||||
}
|
||||
```
|
||||
|
||||
Vous pouvez désormais exécuter les mêmes commandes via Yarn, par exemple `yarn app:dev`, `yarn app:generate`, etc.
|
||||
Vous pouvez désormais exécuter les mêmes commandes via Yarn, par exemple `yarn app:dev`, etc.
|
||||
|
||||
## Résolution des problèmes
|
||||
|
||||
* Erreurs d’authentification : exécutez `yarn auth:login` et assurez-vous que votre clé API dispose des autorisations requises.
|
||||
* Impossible de se connecter au serveur : vérifiez l’URL de l’API et que le serveur Twenty est accessible.
|
||||
* Types ou client manquants/obsolètes : exécutez `yarn app:generate`.
|
||||
* Types ou client manquants/obsolètes : redémarrez `yarn app:dev`.
|
||||
* Le mode dev ne se synchronise pas : assurez-vous que `yarn app:dev` est en cours d’exécution et que les modifications ne sont pas ignorées par votre environnement.
|
||||
|
||||
Canal d’aide Discord : https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -36,32 +36,32 @@ corepack enable
|
||||
yarn install
|
||||
|
||||
# Autenticati usando la tua API key (ti verrà richiesto)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Avvia la modalità di sviluppo: sincronizza automaticamente le modifiche locali con il tuo workspace
|
||||
yarn app:dev
|
||||
yarn twenty app:dev
|
||||
```
|
||||
|
||||
Da qui puoi:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Aggiungi una nuova entità alla tua applicazione (guidata)
|
||||
yarn entity:add
|
||||
|
||||
# Genera un client Twenty tipizzato e i tipi di entità dell'area di lavoro
|
||||
yarn app:generate
|
||||
yarn twenty entity:add
|
||||
|
||||
# Monitora i log delle funzioni della tua applicazione
|
||||
yarn function:logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Esegui una funzione per nome
|
||||
yarn function:execute -n my-function -p '{"name": "test"}'
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Esegui la funzione post-installazione
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Disinstalla l'applicazione dallo spazio di lavoro corrente
|
||||
yarn app:uninstall
|
||||
yarn twenty app:uninstall
|
||||
|
||||
# Mostra l'aiuto dei comandi
|
||||
yarn help
|
||||
yarn twenty help
|
||||
```
|
||||
|
||||
Vedi anche: le pagine di riferimento della CLI per [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) e [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
@@ -73,7 +73,7 @@ Quando esegui `npx create-twenty-app@latest my-twenty-app`, lo scaffolder:
|
||||
* Copia un'applicazione base minimale in `my-twenty-app/`
|
||||
* Aggiunge una dipendenza locale `twenty-sdk` e la configurazione di Yarn 4
|
||||
* Crea file di configurazione e script collegati alla CLI `twenty`
|
||||
* Genera una configurazione applicativa predefinita e un ruolo funzione predefinito
|
||||
* Genera una configurazione applicativa predefinita, un ruolo funzione predefinito e una funzione post-installazione
|
||||
|
||||
Un'app appena generata dallo scaffolder si presenta così:
|
||||
|
||||
@@ -95,14 +95,15 @@ my-twenty-app/
|
||||
├── roles/
|
||||
│ └── default-role.ts # Ruolo predefinito per le funzioni logiche
|
||||
├── logic-functions/
|
||||
│ └── hello-world.ts # Funzione logica di esempio
|
||||
│ ├── hello-world.ts # Funzione logica di esempio
|
||||
│ └── post-install.ts # Funzione logica post-installazione
|
||||
└── front-components/
|
||||
└── hello-world.tsx # Componente front-end di esempio
|
||||
```
|
||||
|
||||
A livello generale:
|
||||
|
||||
* **package.json**: Dichiara il nome dell'app, la versione, i motori (Node 24+, Yarn 4) e aggiunge `twenty-sdk`, oltre a script come `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` e comandi di autenticazione che delegano alla CLI locale `twenty`.
|
||||
* **package.json**: Dichiara il nome dell'app, la versione, i motori (Node 24+, Yarn 4) e aggiunge `twenty-sdk` più uno script `twenty` che delega alla CLI locale `twenty`. Esegui `yarn twenty help` per elencare tutti i comandi disponibili.
|
||||
* **.gitignore**: Ignora i file generati comuni come `node_modules`, `.yarn`, `generated/` (client tipizzato), `dist/`, `build/`, cartelle di coverage, file di log e file `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Bloccano e configurano la toolchain Yarn 4 utilizzata dal progetto.
|
||||
* **.nvmrc**: Fissa la versione di Node.js prevista dal progetto.
|
||||
@@ -142,12 +143,12 @@ export default defineObject({
|
||||
|
||||
Comandi successivi aggiungeranno altri file e cartelle:
|
||||
|
||||
* `yarn app:generate` creerà una cartella `generated/` (client Twenty tipizzato + tipi dello spazio di lavoro).
|
||||
* `yarn entity:add` aggiungerà file di definizione delle entità sotto `src/` per i tuoi oggetti, funzioni, componenti front-end o ruoli personalizzati.
|
||||
* `yarn twenty app:dev` genererà automaticamente un client API tipizzato in `node_modules/twenty-sdk/generated` (client Twenty tipizzato + tipi dell'area di lavoro).
|
||||
* `yarn twenty entity:add` aggiungerà file di definizione delle entità sotto `src/` per i tuoi oggetti, funzioni, componenti front-end o ruoli personalizzati.
|
||||
|
||||
## Autenticazione
|
||||
|
||||
La prima volta che esegui `yarn auth:login`, ti verranno richiesti:
|
||||
La prima volta che esegui `yarn twenty auth:login`, ti verranno richiesti:
|
||||
|
||||
* URL dell'API (predefinito a http://localhost:3000 o al profilo dello spazio di lavoro corrente)
|
||||
* Chiave API
|
||||
@@ -158,25 +159,25 @@ Le tue credenziali sono archiviate per utente in `~/.twenty/config.json`. Puoi m
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn auth:login --workspace my-custom-workspace
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
|
||||
# List all configured workspaces
|
||||
yarn auth:list
|
||||
yarn twenty auth:list
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn auth:switch
|
||||
yarn twenty auth:switch
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn auth:switch production
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn auth:status
|
||||
yarn twenty auth:status
|
||||
```
|
||||
|
||||
Una volta che hai cambiato area di lavoro con `auth:switch`, tutti i comandi successivi utilizzeranno quell'area di lavoro per impostazione predefinita. Puoi comunque sovrascriverla temporaneamente con `--workspace <name>`.
|
||||
Una volta che hai cambiato area di lavoro con `yarn twenty auth:switch`, tutti i comandi successivi utilizzeranno quell'area di lavoro per impostazione predefinita. Puoi comunque sovrascriverla temporaneamente con `--workspace <name>`.
|
||||
|
||||
## Usa le risorse dell'SDK (tipi e configurazione)
|
||||
|
||||
@@ -276,10 +277,14 @@ Punti chiave:
|
||||
* Il `universalIdentifier` deve essere univoco e stabile tra i deployment.
|
||||
* Ogni campo richiede un `name`, `type`, `label` e il proprio `universalIdentifier` stabile.
|
||||
* L'array `fields` è facoltativo: puoi definire oggetti senza campi personalizzati.
|
||||
* Puoi generare nuovi oggetti con `yarn entity:add`, che ti guida nella denominazione, nei campi e nelle relazioni.
|
||||
* Puoi generare nuovi oggetti con `yarn twenty entity:add`, che ti guida nella denominazione, nei campi e nelle relazioni.
|
||||
|
||||
<Note>
|
||||
**I campi base vengono creati automaticamente.** Quando definisci un oggetto personalizzato, Twenty aggiunge automaticamente i campi standard come `name`, `createdAt`, `updatedAt`, `createdBy`, `position` e `deletedAt`. Non è necessario definirli nel tuo array `fields` — aggiungi solo i tuoi campi personalizzati.
|
||||
**I campi base vengono creati automaticamente.** Quando definisci un oggetto personalizzato, Twenty aggiunge automaticamente i campi standard
|
||||
come `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` e `deletedAt`.
|
||||
Non è necessario definirli nel tuo array `fields` — aggiungi solo i tuoi campi personalizzati.
|
||||
Puoi sovrascrivere i campi predefiniti definendo un campo con lo stesso nome nel tuo array `fields`,
|
||||
ma non è consigliato.
|
||||
</Note>
|
||||
|
||||
### Configurazione dell'applicazione (application-config.ts)
|
||||
@@ -289,6 +294,7 @@ Ogni app ha un singolo file `application-config.ts` che descrive:
|
||||
* **Identità dell'app**: identificatori, nome visualizzato e descrizione.
|
||||
* **Come vengono eseguite le sue funzioni**: quale ruolo usano per i permessi.
|
||||
* **Variabili (opzionali)**: coppie chiave–valore esposte alle funzioni come variabili d'ambiente.
|
||||
* **(Opzionale) funzione post-installazione**: una funzione logica che viene eseguita dopo l'installazione dell'app.
|
||||
|
||||
Usa `defineApplication()` per definire la configurazione della tua applicazione:
|
||||
|
||||
@@ -296,6 +302,7 @@ Usa `defineApplication()` per definire la configurazione della tua applicazione:
|
||||
// src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
@@ -311,6 +318,7 @@ export default defineApplication({
|
||||
},
|
||||
},
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -319,6 +327,7 @@ Note:
|
||||
* I campi `universalIdentifier` sono ID deterministici sotto il tuo controllo; generali una volta e mantienili stabili tra le sincronizzazioni.
|
||||
* `applicationVariables` diventano variabili d'ambiente per le tue funzioni (ad esempio, `DEFAULT_RECIPIENT_NAME` è disponibile come `process.env.DEFAULT_RECIPIENT_NAME`).
|
||||
* `defaultRoleUniversalIdentifier` deve corrispondere al file del ruolo (vedi sotto).
|
||||
* `postInstallLogicFunctionUniversalIdentifier` (opzionale) fa riferimento a una funzione logica che viene eseguita automaticamente dopo l'installazione dell'app. Vedi [Funzioni post-installazione](#post-install-functions).
|
||||
|
||||
#### Ruoli e permessi
|
||||
|
||||
@@ -457,6 +466,55 @@ Note:
|
||||
* L'array `triggers` è facoltativo. Le funzioni senza trigger possono essere utilizzate come funzioni di utilità richiamate da altre funzioni.
|
||||
* Puoi combinare più tipi di trigger in un'unica funzione.
|
||||
|
||||
### Funzioni post-installazione
|
||||
|
||||
Una funzione post-installazione è una funzione logica che viene eseguita automaticamente dopo che la tua app è stata installata in uno spazio di lavoro. Questo è utile per attività di configurazione una tantum come il popolamento di dati predefiniti, la creazione di record iniziali o la configurazione delle impostazioni dello spazio di lavoro.
|
||||
|
||||
When you scaffold a new app with `create-twenty-app`, a post-install function is generated for you at `src/logic-functions/post-install.ts`:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/post-install.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
|
||||
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
|
||||
|
||||
const handler = async (): Promise<void> => {
|
||||
console.log('Post install logic function executed successfully!');
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
name: 'post-install',
|
||||
description: 'Runs after installation to set up the application.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
The function is wired into your app by referencing its universal identifier in `application-config.ts`:
|
||||
|
||||
```typescript
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
// ...
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
You can also manually execute the post-install function at any time using the CLI:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty function:execute --postInstall
|
||||
```
|
||||
|
||||
Punti chiave:
|
||||
|
||||
* Post-install functions are standard logic functions — they use `defineLogicFunction()` like any other function.
|
||||
* The `postInstallLogicFunctionUniversalIdentifier` field in `defineApplication()` is optional. If omitted, no function runs after installation.
|
||||
* The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `function:execute --postInstall`.
|
||||
|
||||
### Payload del trigger di route
|
||||
|
||||
<Warning>
|
||||
@@ -551,9 +609,74 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Puoi creare nuove funzioni in due modi:
|
||||
|
||||
* **Generata dallo scaffolder**: Esegui `yarn entity:add` e scegli l'opzione per aggiungere una nuova funzione logica. Questo genera un file iniziale con un handler e una configurazione.
|
||||
* **Generata dallo scaffolder**: Esegui `yarn twenty entity:add` e scegli l'opzione per aggiungere una nuova funzione logica. Questo genera un file iniziale con un handler e una configurazione.
|
||||
* **Manuale**: Crea un nuovo file `*.logic-function.ts` e usa `defineLogicFunction()`, seguendo lo stesso schema.
|
||||
|
||||
### Contrassegnare una funzione logica come strumento
|
||||
|
||||
Le funzioni logiche possono essere esposte come **strumenti** per gli agenti di IA e i flussi di lavoro. Quando una funzione è contrassegnata come strumento, diventa individuabile dalle funzionalità di IA di Twenty e può essere selezionata come passaggio nelle automazioni dei flussi di lavoro.
|
||||
|
||||
Per contrassegnare una funzione logica come strumento, imposta `isTool: true` e fornisci un `toolInputSchema` che descriva i parametri di input attesi utilizzando [JSON Schema](https://json-schema.org/):
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/enrich-company.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import Twenty from '~/generated';
|
||||
|
||||
const handler = async (params: { companyName: string; domain?: string }) => {
|
||||
const client = new Twenty();
|
||||
|
||||
const result = await client.mutation({
|
||||
createTask: {
|
||||
__args: {
|
||||
data: {
|
||||
title: `Enrich data for ${params.companyName}`,
|
||||
body: `Domain: ${params.domain ?? 'unknown'}`,
|
||||
},
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
return { taskId: result.createTask.id };
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
|
||||
name: 'enrich-company',
|
||||
description: 'Enrich a company record with external data',
|
||||
timeoutSeconds: 10,
|
||||
handler,
|
||||
isTool: true,
|
||||
toolInputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
companyName: {
|
||||
type: 'string',
|
||||
description: 'The name of the company to enrich',
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
description: 'The company website domain (optional)',
|
||||
},
|
||||
},
|
||||
required: ['companyName'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Punti chiave:
|
||||
|
||||
* **`isTool`** (`boolean`, predefinito: `false`): Quando impostato su `true`, la funzione viene registrata come strumento e diventa disponibile per gli agenti IA e le automazioni dei flussi di lavoro.
|
||||
* **`toolInputSchema`** (`object`, opzionale): Un oggetto JSON Schema che descrive i parametri accettati dalla funzione. Gli agenti IA utilizzano questo schema per capire quali input si aspetta lo strumento e per convalidare le chiamate. Se omesso, lo schema assume il valore predefinito `{ type: 'object', properties: {} }` (nessun parametro).
|
||||
* Le funzioni con `isTool: false` (o non impostato) **non** vengono esposte come strumenti. Possono comunque essere eseguite direttamente o chiamate da altre funzioni, ma non compariranno nell'individuazione degli strumenti.
|
||||
* **Denominazione dello strumento**: Quando esposta come strumento, il nome della funzione viene normalizzato automaticamente in `logic_function_<name>` (in minuscolo, i caratteri non alfanumerici vengono sostituiti da trattini bassi). Ad esempio, `enrich-company` diventa `logic_function_enrich_company`.
|
||||
* È possibile combinare `isTool` con i trigger — una funzione può essere sia uno strumento (invocabile dagli agenti IA) sia attivata da eventi (cron, eventi del database, routes) contemporaneamente.
|
||||
|
||||
<Note>
|
||||
**Scrivi una buona `description`.** Gli agenti IA fanno affidamento sul campo `description` della funzione per decidere quando usare lo strumento. Sii specifico su cosa fa lo strumento e quando dovrebbe essere invocato.
|
||||
</Note>
|
||||
|
||||
### Componenti front-end
|
||||
|
||||
I componenti front-end ti consentono di creare componenti React personalizzati che vengono renderizzati all'interno dell'interfaccia di Twenty. Usa `defineFrontComponent()` per definire componenti con convalida integrata:
|
||||
@@ -584,16 +707,16 @@ Punti chiave:
|
||||
* I componenti front-end sono componenti React che eseguono il rendering in contesti isolati all'interno di Twenty.
|
||||
* Usa il suffisso di file `*.front-component.tsx` per il rilevamento automatico.
|
||||
* Il campo `component` fa riferimento al tuo componente React.
|
||||
* I componenti vengono compilati e sincronizzati automaticamente durante `yarn app:dev`.
|
||||
* I componenti vengono compilati e sincronizzati automaticamente durante `yarn twenty app:dev`.
|
||||
|
||||
Puoi creare nuovi componenti front-end in due modi:
|
||||
|
||||
* **Generata dallo scaffolder**: Esegui `yarn entity:add` e scegli l'opzione per aggiungere un nuovo componente front-end.
|
||||
* **Generata dallo scaffolder**: Esegui `yarn twenty entity:add` e scegli l'opzione per aggiungere un nuovo componente front-end.
|
||||
* **Manuale**: Crea un nuovo file `*.front-component.tsx` e usa `defineFrontComponent()`.
|
||||
|
||||
### Client tipizzato generato
|
||||
|
||||
Esegui yarn app:generate per creare un client tipizzato locale in generated/ basato sullo schema del tuo spazio di lavoro. Usalo nelle tue funzioni:
|
||||
Il client tipizzato è generato automaticamente da `yarn twenty app:dev` e salvato in `node_modules/twenty-sdk/generated` in base allo schema della tua area di lavoro. Usalo nelle tue funzioni:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -602,7 +725,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
Il client viene rigenerato da `yarn app:generate`. Eseguilo nuovamente dopo aver modificato i tuoi oggetti oppure quando effettui l'onboarding su un nuovo spazio di lavoro.
|
||||
Il client viene rigenerato automaticamente da `yarn twenty app:dev` ogni volta che i tuoi oggetti o campi cambiano.
|
||||
|
||||
#### Credenziali di runtime nelle funzioni logiche
|
||||
|
||||
@@ -623,40 +746,29 @@ Esplora un esempio minimale end-to-end che dimostra oggetti, funzioni logiche, c
|
||||
|
||||
## Configurazione manuale (senza lo scaffolder)
|
||||
|
||||
Sebbene consigliamo di utilizzare `create-twenty-app` per la migliore esperienza iniziale, puoi anche configurare un progetto manualmente. Non installare la CLI globalmente. Invece, aggiungi `twenty-sdk` come dipendenza locale e collega gli script nel tuo package.json:
|
||||
Sebbene consigliamo di utilizzare `create-twenty-app` per la migliore esperienza iniziale, puoi anche configurare un progetto manualmente. Non installare la CLI globalmente. Invece, aggiungi `twenty-sdk` come dipendenza locale e collega un unico script nel tuo package.json:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
```
|
||||
|
||||
Quindi aggiungi script come questi:
|
||||
Quindi aggiungi uno script `twenty`:
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
"auth:login": "twenty auth:login",
|
||||
"auth:logout": "twenty auth:logout",
|
||||
"auth:status": "twenty auth:status",
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
"function:execute": "twenty function:execute",
|
||||
"help": "twenty help"
|
||||
"twenty": "twenty"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Ora puoi eseguire gli stessi comandi tramite Yarn, ad esempio `yarn app:dev`, `yarn app:generate`, ecc.
|
||||
Ora puoi eseguire tutti i comandi tramite `yarn twenty <command>`, ad es. `yarn twenty app:dev`, `yarn twenty help`, ecc.
|
||||
|
||||
## Risoluzione dei problemi
|
||||
|
||||
* Errori di autenticazione: esegui `yarn auth:login` e assicurati che la tua chiave API abbia i permessi richiesti.
|
||||
* Errori di autenticazione: esegui `yarn twenty auth:login` e assicurati che la tua chiave API abbia i permessi richiesti.
|
||||
* Impossibile connettersi al server: verifica l'URL dell'API e che il server Twenty sia raggiungibile.
|
||||
* Tipi o client mancanti/obsoleti: esegui `yarn app:generate`.
|
||||
* Modalità di sviluppo non in sincronizzazione: assicurati che `yarn app:dev` sia in esecuzione e che le modifiche non vengano ignorate dal tuo ambiente.
|
||||
* Types or client missing/outdated: restart `yarn twenty app:dev` — it auto-generates the typed client.
|
||||
* Modalità di sviluppo non sincronizzata: assicurati che `yarn twenty app:dev` sia in esecuzione e che le modifiche non vengano ignorate dal tuo ambiente.
|
||||
|
||||
Canale di supporto su Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -52,9 +52,6 @@ yarn app:dev
|
||||
# アプリケーションに新しいエンティティを追加(ガイド付き)
|
||||
yarn entity:add
|
||||
|
||||
# 型付きの Twenty クライアントとワークスペースのエンティティ型を生成
|
||||
yarn app:generate
|
||||
|
||||
# アプリケーションの関数のログを監視
|
||||
yarn function:logs
|
||||
|
||||
@@ -156,7 +153,7 @@ src/
|
||||
|
||||
概要:
|
||||
|
||||
* **package.json**: Declares the app name, version, engines (Node 24+, Yarn 4), and adds `twenty-sdk` plus scripts like `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall`, and `auth:login` that delegate to the local `twenty` CLI.
|
||||
* **package.json**: Declares the app name, version, engines (Node 24+, Yarn 4), and adds `twenty-sdk` plus scripts like `app:dev`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall`, and `auth:login` that delegate to the local `twenty` CLI.
|
||||
* **.gitignore**: `node_modules`、`.yarn`、`generated/`(型付きクライアント)、`dist/`、`build/`、カバレッジ用フォルダー、ログファイル、`.env*` ファイルなどの一般的な生成物を無視します。
|
||||
* **yarn.lock**、**.yarnrc.yml**、**.yarn/**: プロジェクトで使用する Yarn 4 ツールチェーンをロックおよび構成します。
|
||||
* **.nvmrc**: プロジェクトで想定する Node.js バージョンを固定します。
|
||||
@@ -171,7 +168,7 @@ src/
|
||||
|
||||
後続のコマンドにより、さらにファイルやフォルダーが追加されます:
|
||||
|
||||
* `yarn app:generate` は `generated/` フォルダー(型付きの Twenty クライアント + ワークスペースの型)を作成します。
|
||||
* `yarn app:dev` は `node_modules/twenty-sdk/generated` に型付き Twenty クライアントを自動生成します。
|
||||
* `yarn entity:add` will add entity definition files under `src/` for your custom objects, functions, front components, or roles.
|
||||
|
||||
## 認証
|
||||
@@ -583,7 +580,7 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
### 生成された型付きクライアント
|
||||
|
||||
ワークスペースのスキーマに基づき、generated/ にローカルの型付きクライアントを作成するには yarn app:generate を実行します。 関数内で使用します:
|
||||
`yarn app:dev` は `node_modules/twenty-sdk/generated` に型付き Twenty クライアントを自動生成します。 関数内で使用します:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -592,7 +589,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
このクライアントは `yarn app:generate` によって再生成されます。 Re-run after changing your objects or when onboarding to a new workspace.
|
||||
このクライアントは `app:dev` 実行中に自動的に再生成されます。 オブジェクトを変更した後、または新しいワークスペースにオンボーディングする際は、`app:dev` を再起動してください。
|
||||
|
||||
#### Runtime credentials in logic functions
|
||||
|
||||
@@ -630,7 +627,6 @@ yarn add -D twenty-sdk
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
@@ -640,13 +636,13 @@ yarn add -D twenty-sdk
|
||||
}
|
||||
```
|
||||
|
||||
Now you can run the same commands via Yarn, e.g. `yarn app:dev`, `yarn app:generate`, etc.
|
||||
Now you can run the same commands via Yarn, e.g. `yarn app:dev`, etc.
|
||||
|
||||
## トラブルシューティング
|
||||
|
||||
* 認証エラー: `yarn auth:login` を実行し、API キーに必要な権限があることを確認してください。
|
||||
* サーバーに接続できません: API URL と、Twenty サーバーに到達可能であることを確認してください。
|
||||
* Types or client missing/outdated: run `yarn app:generate`.
|
||||
* Types or client missing/outdated: restart `yarn app:dev`.
|
||||
* 開発モードで同期されない: `yarn app:dev` が実行中であり、環境によって変更が無視されていないことを確認してください。
|
||||
|
||||
Discord ヘルプチャンネル: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -52,9 +52,6 @@ yarn app:dev
|
||||
# Add a new entity to your application (guided)
|
||||
yarn entity:add
|
||||
|
||||
# Generate a typed Twenty client and workspace entity types
|
||||
yarn app:generate
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn function:logs
|
||||
|
||||
@@ -157,7 +154,7 @@ src/
|
||||
|
||||
개요:
|
||||
|
||||
* **package.json**: 앱 이름, 버전, 엔진(Node 24+, Yarn 4)을 선언하고, `twenty-sdk`와 함께 `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall`, `auth:login` 같은 스크립트를 추가합니다. 이 스크립트들은 로컬 `twenty` CLI에 위임됩니다.
|
||||
* **package.json**: 앱 이름, 버전, 엔진(Node 24+, Yarn 4)을 선언하고, `twenty-sdk`와 함께 `app:dev`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall`, `auth:login` 같은 스크립트를 추가합니다. 이 스크립트들은 로컬 `twenty` CLI에 위임됩니다.
|
||||
* **.gitignore**: `node_modules`, `.yarn`, `generated/`(타입드 클라이언트), `dist/`, `build/`, 커버리지 폴더, 로그 파일, `.env*` 파일 등의 일반 산출물을 무시합니다.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: 프로젝트에서 사용하는 Yarn 4 툴체인을 고정하고 구성합니다.
|
||||
* **.nvmrc**: 프로젝트에서 예상하는 Node.js 버전을 고정합니다.
|
||||
@@ -173,7 +170,7 @@ src/
|
||||
|
||||
이후 명령을 실행하면 더 많은 파일과 폴더가 추가됩니다:
|
||||
|
||||
* `yarn app:generate`는 `generated/` 폴더를 생성합니다(타입드 Twenty 클라이언트 + 워크스페이스 타입).
|
||||
* `yarn app:dev`는 `node_modules/twenty-sdk/generated`에 타입드 Twenty 클라이언트를 자동으로 생성합니다.
|
||||
* `yarn entity:add`는 사용자 정의 객체, 함수, 프런트 컴포넌트 또는 역할에 대한 엔티티 정의 파일을 `src/` 아래에 추가합니다.
|
||||
|
||||
## 인증
|
||||
@@ -585,7 +582,7 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
### 생성된 타입드 클라이언트
|
||||
|
||||
워크스페이스 스키마를 기반으로 generated/에 로컬 타입드 클라이언트를 생성하려면 yarn app:generate를 실행하세요. 함수에서 사용하세요:
|
||||
`yarn app:dev`는 `node_modules/twenty-sdk/generated`에 타입드 Twenty 클라이언트를 자동으로 생성합니다. 함수에서 사용하세요:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -594,7 +591,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
클라이언트는 `yarn app:generate`로 다시 생성됩니다. 객체를 변경한 후 또는 새 워크스페이스에 온보딩할 때 다시 실행하세요.
|
||||
클라이언트는 `app:dev` 실행 중 자동으로 다시 생성됩니다. 객체를 변경한 후 또는 새 워크스페이스에 온보딩할 때 `app:dev`를 다시 시작하세요.
|
||||
|
||||
#### 로직 함수의 런타임 자격 증명
|
||||
|
||||
@@ -632,7 +629,6 @@ yarn add -D twenty-sdk
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
@@ -642,13 +638,13 @@ yarn add -D twenty-sdk
|
||||
}
|
||||
```
|
||||
|
||||
이제 Yarn을 통해 동일한 명령을 실행할 수 있습니다. 예: `yarn app:dev`, `yarn app:generate` 등.
|
||||
이제 Yarn을 통해 동일한 명령을 실행할 수 있습니다. 예: `yarn app:dev` 등.
|
||||
|
||||
## 문제 해결
|
||||
|
||||
* 인증 오류: `yarn auth:login`를 실행하고 API 키에 필요한 권한이 있는지 확인하세요.
|
||||
* 서버에 연결할 수 없음: API URL과 Twenty 서버에 접근 가능한지 확인하세요.
|
||||
* 타입 또는 클라이언트가 없거나 오래된 경우: `yarn app:generate`를 실행하세요.
|
||||
* 타입 또는 클라이언트가 없거나 오래된 경우: `yarn app:dev`를 다시 시작하세요.
|
||||
* 개발 모드가 동기화되지 않음: `yarn app:dev`가 실행 중인지, 환경에서 변경 사항을 무시하지 않는지 확인하세요.
|
||||
|
||||
Discord 도움말 채널: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -27,41 +27,41 @@ Os aplicativos permitem criar e gerenciar personalizações do Twenty **como có
|
||||
Crie um novo aplicativo usando o gerador oficial, depois autentique-se e comece a desenvolver:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Criar a estrutura de um novo app
|
||||
# Scaffold a new app
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
cd my-twenty-app
|
||||
|
||||
# Se você não usa yarn@4
|
||||
# If you don't use yarn@4
|
||||
corepack enable
|
||||
yarn install
|
||||
|
||||
# Autentique-se usando sua chave de API (você será solicitado)
|
||||
yarn auth:login
|
||||
# Authenticate using your API key (you'll be prompted)
|
||||
yarn twenty auth:login
|
||||
|
||||
# Iniciar modo de desenvolvimento: sincroniza automaticamente as alterações locais com seu workspace
|
||||
yarn app:dev
|
||||
# Start dev mode: automatically syncs local changes to your workspace
|
||||
yarn twenty app:dev
|
||||
```
|
||||
|
||||
A partir daqui você pode:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Adicionar uma nova entidade à sua aplicação (assistido)
|
||||
yarn entity:add
|
||||
# Add a new entity to your application (guided)
|
||||
yarn twenty entity:add
|
||||
|
||||
# Gerar um cliente Twenty tipado e tipos de entidades do espaço de trabalho
|
||||
yarn app:generate
|
||||
# Watch your application's function logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Acompanhar os logs das funções da sua aplicação
|
||||
yarn function:logs
|
||||
# Execute a function by name
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Executar uma função pelo nome
|
||||
yarn function:execute -n my-function -p '{\"name\": \"test\"}'
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Desinstalar a aplicação do espaço de trabalho atual
|
||||
yarn app:uninstall
|
||||
# Uninstall the application from the current workspace
|
||||
yarn twenty app:uninstall
|
||||
|
||||
# Exibir a ajuda dos comandos
|
||||
yarn help
|
||||
# Display commands' help
|
||||
yarn twenty help
|
||||
```
|
||||
|
||||
Veja também: as páginas de referência da CLI para [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) e [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
@@ -73,7 +73,7 @@ Ao executar `npx create-twenty-app@latest my-twenty-app`, o gerador:
|
||||
* Copia um aplicativo base mínimo para `my-twenty-app/`
|
||||
* Adiciona uma dependência local `twenty-sdk` e a configuração do Yarn 4
|
||||
* Cria arquivos de configuração e scripts conectados à CLI `twenty`
|
||||
* Gera uma configuração de aplicativo padrão e um papel padrão para as funções
|
||||
* Generates a default application config, a default function role, and a post-install function
|
||||
|
||||
Um aplicativo recém-criado pelo scaffold fica assim:
|
||||
|
||||
@@ -89,20 +89,21 @@ my-twenty-app/
|
||||
eslint.config.mjs
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # Pasta de recursos públicos (imagens, fontes, etc.)
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Obrigatório - configuração principal da aplicação
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── roles/
|
||||
│ └── default-role.ts # Papel padrão para funções de lógica
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── logic-functions/
|
||||
│ └── hello-world.ts # Exemplo de função de lógica
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
└── front-components/
|
||||
└── hello-world.tsx # Exemplo de componente de front-end
|
||||
└── hello-world.tsx # Example front component
|
||||
```
|
||||
|
||||
Em alto nível:
|
||||
|
||||
* **package.json**: Declara o nome do app, versão, engines (Node 24+, Yarn 4) e adiciona `twenty-sdk`, além de scripts como `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` e comandos de autenticação que delegam para a CLI local `twenty`.
|
||||
* **package.json**: Declara o nome do app, versão, engines (Node 24+, Yarn 4), e adiciona `twenty-sdk` além de um script `twenty` que delega para a CLI `twenty` local. Execute `yarn twenty help` para listar todos os comandos disponíveis.
|
||||
* **.gitignore**: Ignora artefatos comuns como `node_modules`, `.yarn`, `generated/` (cliente tipado), `dist/`, `build/`, pastas de cobertura, arquivos de log e arquivos `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Bloqueiam e configuram a ferramenta Yarn 4 usada pelo projeto.
|
||||
* **.nvmrc**: Fixa a versão do Node.js esperada pelo projeto.
|
||||
@@ -142,12 +143,12 @@ export default defineObject({
|
||||
|
||||
Comandos posteriores adicionarão mais arquivos e pastas:
|
||||
|
||||
* `yarn app:generate` criará uma pasta `generated/` (cliente tipado do Twenty + tipos do workspace).
|
||||
* `yarn entity:add` adicionará arquivos de definição de entidade em `src/` para seus objetos, funções, componentes de front-end ou papéis personalizados.
|
||||
* `yarn twenty app:dev` vai gerar automaticamente um cliente de API tipado em `node_modules/twenty-sdk/generated` (cliente Twenty tipado + tipos do espaço de trabalho).
|
||||
* `yarn twenty entity:add` adicionará arquivos de definição de entidade em `src/` para seus objetos, funções, componentes de front-end ou papéis personalizados.
|
||||
|
||||
## Autenticação
|
||||
|
||||
Na primeira vez que você executar `yarn auth:login`, será solicitado o seguinte:
|
||||
Na primeira vez que você executar `yarn twenty auth:login`, será solicitado o seguinte:
|
||||
|
||||
* URL da API (padrão: http://localhost:3000 ou o perfil do seu espaço de trabalho atual)
|
||||
* Chave de API
|
||||
@@ -158,25 +159,25 @@ Suas credenciais são armazenadas por usuário em `~/.twenty/config.json`. Você
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Fazer login interativamente (recomendado)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Fazer login em um perfil de espaço de trabalho específico
|
||||
yarn auth:login --workspace my-custom-workspace
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
|
||||
# Listar todos os espaços de trabalho configurados
|
||||
yarn auth:list
|
||||
yarn twenty auth:list
|
||||
|
||||
# Alterar o espaço de trabalho padrão (interativo)
|
||||
yarn auth:switch
|
||||
yarn twenty auth:switch
|
||||
|
||||
# Alternar para um espaço de trabalho específico
|
||||
yarn auth:switch production
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Verificar o status atual da autenticação
|
||||
yarn auth:status
|
||||
yarn twenty auth:status
|
||||
```
|
||||
|
||||
Depois que você alternar os espaços de trabalho com `auth:switch`, todos os comandos subsequentes usarão esse espaço de trabalho por padrão. Você ainda pode substituí-lo temporariamente com `--workspace <name>`.
|
||||
Depois que você alternar os espaços de trabalho com `yarn twenty auth:switch`, todos os comandos subsequentes usarão esse espaço de trabalho por padrão. Você ainda pode substituí-lo temporariamente com `--workspace <name>`.
|
||||
|
||||
## Use os recursos do SDK (tipos e configuração)
|
||||
|
||||
@@ -276,10 +277,14 @@ Pontos-chave:
|
||||
* O `universalIdentifier` deve ser exclusivo e estável entre implantações.
|
||||
* Cada campo requer `name`, `type`, `label` e seu próprio `universalIdentifier` estável.
|
||||
* O array `fields` é opcional — você pode definir objetos sem campos personalizados.
|
||||
* Você pode criar novos objetos usando `yarn entity:add`, que orienta você sobre nomeação, campos e relacionamentos.
|
||||
* Você pode criar novos objetos usando `yarn twenty entity:add`, que orienta você sobre nomeação, campos e relacionamentos.
|
||||
|
||||
<Note>
|
||||
**Os campos base são criados automaticamente.** Quando você define um objeto personalizado, o Twenty adiciona automaticamente campos padrão como `name`, `createdAt`, `updatedAt`, `createdBy`, `position` e `deletedAt`. Você não precisa definir esses no seu array `fields` — adicione apenas seus campos personalizados.
|
||||
**Os campos base são criados automaticamente.** Quando você define um objeto personalizado, o Twenty adiciona automaticamente campos padrão
|
||||
como `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` e `deletedAt`.
|
||||
Você não precisa definir esses no seu array `fields` — adicione apenas seus campos personalizados.
|
||||
Você pode substituir os campos padrão definindo um campo com o mesmo nome no seu array `fields`,
|
||||
mas isso não é recomendado.
|
||||
</Note>
|
||||
|
||||
### Configuração do aplicativo (application-config.ts)
|
||||
@@ -289,6 +294,7 @@ Todo aplicativo tem um único arquivo `application-config.ts` que descreve:
|
||||
* **O que é o aplicativo**: identificadores, nome de exibição e descrição.
|
||||
* **Como suas funções são executadas**: qual papel usam para permissões.
|
||||
* **Variáveis (opcional)**: pares chave–valor expostos às suas funções como variáveis de ambiente.
|
||||
* **(Optional) post-install function**: a logic function that runs after the app is installed.
|
||||
|
||||
Use `defineApplication()` to define your application configuration:
|
||||
|
||||
@@ -296,6 +302,7 @@ Use `defineApplication()` to define your application configuration:
|
||||
// src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
@@ -311,6 +318,7 @@ export default defineApplication({
|
||||
},
|
||||
},
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -319,6 +327,7 @@ Notas:
|
||||
* `universalIdentifier` são IDs determinísticos que você controla; gere-os uma vez e mantenha-os estáveis entre sincronizações.
|
||||
* `applicationVariables` tornam-se variáveis de ambiente para suas funções (por exemplo, `DEFAULT_RECIPIENT_NAME` fica disponível como `process.env.DEFAULT_RECIPIENT_NAME`).
|
||||
* `defaultRoleUniversalIdentifier` deve corresponder ao arquivo do papel (veja abaixo).
|
||||
* `postInstallLogicFunctionUniversalIdentifier` (optional) points to a logic function that runs automatically after the app is installed. See [Post-install functions](#post-install-functions).
|
||||
|
||||
#### Papéis e permissões
|
||||
|
||||
@@ -457,6 +466,55 @@ Notas:
|
||||
* O array `triggers` é opcional. Funções sem gatilhos podem ser usadas como funções utilitárias chamadas por outras funções.
|
||||
* Você pode misturar vários tipos de gatilho em uma única função.
|
||||
|
||||
### Post-install functions
|
||||
|
||||
A post-install function is a logic function that runs automatically after your app is installed on a workspace. This is useful for one-time setup tasks such as seeding default data, creating initial records, or configuring workspace settings.
|
||||
|
||||
When you scaffold a new app with `create-twenty-app`, a post-install function is generated for you at `src/logic-functions/post-install.ts`:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/post-install.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
|
||||
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
|
||||
|
||||
const handler = async (): Promise<void> => {
|
||||
console.log('Post install logic function executed successfully!');
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
name: 'post-install',
|
||||
description: 'Runs after installation to set up the application.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
The function is wired into your app by referencing its universal identifier in `application-config.ts`:
|
||||
|
||||
```typescript
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
// ...
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
You can also manually execute the post-install function at any time using the CLI:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty function:execute --postInstall
|
||||
```
|
||||
|
||||
Pontos-chave:
|
||||
|
||||
* Post-install functions are standard logic functions — they use `defineLogicFunction()` like any other function.
|
||||
* The `postInstallLogicFunctionUniversalIdentifier` field in `defineApplication()` is optional. If omitted, no function runs after installation.
|
||||
* The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `function:execute --postInstall`.
|
||||
|
||||
### Payload de gatilho de rota
|
||||
|
||||
<Warning>
|
||||
@@ -551,9 +609,74 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Você pode criar novas funções de duas formas:
|
||||
|
||||
* **Gerado automaticamente**: Execute `yarn entity:add` e escolha a opção para adicionar uma nova função de lógica. Isso gera um arquivo inicial com um handler e configuração.
|
||||
* **Gerado automaticamente**: Execute `yarn twenty entity:add` e escolha a opção para adicionar uma nova função de lógica. Isso gera um arquivo inicial com um handler e configuração.
|
||||
* **Manual**: Crie um novo arquivo `*.logic-function.ts` e use `defineLogicFunction()`, seguindo o mesmo padrão.
|
||||
|
||||
### Marcar uma função lógica como ferramenta
|
||||
|
||||
Funções lógicas podem ser expostas como **ferramentas** para agentes de IA e fluxos de trabalho. Quando uma função é marcada como ferramenta, ela fica disponível para os recursos de IA do Twenty e pode ser selecionada como uma etapa em automações de fluxos de trabalho.
|
||||
|
||||
Para marcar uma função lógica como ferramenta, defina `isTool: true` e forneça um `toolInputSchema` descrevendo os parâmetros de entrada esperados usando [JSON Schema](https://json-schema.org/):
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/enrich-company.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import Twenty from '~/generated';
|
||||
|
||||
const handler = async (params: { companyName: string; domain?: string }) => {
|
||||
const client = new Twenty();
|
||||
|
||||
const result = await client.mutation({
|
||||
createTask: {
|
||||
__args: {
|
||||
data: {
|
||||
title: `Enrich data for ${params.companyName}`,
|
||||
body: `Domain: ${params.domain ?? 'unknown'}`,
|
||||
},
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
return { taskId: result.createTask.id };
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
|
||||
name: 'enrich-company',
|
||||
description: 'Enrich a company record with external data',
|
||||
timeoutSeconds: 10,
|
||||
handler,
|
||||
isTool: true,
|
||||
toolInputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
companyName: {
|
||||
type: 'string',
|
||||
description: 'The name of the company to enrich',
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
description: 'The company website domain (optional)',
|
||||
},
|
||||
},
|
||||
required: ['companyName'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Pontos-chave:
|
||||
|
||||
* **`isTool`** (`boolean`, padrão: `false`): Quando definido como `true`, a função é registrada como uma ferramenta e fica disponível para agentes de IA e automações de fluxos de trabalho.
|
||||
* **`toolInputSchema`** (`object`, opcional): Um objeto JSON Schema que descreve os parâmetros que sua função aceita. Os agentes de IA usam esse esquema para entender quais entradas a ferramenta espera e para validar as chamadas. Se omitido, o esquema tem como padrão `{ type: 'object', properties: {} }` (sem parâmetros).
|
||||
* Funções com `isTool: false` (ou não definido) **não** são expostas como ferramentas. Elas ainda podem ser executadas diretamente ou chamadas por outras funções, mas não aparecerão na descoberta de ferramentas.
|
||||
* **Nomenclatura de ferramentas**: Quando exposta como uma ferramenta, o nome da função é automaticamente normalizado para `logic_function_<name>` (em minúsculas, caracteres não alfanuméricos substituídos por sublinhados). Por exemplo, `enrich-company` torna-se `logic_function_enrich_company`.
|
||||
* Você pode combinar `isTool` com gatilhos — uma função pode ser ao mesmo tempo uma ferramenta (chamável por agentes de IA) e acionada por eventos (cron, eventos de banco de dados, rotas) simultaneamente.
|
||||
|
||||
<Note>
|
||||
**Escreva uma boa `description`.** Os agentes de IA dependem do campo `description` da função para decidir quando usar a ferramenta. Seja específico sobre o que a ferramenta faz e quando ela deve ser chamada.
|
||||
</Note>
|
||||
|
||||
### Componentes de front-end
|
||||
|
||||
Componentes de front-end permitem criar componentes React personalizados que são renderizados na UI do Twenty. Use `defineFrontComponent()` para definir componentes com validação integrada:
|
||||
@@ -584,16 +707,16 @@ Pontos-chave:
|
||||
* Componentes de front-end são componentes React que renderizam em contextos isolados dentro do Twenty.
|
||||
* Use o sufixo de arquivo `*.front-component.tsx` para detecção automática.
|
||||
* O campo `component` faz referência ao seu componente React.
|
||||
* Os componentes são compilados e sincronizados automaticamente durante `yarn app:dev`.
|
||||
* Os componentes são compilados e sincronizados automaticamente durante `yarn twenty app:dev`.
|
||||
|
||||
Você pode criar novos componentes de front-end de duas formas:
|
||||
|
||||
* **Gerado automaticamente**: Execute `yarn entity:add` e escolha a opção para adicionar um novo componente de front-end.
|
||||
* **Gerado automaticamente**: Execute `yarn twenty entity:add` e escolha a opção para adicionar um novo componente de front-end.
|
||||
* **Manual**: Crie um novo arquivo `*.front-component.tsx` e use `defineFrontComponent()`.
|
||||
|
||||
### Cliente tipado gerado
|
||||
|
||||
Execute yarn app:generate para criar um cliente tipado local em generated/ com base no esquema do seu workspace. Use-o em suas funções:
|
||||
O cliente tipado é gerado automaticamente pelo `yarn twenty app:dev` e armazenado em `node_modules/twenty-sdk/generated` com base no esquema do seu espaço de trabalho. Use-o em suas funções:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -602,7 +725,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
O cliente é regenerado pelo `yarn app:generate`. Execute novamente após alterar seus objetos ou ao ingressar em um novo workspace.
|
||||
O cliente é regenerado automaticamente pelo `yarn twenty app:dev` sempre que seus objetos ou campos forem alterados.
|
||||
|
||||
#### Credenciais em tempo de execução em funções de lógica
|
||||
|
||||
@@ -623,40 +746,29 @@ Explore um exemplo mínimo de ponta a ponta que demonstra objetos, funções de
|
||||
|
||||
## Configuração manual (sem o gerador)
|
||||
|
||||
Embora recomendemos usar `create-twenty-app` para a melhor experiência inicial, você também pode configurar um projeto manualmente. Não instale a CLI globalmente. Em vez disso, adicione `twenty-sdk` como uma dependência local e conecte scripts no seu package.json:
|
||||
Embora recomendemos usar `create-twenty-app` para a melhor experiência inicial, você também pode configurar um projeto manualmente. Não instale a CLI globalmente. Em vez disso, adicione `twenty-sdk` como uma dependência local e configure um único script no seu package.json:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
```
|
||||
|
||||
Em seguida, adicione scripts como estes:
|
||||
Em seguida, adicione um script `twenty`:
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
"auth:login": "twenty auth:login",
|
||||
"auth:logout": "twenty auth:logout",
|
||||
"auth:status": "twenty auth:status",
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
"function:execute": "twenty function:execute",
|
||||
"help": "twenty help"
|
||||
"twenty": "twenty"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Agora você pode executar os mesmos comandos via Yarn, por exemplo, `yarn app:dev`, `yarn app:generate`, etc.
|
||||
Agora você pode executar todos os comandos via `yarn twenty <command>`, por exemplo, `yarn twenty app:dev`, `yarn twenty help`, etc.
|
||||
|
||||
## Resolução de Problemas
|
||||
|
||||
* Erros de autenticação: execute `yarn auth:login` e certifique-se de que sua chave de API tenha as permissões necessárias.
|
||||
* Erros de autenticação: execute `yarn twenty auth:login` e certifique-se de que sua chave de API tenha as permissões necessárias.
|
||||
* Não é possível conectar ao servidor: verifique a URL da API e se o servidor do Twenty está acessível.
|
||||
* Tipos ou cliente ausentes/desatualizados: execute `yarn app:generate`.
|
||||
* Modo de desenvolvimento não sincronizando: certifique-se de que `yarn app:dev` esteja em execução e de que as alterações não estejam sendo ignoradas pelo seu ambiente.
|
||||
* Tipos ou cliente ausentes/desatualizados: reinicie `yarn twenty app:dev` — ele gera automaticamente o cliente tipado.
|
||||
* Modo de desenvolvimento não sincronizando: certifique-se de que `yarn twenty app:dev` esteja em execução e de que as alterações não estejam sendo ignoradas pelo seu ambiente.
|
||||
|
||||
Canal de ajuda no Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -36,32 +36,32 @@ corepack enable
|
||||
yarn install
|
||||
|
||||
# Autentifică-te folosind cheia ta API (ți se va solicita)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Pornește modul de dezvoltare: sincronizează automat modificările locale cu spațiul tău de lucru
|
||||
yarn app:dev
|
||||
yarn twenty app:dev
|
||||
```
|
||||
|
||||
De aici puteți:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Adaugă o entitate nouă în aplicația ta (ghidat)
|
||||
yarn entity:add
|
||||
|
||||
# Generează un client Twenty tipat și tipurile de entități ale spațiului de lucru
|
||||
yarn app:generate
|
||||
yarn twenty entity:add
|
||||
|
||||
# Urmărește jurnalele funcțiilor aplicației tale
|
||||
yarn function:logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execută o funcție după nume
|
||||
yarn function:execute -n my-function -p '{"name": "test"}'
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execută funcția post-instalare
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Dezinstalează aplicația din spațiul de lucru curent
|
||||
yarn app:uninstall
|
||||
yarn twenty app:uninstall
|
||||
|
||||
# Afișează ajutorul pentru comenzi
|
||||
yarn help},{
|
||||
yarn twenty help
|
||||
```
|
||||
|
||||
Consultați și: paginile de referință CLI pentru [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) și [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
@@ -73,7 +73,7 @@ Când rulați `npx create-twenty-app@latest my-twenty-app`, generatorul:
|
||||
* Copiază o aplicație de bază minimală în `my-twenty-app/`
|
||||
* Adaugă o dependență locală `twenty-sdk` și configurația Yarn 4
|
||||
* Creează fișiere de configurare și scripturi conectate la CLI-ul `twenty`
|
||||
* Generează o configurație implicită a aplicației și un rol implicit pentru funcții
|
||||
* Generează o configurație implicită a aplicației, un rol implicit pentru funcții și o funcție post-instalare
|
||||
|
||||
O aplicație nou generată arată astfel:
|
||||
|
||||
@@ -89,20 +89,21 @@ my-twenty-app/
|
||||
eslint.config.mjs
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
public/ # Director pentru resurse publice (imagini, fonturi etc.)
|
||||
src/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── application-config.ts # Obligatoriu - configurația principală a aplicației
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
│ └── default-role.ts # Rol implicit pentru funcțiile logice
|
||||
├── logic-functions/
|
||||
│ └── hello-world.ts # Example logic function
|
||||
│ ├── hello-world.ts # Exemplu de funcție logică
|
||||
│ └── post-install.ts # Funcție logică post-instalare
|
||||
└── front-components/
|
||||
└── hello-world.tsx # Example front component
|
||||
└── hello-world.tsx # Exemplu de componentă de interfață
|
||||
```
|
||||
|
||||
Pe scurt:
|
||||
|
||||
* **package.json**: Declară numele aplicației, versiunea, motoarele (Node 24+, Yarn 4) și adaugă `twenty-sdk` plus scripturi precum `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall`, precum și comenzi de autentificare care deleagă către CLI-ul local `twenty`.
|
||||
* **package.json**: Declară numele aplicației, versiunea, motoarele (Node 24+, Yarn 4) și adaugă `twenty-sdk` plus un script `twenty` care deleagă către CLI-ul local `twenty`. Rulează `yarn twenty help` pentru a lista toate comenzile disponibile.
|
||||
* **.gitignore**: Ignoră artefacte comune precum `node_modules`, `.yarn`, `generated/` (client tipizat), `dist/`, `build/`, foldere de coverage, fișiere jurnal și fișiere `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Blochează și configurează lanțul de instrumente Yarn 4 folosit de proiect.
|
||||
* **.nvmrc**: Fixează versiunea Node.js așteptată de proiect.
|
||||
@@ -142,12 +143,12 @@ export default defineObject({
|
||||
|
||||
Comenzile ulterioare vor adăuga mai multe fișiere și foldere:
|
||||
|
||||
* `yarn app:generate` va crea un folder `generated/` (client Twenty tipizat + tipuri pentru spațiul de lucru).
|
||||
* `yarn entity:add` va adăuga fișiere de definire a entităților în `src/` pentru obiectele, funcțiile, componentele front-end sau rolurile personalizate.
|
||||
* `yarn twenty app:dev` va genera automat un client API tipizat în `node_modules/twenty-sdk/generated` (client Twenty tipizat + tipuri ale spațiului de lucru).
|
||||
* `yarn twenty entity:add` va adăuga fișiere de definire a entităților în `src/` pentru obiectele, funcțiile, componentele front-end sau rolurile personalizate.
|
||||
|
||||
## Autentificare
|
||||
|
||||
Prima dată când rulați `yarn auth:login`, vi se vor solicita:
|
||||
Prima dată când rulați `yarn twenty auth:login`, vi se vor solicita:
|
||||
|
||||
* URL-ul API (implicit http://localhost:3000 sau profilul spațiului de lucru curent)
|
||||
* Cheie API
|
||||
@@ -158,25 +159,25 @@ Acreditările dvs. sunt stocate per utilizator în `~/.twenty/config.json`. Pute
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn auth:login --workspace my-custom-workspace
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
|
||||
# List all configured workspaces
|
||||
yarn auth:list
|
||||
yarn twenty auth:list
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn auth:switch
|
||||
yarn twenty auth:switch
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn auth:switch production
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn auth:status
|
||||
yarn twenty auth:status
|
||||
```
|
||||
|
||||
După ce ați schimbat spațiul de lucru cu `auth:switch`, toate comenzile ulterioare vor folosi implicit acel spațiu de lucru. Îl puteți totuși suprascrie temporar cu `--workspace <name>`.
|
||||
După ce ați schimbat spațiul de lucru cu `yarn twenty auth:switch`, toate comenzile ulterioare vor folosi implicit acel spațiu de lucru. Îl puteți totuși suprascrie temporar cu `--workspace <name>`.
|
||||
|
||||
## Utilizați resursele SDK (tipuri și configurare)
|
||||
|
||||
@@ -276,10 +277,14 @@ Puncte cheie:
|
||||
* `universalIdentifier` trebuie să fie unic și stabil între implementări.
|
||||
* Fiecare câmp necesită un `name`, un `type`, un `label` și propriul `universalIdentifier` stabil.
|
||||
* Matricea `fields` este opțională — puteți defini obiecte fără câmpuri personalizate.
|
||||
* Puteți genera obiecte noi folosind `yarn entity:add`, care vă ghidează prin denumire, câmpuri și relații.
|
||||
* Puteți genera obiecte noi folosind `yarn twenty entity:add`, care vă ghidează prin denumire, câmpuri și relații.
|
||||
|
||||
<Note>
|
||||
**Câmpurile de bază sunt create automat.** Când definiți un obiect personalizat, Twenty adaugă automat câmpuri standard precum `name`, `createdAt`, `updatedAt`, `createdBy`, `position` și `deletedAt`. Nu trebuie să le definiți în tabloul `fields` — adăugați doar câmpurile personalizate proprii.
|
||||
**Câmpurile de bază sunt create automat.** Când definiți un obiect personalizat, Twenty adaugă automat câmpuri standard
|
||||
precum `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` și `deletedAt`.
|
||||
Nu trebuie să le definiți în tabloul `fields` — adăugați doar câmpurile personalizate proprii.
|
||||
Puteți suprascrie câmpurile implicite definind un câmp cu același nume în tabloul `fields`,
|
||||
dar acest lucru nu este recomandat.
|
||||
</Note>
|
||||
|
||||
### Configurația aplicației (application-config.ts)
|
||||
@@ -289,6 +294,7 @@ Fiecare aplicație are un singur fișier `application-config.ts` care descrie:
|
||||
* **Cine este aplicația**: identificatori, nume de afișare și descriere.
|
||||
* **Cum rulează funcțiile**: ce rol folosesc pentru permisiuni.
|
||||
* **(Opțional) variabile**: perechi cheie–valoare expuse funcțiilor ca variabile de mediu.
|
||||
* **(Opțional) funcție post-instalare**: o funcție logică care rulează după instalarea aplicației.
|
||||
|
||||
Folosiți `defineApplication()` pentru a defini configurația aplicației:
|
||||
|
||||
@@ -296,6 +302,7 @@ Folosiți `defineApplication()` pentru a defini configurația aplicației:
|
||||
// src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
@@ -311,6 +318,7 @@ export default defineApplication({
|
||||
},
|
||||
},
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -319,6 +327,7 @@ Notițe:
|
||||
* Câmpurile `universalIdentifier` sunt ID-uri deterministe pe care le dețineți; generați-le o singură dată și păstrați-le stabile între sincronizări.
|
||||
* `applicationVariables` devin variabile de mediu pentru funcțiile dvs. (de exemplu, `DEFAULT_RECIPIENT_NAME` este disponibil ca `process.env.DEFAULT_RECIPIENT_NAME`).
|
||||
* `defaultRoleUniversalIdentifier` trebuie să corespundă fișierului de rol (vedeți mai jos).
|
||||
* `postInstallLogicFunctionUniversalIdentifier` (opțional) indică o funcție logică care rulează automat după instalarea aplicației. Vezi [Funcții post-instalare](#post-install-functions).
|
||||
|
||||
#### Roluri și permisiuni
|
||||
|
||||
@@ -457,6 +466,55 @@ Notițe:
|
||||
* Matricea `triggers` este opțională. Funcțiile fără declanșatoare pot fi folosite ca funcții utilitare apelate de alte funcții.
|
||||
* Puteți combina mai multe tipuri de declanșatoare într-o singură funcție.
|
||||
|
||||
### Funcții post-instalare
|
||||
|
||||
O funcție post-instalare este o funcție logică care rulează automat după instalarea aplicației într-un spațiu de lucru. Aceasta este utilă pentru sarcini de configurare unice, cum ar fi popularea cu date implicite, crearea înregistrărilor inițiale sau configurarea setărilor spațiului de lucru.
|
||||
|
||||
When you scaffold a new app with `create-twenty-app`, a post-install function is generated for you at `src/logic-functions/post-install.ts`:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/post-install.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
|
||||
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
|
||||
|
||||
const handler = async (): Promise<void> => {
|
||||
console.log('Post install logic function executed successfully!');
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
name: 'post-install',
|
||||
description: 'Runs after installation to set up the application.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
The function is wired into your app by referencing its universal identifier in `application-config.ts`:
|
||||
|
||||
```typescript
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
// ...
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
You can also manually execute the post-install function at any time using the CLI:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty function:execute --postInstall
|
||||
```
|
||||
|
||||
Puncte cheie:
|
||||
|
||||
* Post-install functions are standard logic functions — they use `defineLogicFunction()` like any other function.
|
||||
* The `postInstallLogicFunctionUniversalIdentifier` field in `defineApplication()` is optional. If omitted, no function runs after installation.
|
||||
* The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `function:execute --postInstall`.
|
||||
|
||||
### Payload-ul declanșatorului de rută
|
||||
|
||||
<Warning>
|
||||
@@ -551,9 +609,74 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Puteți crea funcții noi în două moduri:
|
||||
|
||||
* **Generat**: Rulați `yarn entity:add` și alegeți opțiunea de a adăuga o funcție de logică nouă. Aceasta generează un fișier inițial cu un handler și o configurație.
|
||||
* **Generat**: Rulați `yarn twenty entity:add` și alegeți opțiunea de a adăuga o funcție logică nouă. Aceasta generează un fișier inițial cu un handler și o configurație.
|
||||
* **Manual**: Creați un fișier nou `*.logic-function.ts` și folosiți `defineLogicFunction()`, urmând același model.
|
||||
|
||||
### Marcarea unei funcții logice drept instrument
|
||||
|
||||
Funcțiile logice pot fi expuse ca **instrumente** pentru agenți de IA și fluxuri de lucru. Când o funcție este marcată ca instrument, poate fi descoperită de funcționalitățile de IA ale Twenty și poate fi selectată ca pas în automatizări ale fluxurilor de lucru.
|
||||
|
||||
Pentru a marca o funcție logică drept instrument, setați `isTool: true` și furnizați un `toolInputSchema` care descrie parametrii de intrare așteptați folosind [JSON Schema](https://json-schema.org/):
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/enrich-company.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import Twenty from '~/generated';
|
||||
|
||||
const handler = async (params: { companyName: string; domain?: string }) => {
|
||||
const client = new Twenty();
|
||||
|
||||
const result = await client.mutation({
|
||||
createTask: {
|
||||
__args: {
|
||||
data: {
|
||||
title: `Enrich data for ${params.companyName}`,
|
||||
body: `Domain: ${params.domain ?? 'unknown'}`,
|
||||
},
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
return { taskId: result.createTask.id };
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
|
||||
name: 'enrich-company',
|
||||
description: 'Enrich a company record with external data',
|
||||
timeoutSeconds: 10,
|
||||
handler,
|
||||
isTool: true,
|
||||
toolInputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
companyName: {
|
||||
type: 'string',
|
||||
description: 'The name of the company to enrich',
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
description: 'The company website domain (optional)',
|
||||
},
|
||||
},
|
||||
required: ['companyName'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Puncte cheie:
|
||||
|
||||
* **`isTool`** (`boolean`, implicit: `false`): Când este setat la `true`, funcția este înregistrată ca instrument și devine disponibilă pentru agenții AI și automatizările de fluxuri de lucru.
|
||||
* **`toolInputSchema`** (`object`, opțional): Un obiect JSON Schema care descrie parametrii pe care îi acceptă funcția dvs. Agenții AI folosesc această schemă pentru a înțelege ce intrări așteaptă instrumentul și pentru a valida apelurile. Dacă este omisă, schema are implicit valoarea `{ type: 'object', properties: {} }` (fără parametri).
|
||||
* Funcțiile cu `isTool: false` (sau nedefinit) **nu** sunt expuse ca instrumente. Pot totuși fi executate direct sau apelate de alte funcții, dar nu vor apărea în descoperirea instrumentelor.
|
||||
* **Denumierea instrumentelor**: Când este expusă ca instrument, denumirea funcției este normalizată automat la `logic_function_<name>` (convertită la litere mici, iar caracterele non-alfanumerice sunt înlocuite cu caractere de subliniere). De exemplu, `enrich-company` devine `logic_function_enrich_company`.
|
||||
* Puteți combina `isTool` cu declanșatoare — o funcție poate fi atât un instrument (apelabilă de agenții AI), cât și declanșată de evenimente (cron, evenimente de bază de date, rute) în același timp.
|
||||
|
||||
<Note>
|
||||
**Scrieți o `description` bună.** Agenții AI se bazează pe câmpul `description` al funcției pentru a decide când să folosească instrumentul. Fiți specifici cu privire la ceea ce face instrumentul și când ar trebui apelat.
|
||||
</Note>
|
||||
|
||||
### Componente Front
|
||||
|
||||
Componentele Front vă permit să construiți componente React personalizate care sunt randate în interfața Twenty. Utilizați `defineFrontComponent()` pentru a defini componente cu validare încorporată:
|
||||
@@ -584,16 +707,16 @@ Puncte cheie:
|
||||
* Componentele Front sunt componente React care sunt randate în contexte izolate în cadrul Twenty.
|
||||
* Folosiți sufixul de fișier `*.front-component.tsx` pentru detectare automată.
|
||||
* Câmpul `component` face referire la componenta React.
|
||||
* Componentele sunt construite și sincronizate automat în timpul `yarn app:dev`.
|
||||
* Componentele sunt construite și sincronizate automat în timpul `yarn twenty app:dev`.
|
||||
|
||||
Puteți crea componente Front noi în două moduri:
|
||||
|
||||
* **Generat**: Rulați `yarn entity:add` și alegeți opțiunea de a adăuga o componentă Front nouă.
|
||||
* **Generat**: Rulați `yarn twenty entity:add` și alegeți opțiunea de a adăuga o componentă frontend nouă.
|
||||
* **Manual**: Creați un fișier nou `*.front-component.tsx` și folosiți `defineFrontComponent()`.
|
||||
|
||||
### Client tipizat generat
|
||||
|
||||
Rulați yarn app:generate pentru a crea un client tipizat local în generated/, pe baza schemei spațiului de lucru. Folosiți-l în funcțiile dvs.:
|
||||
Clientul tipizat este generat automat de `yarn twenty app:dev` și stocat în `node_modules/twenty-sdk/generated`, pe baza schemei spațiului tău de lucru. Folosiți-l în funcțiile dvs.:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -602,7 +725,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
Clientul este regenerat de `yarn app:generate`. Rulați din nou după ce vă modificați obiectele sau când vă integrați într-un spațiu de lucru nou.
|
||||
Clientul este regenerat automat de `yarn twenty app:dev` ori de câte ori obiectele sau câmpurile tale se schimbă.
|
||||
|
||||
#### Acreditări la runtime în funcțiile de logică
|
||||
|
||||
@@ -623,40 +746,29 @@ Explorați un exemplu minim, cap la cap, care demonstrează obiecte, funcții de
|
||||
|
||||
## Configurare manuală (fără generator)
|
||||
|
||||
Deși recomandăm utilizarea `create-twenty-app` pentru cea mai bună experiență de început, puteți configura și un proiect manual. Nu instalați CLI-ul global. În schimb, adăugați `twenty-sdk` ca dependență locală și conectați scripturile în package.json-ul dvs.:
|
||||
Deși recomandăm utilizarea `create-twenty-app` pentru cea mai bună experiență de început, puteți configura și un proiect manual. Nu instalați CLI-ul global. În schimb, adăugați `twenty-sdk` ca dependență locală și conectați un singur script în package.json-ul dvs.:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
```
|
||||
|
||||
Apoi adăugați scripturi ca acestea:
|
||||
Apoi adăugați un script `twenty`:
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
"auth:login": "twenty auth:login",
|
||||
"auth:logout": "twenty auth:logout",
|
||||
"auth:status": "twenty auth:status",
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
"function:execute": "twenty function:execute",
|
||||
"help": "twenty help"
|
||||
"twenty": "twenty"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Acum puteți rula aceleași comenzi prin Yarn, de ex. `yarn app:dev`, `yarn app:generate`, etc.
|
||||
Acum poți rula toate comenzile prin `yarn twenty <command>`, de ex. `yarn twenty app:dev`, `yarn twenty help`, etc.
|
||||
|
||||
## Depanare
|
||||
|
||||
* Erori de autentificare: rulați `yarn auth:login` și asigurați-vă că cheia API are permisiunile necesare.
|
||||
* Erori de autentificare: rulați `yarn twenty auth:login` și asigurați-vă că cheia API are permisiunile necesare.
|
||||
* Nu se poate conecta la server: verificați URL-ul API și că serverul Twenty este accesibil.
|
||||
* Tipuri sau client lipsă/învechite: rulați `yarn app:generate`.
|
||||
* Modul dev nu sincronizează: asigurați-vă că `yarn app:dev` rulează și că modificările nu sunt ignorate de mediul dvs.
|
||||
* Types or client missing/outdated: restart `yarn twenty app:dev` — it auto-generates the typed client.
|
||||
* Modul dev nu sincronizează: asigurați-vă că `yarn twenty app:dev` rulează și că modificările nu sunt ignorate de mediul dvs.
|
||||
|
||||
Canal de ajutor pe Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -27,41 +27,41 @@ description: Создавайте и управляйте настройками
|
||||
Создайте новое приложение с помощью официального генератора, затем выполните аутентификацию и начните разработку:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Scaffold a new app
|
||||
# Создать каркас нового приложения
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
cd my-twenty-app
|
||||
|
||||
# If you don't use yarn@4
|
||||
# Если вы не используете yarn@4
|
||||
corepack enable
|
||||
yarn install
|
||||
|
||||
# Authenticate using your API key (you'll be prompted)
|
||||
yarn auth:login
|
||||
# Аутентифицироваться с помощью вашего API-ключа (вам будет предложено)
|
||||
yarn twenty auth:login
|
||||
|
||||
# Start dev mode: automatically syncs local changes to your workspace
|
||||
yarn app:dev
|
||||
# Запустить режим разработки: автоматически синхронизирует локальные изменения с вашим рабочим пространством
|
||||
yarn twenty app:dev
|
||||
```
|
||||
|
||||
Отсюда вы можете:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Добавить новую сущность в ваше приложение (с мастером)
|
||||
yarn entity:add
|
||||
# Add a new entity to your application (guided)
|
||||
yarn twenty entity:add
|
||||
|
||||
# Сгенерировать типизированный клиент Twenty и типы сущностей рабочего пространства
|
||||
yarn app:generate
|
||||
# Watch your application's function logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Просматривать логи функций вашего приложения
|
||||
yarn function:logs
|
||||
# Execute a function by name
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Выполнить функцию по имени
|
||||
yarn function:execute -n my-function -p '{"name": "test"}'
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Удалить приложение из текущего рабочего пространства
|
||||
yarn app:uninstall
|
||||
# Uninstall the application from the current workspace
|
||||
yarn twenty app:uninstall
|
||||
|
||||
# Показать справку по командам
|
||||
yarn help
|
||||
# Display commands' help
|
||||
yarn twenty help
|
||||
```
|
||||
|
||||
Смотрите также: страницы справки CLI для [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) и [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
|
||||
@@ -73,7 +73,7 @@ yarn help
|
||||
* Копирует минимальное базовое приложение в `my-twenty-app/`
|
||||
* Добавляет локальную зависимость `twenty-sdk` и конфигурацию Yarn 4
|
||||
* Создаёт файлы конфигурации и скрипты, подключённые к CLI `twenty`
|
||||
* Генерирует конфигурацию приложения по умолчанию и роль функции по умолчанию
|
||||
* Generates a default application config, a default function role, and a post-install function
|
||||
|
||||
Свежесгенерированное приложение выглядит так:
|
||||
|
||||
@@ -89,20 +89,21 @@ my-twenty-app/
|
||||
eslint.config.mjs
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # Папка общедоступных ресурсов (изображения, шрифты и т. п.)
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Обязательный — основная конфигурация приложения
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── roles/
|
||||
│ └── default-role.ts # Роль по умолчанию для логических функций
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── logic-functions/
|
||||
│ └── hello-world.ts # Пример логической функции
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
└── front-components/
|
||||
└── hello-world.tsx # Пример фронтенд-компонента
|
||||
└── hello-world.tsx # Example front component
|
||||
```
|
||||
|
||||
В общих чертах:
|
||||
|
||||
* **package.json**: Объявляет имя приложения, версию, движки (Node 24+, Yarn 4) и добавляет `twenty-sdk`, а также скрипты вроде `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` и команды аутентификации, которые делегируют выполнение локальному CLI `twenty`.
|
||||
* **package.json**: Объявляет имя приложения, версию, движки (Node 24+, Yarn 4) и добавляет `twenty-sdk`, а также скрипт `twenty`, который делегирует выполнение локальному CLI `twenty`. Выполните `yarn twenty help`, чтобы вывести список всех доступных команд.
|
||||
* **.gitignore**: Игнорирует распространённые артефакты, такие как `node_modules`, `.yarn`, `generated/` (типизированный клиент), `dist/`, `build/`, каталоги coverage, файлы журналов и файлы `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Фиксируют и настраивают используемый в проекте инструментарий Yarn 4.
|
||||
* **.nvmrc**: Фиксирует версию Node.js, ожидаемую проектом.
|
||||
@@ -142,12 +143,12 @@ export default defineObject({
|
||||
|
||||
Позднее команды добавят больше файлов и папок:
|
||||
|
||||
* `yarn app:generate` создаст папку `generated/` (типизированный клиент Twenty + типы рабочего пространства).
|
||||
* `yarn entity:add` добавит файлы определений сущностей в `src/` для ваших пользовательских объектов, функций, фронтенд-компонентов или ролей.
|
||||
* `yarn twenty app:dev` автоматически сгенерирует типизированный клиент API в `node_modules/twenty-sdk/generated` (типизированный клиент Twenty + типы рабочего пространства).
|
||||
* `yarn twenty entity:add` добавит файлы определений сущностей в `src/` для ваших пользовательских объектов, функций, фронтенд-компонентов или ролей.
|
||||
|
||||
## Аутентификация
|
||||
|
||||
При первом запуске `yarn auth:login` вам будет предложено указать:
|
||||
При первом запуске `yarn twenty auth:login` вам будет предложено указать:
|
||||
|
||||
* URL API (по умолчанию http://localhost:3000 или текущий профиль рабочего пространства)
|
||||
* Ключ API
|
||||
@@ -158,25 +159,25 @@ export default defineObject({
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Войти в интерактивном режиме (рекомендуется)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Войти в профиль конкретного рабочего пространства
|
||||
yarn auth:login --workspace my-custom-workspace
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
|
||||
# Показать список всех настроенных рабочих пространств
|
||||
yarn auth:list
|
||||
yarn twenty auth:list
|
||||
|
||||
# Переключить рабочее пространство по умолчанию (в интерактивном режиме)
|
||||
yarn auth:switch
|
||||
yarn twenty auth:switch
|
||||
|
||||
# Переключиться на определённое рабочее пространство
|
||||
yarn auth:switch production
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Проверить текущий статус аутентификации
|
||||
yarn auth:status
|
||||
yarn twenty auth:status
|
||||
```
|
||||
|
||||
После переключения рабочего пространства с помощью `auth:switch` все последующие команды по умолчанию будут использовать это рабочее пространство. Вы по-прежнему можете временно переопределить это с помощью `--workspace <name>`.
|
||||
После переключения рабочего пространства с помощью `yarn twenty auth:switch` все последующие команды по умолчанию будут использовать это рабочее пространство. Вы по-прежнему можете временно переопределить это с помощью `--workspace <name>`.
|
||||
|
||||
## Используйте ресурсы SDK (типы и конфигурация)
|
||||
|
||||
@@ -276,10 +277,14 @@ export default defineObject({
|
||||
* `universalIdentifier` должен быть уникальным и стабильным между развёртываниями.
|
||||
* Каждому полю требуются `name`, `type`, `label` и собственный стабильный `universalIdentifier`.
|
||||
* Массив `fields` необязателен — вы можете определять объекты без пользовательских полей.
|
||||
* Вы можете сгенерировать новые объекты с помощью `yarn entity:add`, который проведёт вас через выбор именования, полей и связей.
|
||||
* Вы можете сгенерировать новые объекты с помощью `yarn twenty entity:add`, который проведёт вас через настройку имени, полей и связей.
|
||||
|
||||
<Note>
|
||||
**Базовые поля создаются автоматически.** Когда вы определяете пользовательский объект, Twenty автоматически добавляет стандартные поля, такие как `name`, `createdAt`, `updatedAt`, `createdBy`, `position` и `deletedAt`. Вам не нужно определять их в массиве `fields` — добавляйте только свои пользовательские поля.
|
||||
**Базовые поля создаются автоматически.** Когда вы определяете пользовательский объект, Twenty автоматически добавляет стандартные поля,
|
||||
такие как `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` и `deletedAt`.
|
||||
Вам не нужно определять их в массиве `fields` — добавляйте только свои пользовательские поля.
|
||||
Вы можете переопределить поля по умолчанию, определив поле с тем же именем в массиве `fields`,
|
||||
но это не рекомендуется.
|
||||
</Note>
|
||||
|
||||
### Конфигурация приложения (application-config.ts)
|
||||
@@ -289,6 +294,7 @@ export default defineObject({
|
||||
* **Что это за приложение**: идентификаторы, отображаемое имя и описание.
|
||||
* **Как запускаются его функции**: какую роль они используют для прав доступа.
|
||||
* **(Необязательно) переменные**: пары ключ-значение, предоставляемые вашим функциям как переменные окружения.
|
||||
* **(Optional) post-install function**: a logic function that runs after the app is installed.
|
||||
|
||||
Используйте `defineApplication()` для определения конфигурации вашего приложения:
|
||||
|
||||
@@ -296,6 +302,7 @@ export default defineObject({
|
||||
// src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
@@ -311,6 +318,7 @@ export default defineApplication({
|
||||
},
|
||||
},
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -319,6 +327,7 @@ export default defineApplication({
|
||||
* `universalIdentifier` — это детерминированные идентификаторы, которыми вы управляете; сгенерируйте их один раз и сохраняйте стабильными между синхронизациями.
|
||||
* `applicationVariables` становятся переменными окружения для ваших функций (например, `DEFAULT_RECIPIENT_NAME` доступна как `process.env.DEFAULT_RECIPIENT_NAME`).
|
||||
* `defaultRoleUniversalIdentifier` должен соответствовать файлу роли (см. ниже).
|
||||
* `postInstallLogicFunctionUniversalIdentifier` (optional) points to a logic function that runs automatically after the app is installed. See [Post-install functions](#post-install-functions).
|
||||
|
||||
#### Роли и разрешения
|
||||
|
||||
@@ -457,6 +466,55 @@ export default defineLogicFunction({
|
||||
* Массив `triggers` необязателен. Функции без триггеров можно использовать как вспомогательные, вызываемые другими функциями.
|
||||
* Вы можете сочетать несколько типов триггеров в одной функции.
|
||||
|
||||
### Post-install functions
|
||||
|
||||
A post-install function is a logic function that runs automatically after your app is installed on a workspace. This is useful for one-time setup tasks such as seeding default data, creating initial records, or configuring workspace settings.
|
||||
|
||||
When you scaffold a new app with `create-twenty-app`, a post-install function is generated for you at `src/logic-functions/post-install.ts`:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/post-install.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
|
||||
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
|
||||
|
||||
const handler = async (): Promise<void> => {
|
||||
console.log('Post install logic function executed successfully!');
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
name: 'post-install',
|
||||
description: 'Runs after installation to set up the application.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
The function is wired into your app by referencing its universal identifier in `application-config.ts`:
|
||||
|
||||
```typescript
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
// ...
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
You can also manually execute the post-install function at any time using the CLI:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty function:execute --postInstall
|
||||
```
|
||||
|
||||
Основные моменты:
|
||||
|
||||
* Post-install functions are standard logic functions — they use `defineLogicFunction()` like any other function.
|
||||
* The `postInstallLogicFunctionUniversalIdentifier` field in `defineApplication()` is optional. If omitted, no function runs after installation.
|
||||
* The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `function:execute --postInstall`.
|
||||
|
||||
### Полезная нагрузка триггера маршрута
|
||||
|
||||
<Warning>
|
||||
@@ -551,9 +609,74 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Вы можете создать новые функции двумя способами:
|
||||
|
||||
* **Сгенерировано**: Запустите `yarn entity:add` и выберите опцию добавления новой логической функции. Это создаёт стартовый файл с обработчиком и конфигурацией.
|
||||
* **Сгенерировано**: Запустите `yarn twenty entity:add` и выберите опцию добавления новой функции логики. Это создаёт стартовый файл с обработчиком и конфигурацией.
|
||||
* **Вручную**: Создайте новый файл `*.logic-function.ts` и используйте `defineLogicFunction()`, следуя тому же шаблону.
|
||||
|
||||
### Пометка логической функции как инструмента
|
||||
|
||||
Логические функции можно предоставлять как **инструменты** для ИИ-агентов и рабочих процессов. Когда функция помечена как инструмент, она становится доступной для ИИ Twenty и может быть выбрана в качестве шага в автоматизациях рабочих процессов.
|
||||
|
||||
Чтобы пометить логическую функцию как инструмент, установите `isTool: true` и укажите `toolInputSchema` для описания ожидаемых входных параметров с помощью [схемы JSON](https://json-schema.org/):
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/enrich-company.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import Twenty from '~/generated';
|
||||
|
||||
const handler = async (params: { companyName: string; domain?: string }) => {
|
||||
const client = new Twenty();
|
||||
|
||||
const result = await client.mutation({
|
||||
createTask: {
|
||||
__args: {
|
||||
data: {
|
||||
title: `Enrich data for ${params.companyName}`,
|
||||
body: `Domain: ${params.domain ?? 'unknown'}`,
|
||||
},
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
return { taskId: result.createTask.id };
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
|
||||
name: 'enrich-company',
|
||||
description: 'Enrich a company record with external data',
|
||||
timeoutSeconds: 10,
|
||||
handler,
|
||||
isTool: true,
|
||||
toolInputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
companyName: {
|
||||
type: 'string',
|
||||
description: 'The name of the company to enrich',
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
description: 'The company website domain (optional)',
|
||||
},
|
||||
},
|
||||
required: ['companyName'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Основные моменты:
|
||||
|
||||
* **`isTool`** (`boolean`, по умолчанию: `false`): Если значение равно `true`, функция регистрируется как инструмент и становится доступной агентам ИИ и автоматизациям рабочих процессов.
|
||||
* **`toolInputSchema`** (`object`, необязательно): Объект JSON Schema, который описывает параметры, которые принимает ваша функция. Агенты ИИ используют эту схему, чтобы понять, какие входные данные ожидает инструмент, и проверять корректность вызовов. Если опущено, по умолчанию используется схема `{ type: 'object', properties: {} }` (без параметров).
|
||||
* Функции с `isTool: false` (или без указания) **не** выставляются как инструменты. Их по-прежнему можно выполнять напрямую или вызывать из других функций, но они не будут отображаться при обнаружении инструментов.
|
||||
* **Именование инструмента**: При публикации как инструмента имя функции автоматически нормализуется до `logic_function_<name>` (в нижнем регистре, небуквенно-цифровые символы заменяются на подчёркивания). Например, `enrich-company` становится `logic_function_enrich_company`.
|
||||
* Вы можете комбинировать `isTool` с триггерами — функция может одновременно быть инструментом (вызываемым агентами ИИ) и запускаться событиями (cron, события базы данных, маршруты).
|
||||
|
||||
<Note>
|
||||
**Напишите хорошее описание в поле `description`.** Агенты ИИ опираются на поле `description` функции, чтобы решить, когда использовать инструмент. Чётко опишите, что делает инструмент и когда его следует вызывать.
|
||||
</Note>
|
||||
|
||||
### Фронт-компоненты
|
||||
|
||||
Фронт-компоненты позволяют создавать пользовательские компоненты React, которые рендерятся внутри интерфейса Twenty. Используйте `defineFrontComponent()` для определения компонентов со встроенной валидацией:
|
||||
@@ -584,16 +707,16 @@ export default defineFrontComponent({
|
||||
* Фронт-компоненты — это компоненты React, которые рендерятся в изолированных контекстах внутри Twenty.
|
||||
* Используйте суффикс файла `*.front-component.tsx` для автоматического обнаружения.
|
||||
* Поле `component` ссылается на ваш компонент React.
|
||||
* Компоненты автоматически собираются и синхронизируются во время `yarn app:dev`.
|
||||
* Компоненты автоматически собираются и синхронизируются во время `yarn twenty app:dev`.
|
||||
|
||||
Вы можете создать новые фронт-компоненты двумя способами:
|
||||
|
||||
* **Сгенерировано**: Запустите `yarn entity:add` и выберите опцию добавления нового фронт-компонента.
|
||||
* **Сгенерировано**: Запустите `yarn twenty entity:add` и выберите опцию добавления нового фронтенд-компонента.
|
||||
* **Вручную**: Создайте новый файл `*.front-component.tsx` и используйте `defineFrontComponent()`.
|
||||
|
||||
### Сгенерированный типизированный клиент
|
||||
|
||||
Запустите yarn app:generate, чтобы создать локальный типизированный клиент в generated/ на основе схемы вашего рабочего пространства. Используйте его в своих функциях:
|
||||
Типизированный клиент автоматически генерируется с помощью `yarn twenty app:dev` и сохраняется в `node_modules/twenty-sdk/generated` на основе схемы вашего рабочего пространства. Используйте его в своих функциях:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -602,7 +725,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
Клиент повторно генерируется командой `yarn app:generate`. Запускайте повторно после изменения ваших объектов или при подключении к новому рабочему пространству.
|
||||
Клиент автоматически перегенерируется с помощью `yarn twenty app:dev` при изменении ваших объектов или полей.
|
||||
|
||||
#### Учётные данные времени выполнения в логических функциях
|
||||
|
||||
@@ -623,40 +746,29 @@ const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
|
||||
## Ручная настройка (без генератора)
|
||||
|
||||
Хотя мы рекомендуем использовать `create-twenty-app` для наилучшего старта, вы также можете настроить проект вручную. Не устанавливайте CLI глобально. Вместо этого добавьте `twenty-sdk` как локальную зависимость и настройте скрипты в вашем package.json:
|
||||
Хотя мы рекомендуем использовать `create-twenty-app` для наилучшего старта, вы также можете настроить проект вручную. Не устанавливайте CLI глобально. Вместо этого добавьте `twenty-sdk` как локальную зависимость и настройте один скрипт в вашем package.json:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
```
|
||||
|
||||
Затем добавьте скрипты, подобные этим:
|
||||
Затем добавьте скрипт `twenty`:
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
"auth:login": "twenty auth:login",
|
||||
"auth:logout": "twenty auth:logout",
|
||||
"auth:status": "twenty auth:status",
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
"function:execute": "twenty function:execute",
|
||||
"help": "twenty help"
|
||||
"twenty": "twenty"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Теперь вы можете запускать те же команды через Yarn, например, `yarn app:dev`, `yarn app:generate` и т. д.
|
||||
Теперь вы можете запускать все команды через `yarn twenty <command>`, например, `yarn twenty app:dev`, `yarn twenty help` и т. д.
|
||||
|
||||
## Устранение неполадок
|
||||
|
||||
* Ошибки аутентификации: выполните `yarn auth:login` и убедитесь, что у вашего ключа API есть необходимые права.
|
||||
* Ошибки аутентификации: выполните `yarn twenty auth:login` и убедитесь, что у вашего ключа API есть необходимые права.
|
||||
* Не удаётся подключиться к серверу: проверьте URL API и доступность сервера Twenty.
|
||||
* Типы или клиент отсутствуют/устарели: выполните `yarn app:generate`.
|
||||
* Режим разработки не синхронизируется: убедитесь, что запущен `yarn app:dev`, и что ваша среда не игнорирует изменения.
|
||||
* Types or client missing/outdated: restart `yarn twenty app:dev` — it auto-generates the typed client.
|
||||
* Режим разработки не синхронизируется: убедитесь, что запущен `yarn twenty app:dev`, и что ваша среда не игнорирует изменения.
|
||||
|
||||
Канал помощи в Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -36,32 +36,32 @@ corepack enable
|
||||
yarn install
|
||||
|
||||
# Authenticate using your API key (you'll be prompted)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Start dev mode: automatically syncs local changes to your workspace
|
||||
yarn app:dev
|
||||
yarn twenty app:dev
|
||||
```
|
||||
|
||||
Buradan şunları yapabilirsiniz:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn entity:add
|
||||
|
||||
# Generate a typed Twenty client and workspace entity types
|
||||
yarn app:generate
|
||||
yarn twenty entity:add
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn function:logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function by name
|
||||
yarn function:execute -n my-function -p '{"name": "test"}'
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn app:uninstall
|
||||
yarn twenty app:uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn help
|
||||
yarn twenty help
|
||||
```
|
||||
|
||||
Ayrıca bkz.: [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) ve [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk) için CLI başvuru sayfaları.
|
||||
@@ -73,7 +73,7 @@ Ayrıca bkz.: [create-twenty-app](https://www.npmjs.com/package/create-twenty-ap
|
||||
* Minimal bir temel uygulamayı `my-twenty-app/` içine kopyalar
|
||||
* Yerel bir `twenty-sdk` bağımlılığı ve Yarn 4 yapılandırması ekler
|
||||
* `twenty` CLI ile bağlantılı yapılandırma dosyaları ve betikler oluşturur
|
||||
* Varsayılan bir uygulama yapılandırması ve varsayılan bir fonksiyon rolü üretir
|
||||
* Generates a default application config, a default function role, and a post-install function
|
||||
|
||||
Yeni şablondan oluşturulan bir uygulama şöyle görünür:
|
||||
|
||||
@@ -89,20 +89,21 @@ my-twenty-app/
|
||||
eslint.config.mjs
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # Genel varlıklar klasörü (görseller, yazı tipleri vb.)
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Gerekli - ana uygulama yapılandırması
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── roles/
|
||||
│ └── default-role.ts # Mantık işlevleri için varsayılan rol
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── logic-functions/
|
||||
│ └── hello-world.ts # Örnek mantık işlevi
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
└── front-components/
|
||||
└── hello-world.tsx # Örnek ön uç bileşeni
|
||||
└── hello-world.tsx # Example front component
|
||||
```
|
||||
|
||||
Genel hatlarıyla:
|
||||
|
||||
* **package.json**: Uygulama adını, sürümünü, motorları (Node 24+, Yarn 4) bildirir ve `twenty-sdk` ile `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` gibi betikleri ve yerel `twenty` CLI’sine yetki devreden kimlik doğrulama komutlarını ekler.
|
||||
* **package.json**: Uygulama adını, sürümünü, motorları (Node 24+, Yarn 4) bildirir ve `twenty-sdk` ile yerel `twenty` CLI'sine yetki devreden bir `twenty` betiği ekler. Tüm mevcut komutları listelemek için `yarn twenty help` komutunu çalıştırın.
|
||||
* **.gitignore**: `node_modules`, `.yarn`, `generated/` (türlendirilmiş istemci), `dist/`, `build/`, kapsam klasörleri, günlük dosyaları ve `.env*` dosyaları gibi yaygın artifaktları yok sayar.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Proje tarafından kullanılan Yarn 4 araç zincirini kilitler ve yapılandırır.
|
||||
* **.nvmrc**: Projenin beklediği Node.js sürümünü sabitler.
|
||||
@@ -142,12 +143,12 @@ export default defineObject({
|
||||
|
||||
İlerideki komutlar daha fazla dosya ve klasör ekleyecektir:
|
||||
|
||||
* `yarn app:generate`, `generated/` klasörünü oluşturur (türlendirilmiş Twenty istemcisi + çalışma alanı türleri).
|
||||
* `yarn entity:add`, özel nesneleriniz, fonksiyonlarınız, ön bileşenleriniz veya rolleriniz için `src/` altında varlık tanım dosyaları ekler.
|
||||
* `yarn twenty app:dev`, `node_modules/twenty-sdk/generated` içinde tipli bir API istemcisini otomatik olarak oluşturur (tipli Twenty istemcisi + çalışma alanı türleri).
|
||||
* `yarn twenty entity:add`, özel nesneleriniz, fonksiyonlarınız, ön bileşenleriniz veya rolleriniz için `src/` altında varlık tanım dosyaları ekler.
|
||||
|
||||
## Kimlik Doğrulama
|
||||
|
||||
`yarn auth:login` komutunu ilk kez çalıştırdığınızda, sizden şunlar istenir:
|
||||
`yarn twenty auth:login` komutunu ilk kez çalıştırdığınızda, sizden şunlar istenir:
|
||||
|
||||
* API URL’si (varsayılan: http://localhost:3000 veya mevcut çalışma alanı profiliniz)
|
||||
* API anahtarı
|
||||
@@ -157,26 +158,26 @@ Kimlik bilgileriniz kullanıcı başına `~/.twenty/config.json` içinde saklan
|
||||
### Managing workspaces
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn auth:login
|
||||
# Etkileşimli giriş yapın (önerilir)
|
||||
yarn twenty auth:login
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn auth:login --workspace my-custom-workspace
|
||||
# Belirli bir çalışma alanı profiline giriş yapın
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
|
||||
# List all configured workspaces
|
||||
yarn auth:list
|
||||
# Yapılandırılmış tüm çalışma alanlarını listeleyin
|
||||
yarn twenty auth:list
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn auth:switch
|
||||
# Varsayılan çalışma alanını değiştirin (etkileşimli)
|
||||
yarn twenty auth:switch
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn auth:switch production
|
||||
# Belirli bir çalışma alanına geçin
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn auth:status
|
||||
# Mevcut kimlik doğrulama durumunu kontrol edin
|
||||
yarn twenty auth:status
|
||||
```
|
||||
|
||||
Once you've switched workspaces with `auth:switch`, all subsequent commands will use that workspace by default. You can still override it temporarily with `--workspace <name>`.
|
||||
`yarn twenty auth:switch` ile çalışma alanlarını değiştirdikten sonra, sonraki tüm komutlar varsayılan olarak o çalışma alanını kullanacaktır. You can still override it temporarily with `--workspace <name>`.
|
||||
|
||||
## SDK kaynaklarını kullanın (türler ve yapılandırma)
|
||||
|
||||
@@ -276,10 +277,14 @@ export default defineObject({
|
||||
* `universalIdentifier` dağıtımlar arasında benzersiz ve kararlı olmalıdır.
|
||||
* Her alan bir `name`, `type`, `label` ve kendi kararlı `universalIdentifier` değerini gerektirir.
|
||||
* `fields` dizisi isteğe bağlıdır — özel alanlar olmadan da nesneler tanımlayabilirsiniz.
|
||||
* `yarn entity:add` kullanarak, adlandırma, alanlar ve ilişkiler konusunda sizi yönlendirerek yeni nesneler oluşturabilirsiniz.
|
||||
* `yarn twenty entity:add` kullanarak, adlandırma, alanlar ve ilişkiler konusunda sizi yönlendirerek yeni nesneler oluşturabilirsiniz.
|
||||
|
||||
<Note>
|
||||
**Temel alanlar otomatik olarak oluşturulur.** Özel bir nesne tanımladığınızda Twenty, `name`, `createdAt`, `updatedAt`, `createdBy`, `position` ve `deletedAt` gibi standart alanları otomatik olarak ekler. Bunları `fields` dizinizde tanımlamanız gerekmez — yalnızca özel alanlarınızı ekleyin.
|
||||
**Temel alanlar otomatik olarak oluşturulur.** Özel bir nesne tanımladığınızda Twenty, standart alanları otomatik olarak ekler
|
||||
örneğin `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` ve `deletedAt`.
|
||||
Bunları `fields` dizinizde tanımlamanız gerekmez — yalnızca özel alanlarınızı ekleyin.
|
||||
`fields` dizinizde aynı ada sahip bir alan tanımlayarak varsayılan alanları geçersiz kılabilirsiniz,
|
||||
ancak bu önerilmez.
|
||||
</Note>
|
||||
|
||||
### Uygulama yapılandırması (application-config.ts)
|
||||
@@ -289,6 +294,7 @@ Her uygulamanın aşağıdakileri açıklayan tek bir `application-config.ts` do
|
||||
* **Uygulamanın kim olduğu**: tanımlayıcılar, görünen ad ve açıklama.
|
||||
* **Fonksiyonlarının nasıl çalıştığı**: izinler için hangi rolü kullandıkları.
|
||||
* **(İsteğe bağlı) değişkenler**: fonksiyonlarınıza ortam değişkenleri olarak sunulan anahtar–değer çiftleri.
|
||||
* **(Optional) post-install function**: a logic function that runs after the app is installed.
|
||||
|
||||
Uygulama yapılandırmanızı tanımlamak için `defineApplication()` kullanın:
|
||||
|
||||
@@ -296,6 +302,7 @@ Uygulama yapılandırmanızı tanımlamak için `defineApplication()` kullanın:
|
||||
// src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
@@ -311,6 +318,7 @@ export default defineApplication({
|
||||
},
|
||||
},
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -319,6 +327,7 @@ Notlar:
|
||||
* `universalIdentifier` alanları size ait belirleyici kimliklerdir; bunları bir kez oluşturun ve eşitlemeler boyunca kararlı tutun.
|
||||
* `applicationVariables`, fonksiyonlarınız için ortam değişkenlerine dönüşür (örneğin, `DEFAULT_RECIPIENT_NAME` değeri `process.env.DEFAULT_RECIPIENT_NAME` olarak kullanılabilir).
|
||||
* `defaultRoleUniversalIdentifier`, rol dosyasıyla eşleşmelidir (aşağıya bakın).
|
||||
* `postInstallLogicFunctionUniversalIdentifier` (optional) points to a logic function that runs automatically after the app is installed. See [Post-install functions](#post-install-functions).
|
||||
|
||||
#### Roller ve izinler
|
||||
|
||||
@@ -457,6 +466,55 @@ Notlar:
|
||||
* `triggers` dizisi isteğe bağlıdır. Tetikleyicisi olmayan fonksiyonlar, diğer fonksiyonlar tarafından çağrılan yardımcı fonksiyonlar olarak kullanılabilir.
|
||||
* Tek bir fonksiyonda birden çok tetikleyici türünü birleştirebilirsiniz.
|
||||
|
||||
### Post-install functions
|
||||
|
||||
A post-install function is a logic function that runs automatically after your app is installed on a workspace. This is useful for one-time setup tasks such as seeding default data, creating initial records, or configuring workspace settings.
|
||||
|
||||
When you scaffold a new app with `create-twenty-app`, a post-install function is generated for you at `src/logic-functions/post-install.ts`:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/post-install.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
|
||||
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
|
||||
|
||||
const handler = async (): Promise<void> => {
|
||||
console.log('Post install logic function executed successfully!');
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
name: 'post-install',
|
||||
description: 'Runs after installation to set up the application.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
The function is wired into your app by referencing its universal identifier in `application-config.ts`:
|
||||
|
||||
```typescript
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
// ...
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
You can also manually execute the post-install function at any time using the CLI:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty function:execute --postInstall
|
||||
```
|
||||
|
||||
Önemli noktalar:
|
||||
|
||||
* Post-install functions are standard logic functions — they use `defineLogicFunction()` like any other function.
|
||||
* The `postInstallLogicFunctionUniversalIdentifier` field in `defineApplication()` is optional. If omitted, no function runs after installation.
|
||||
* The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `function:execute --postInstall`.
|
||||
|
||||
### Rota tetikleyicisi yükü
|
||||
|
||||
<Warning>
|
||||
@@ -551,9 +609,74 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Yeni fonksiyonları iki şekilde oluşturabilirsiniz:
|
||||
|
||||
* **Şablondan**: `yarn entity:add` çalıştırın ve yeni bir mantık fonksiyonu ekleme seçeneğini seçin. Bu, bir işleyici ve yapılandırma içeren bir başlangıç dosyası oluşturur.
|
||||
* **Şablondan**: `yarn twenty entity:add` çalıştırın ve yeni bir mantık fonksiyonu ekleme seçeneğini seçin. Bu, bir işleyici ve yapılandırma içeren bir başlangıç dosyası oluşturur.
|
||||
* **Manuel**: Yeni bir `*.logic-function.ts` dosyası oluşturun ve aynı deseni izleyerek `defineLogicFunction()` kullanın.
|
||||
|
||||
### Bir mantık işlevini araç olarak işaretleme
|
||||
|
||||
Mantık işlevleri, yapay zeka ajanları ve iş akışları için **araçlar** olarak sunulabilir. Bir işlev bir araç olarak işaretlendiğinde, Twenty'nin yapay zeka özellikleri tarafından keşfedilebilir hâle gelir ve iş akışı otomasyonlarında bir adım olarak seçilebilir.
|
||||
|
||||
Bir mantık işlevini bir araç olarak işaretlemek için `isTool: true` olarak ayarlayın ve beklenen giriş parametrelerini açıklayan bir `toolInputSchema`yı [JSON Şeması](https://json-schema.org/) kullanarak sağlayın:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/enrich-company.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import Twenty from '~/generated';
|
||||
|
||||
const handler = async (params: { companyName: string; domain?: string }) => {
|
||||
const client = new Twenty();
|
||||
|
||||
const result = await client.mutation({
|
||||
createTask: {
|
||||
__args: {
|
||||
data: {
|
||||
title: `Enrich data for ${params.companyName}`,
|
||||
body: `Domain: ${params.domain ?? 'unknown'}`,
|
||||
},
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
return { taskId: result.createTask.id };
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
|
||||
name: 'enrich-company',
|
||||
description: 'Enrich a company record with external data',
|
||||
timeoutSeconds: 10,
|
||||
handler,
|
||||
isTool: true,
|
||||
toolInputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
companyName: {
|
||||
type: 'string',
|
||||
description: 'The name of the company to enrich',
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
description: 'The company website domain (optional)',
|
||||
},
|
||||
},
|
||||
required: ['companyName'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Önemli noktalar:
|
||||
|
||||
* **`isTool`** (`boolean`, varsayılan: `false`): `true` olarak ayarlandığında, işlev bir araç olarak kaydedilir ve AI ajanları ile iş akışı otomasyonları tarafından kullanılabilir hale gelir.
|
||||
* **`toolInputSchema`** (`object`, isteğe bağlı): İşlevinizin kabul ettiği parametreleri tanımlayan bir JSON Schema nesnesi. AI ajanları, aracın hangi girdileri beklediğini anlamak ve çağrıları doğrulamak için bu şemayı kullanır. Atlanırsa, şema varsayılan olarak `{ type: 'object', properties: {} }` olur (parametre yok).
|
||||
* `isTool: false` (veya ayarlanmamış) olan işlevler araç olarak **sunulmaz**. Yine de doğrudan yürütülebilir veya diğer işlevler tarafından çağrılabilirler, ancak araç keşfinde görünmezler.
|
||||
* **Araç adlandırma**: Bir araç olarak sunulduğunda, işlev adı otomatik olarak `logic_function_<name>` biçimine dönüştürülür (küçük harfe çevrilir, alfasayısal olmayan karakterler alt çizgi ile değiştirilir). Örneğin, `enrich-company` `logic_function_enrich_company` haline gelir.
|
||||
* `isTool` özelliğini tetikleyicilerle birleştirebilirsiniz — bir işlev aynı anda hem bir araç (AI ajanları tarafından çağrılabilir) olabilir hem de olaylar tarafından tetiklenebilir (cron, veritabanı olayları, routes).
|
||||
|
||||
<Note>
|
||||
**İyi bir `description` yazın.** AI ajanları, aracı ne zaman kullanacaklarına karar vermek için işlevin `description` alanına güvenir. Aracın ne yaptığını ve ne zaman çağrılması gerektiğini açıkça belirtin.
|
||||
</Note>
|
||||
|
||||
### Ön uç bileşenleri
|
||||
|
||||
Ön uç bileşenleri, Twenty'nin kullanıcı arayüzünde görüntülenen özel React bileşenleri oluşturmanıza olanak tanır. Yerleşik doğrulamayla bileşenleri tanımlamak için `defineFrontComponent()` kullanın:
|
||||
@@ -584,16 +707,16 @@ export default defineFrontComponent({
|
||||
* Ön uç bileşenleri, Twenty içinde yalıtılmış bağlamlarda görüntülenen React bileşenleridir.
|
||||
* Otomatik algılama için `*.front-component.tsx` dosya soneğini kullanın.
|
||||
* `component` alanı, React bileşeninize referans verir.
|
||||
* Bileşenler, `yarn app:dev` sırasında otomatik olarak oluşturulur ve senkronize edilir.
|
||||
* Bileşenler, `yarn twenty app:dev` sırasında otomatik olarak oluşturulur ve senkronize edilir.
|
||||
|
||||
Yeni ön uç bileşenlerini iki şekilde oluşturabilirsiniz:
|
||||
|
||||
* **Şablondan**: `yarn entity:add` çalıştırın ve yeni bir ön uç bileşeni ekleme seçeneğini seçin.
|
||||
* **Şablondan**: `yarn twenty entity:add` çalıştırın ve yeni bir ön uç bileşeni ekleme seçeneğini seçin.
|
||||
* **Manuel**: Yeni bir `*.front-component.tsx` dosyası oluşturun ve `defineFrontComponent()` kullanın.
|
||||
|
||||
### Oluşturulmuş türlendirilmiş istemci
|
||||
|
||||
Çalışma alanı şemanıza göre generated/ içinde yerel bir türlendirilmiş istemci oluşturmak için yarn app:generate çalıştırın. Fonksiyonlarınızda kullanın:
|
||||
Tipli istemci, `yarn twenty app:dev` tarafından otomatik olarak oluşturulur ve çalışma alanı şemanıza göre `node_modules/twenty-sdk/generated` içine kaydedilir. Fonksiyonlarınızda kullanın:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -602,7 +725,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
İstemci `yarn app:generate` tarafından yeniden oluşturulur. Nesnelerinizi değiştirdikten sonra veya yeni bir çalışma alanına katılırken yeniden çalıştırın.
|
||||
Nesneleriniz veya alanlarınız değiştiğinde, istemci `yarn twenty app:dev` tarafından otomatik olarak yeniden oluşturulur.
|
||||
|
||||
#### Mantık fonksiyonlarında çalışma zamanı kimlik bilgileri
|
||||
|
||||
@@ -623,40 +746,29 @@ Nesneleri, mantık fonksiyonlarını, ön uç bileşenlerini ve birden çok teti
|
||||
|
||||
## Manuel kurulum (scaffolder olmadan)
|
||||
|
||||
En iyi başlangıç deneyimi için `create-twenty-app` kullanmanızı önersek de, bir projeyi manuel olarak da kurabilirsiniz. CLI'yi global olarak kurmayın. Bunun yerine `twenty-sdk`'yi yerel bir bağımlılık olarak ekleyin ve package.json içinde betikleri bağlayın:
|
||||
En iyi başlangıç deneyimi için `create-twenty-app` kullanmanızı önersek de, bir projeyi manuel olarak da kurabilirsiniz. CLI'yi global olarak kurmayın. Bunun yerine `twenty-sdk`'yi yerel bir bağımlılık olarak ekleyin ve package.json içinde tek bir betik tanımlayın:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
```
|
||||
|
||||
Ardından şu gibi betikler ekleyin:
|
||||
Ardından bir `twenty` betiği ekleyin:
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
"auth:login": "twenty auth:login",
|
||||
"auth:logout": "twenty auth:logout",
|
||||
"auth:status": "twenty auth:status",
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
"function:execute": "twenty function:execute",
|
||||
"help": "twenty help"
|
||||
"twenty": "twenty"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Artık aynı komutları Yarn üzerinden çalıştırabilirsiniz; örn. `yarn app:dev`, `yarn app:generate` vb.
|
||||
Artık tüm komutları `yarn twenty <command>` üzerinden çalıştırabilirsiniz; örn. `yarn twenty app:dev`, `yarn twenty help` vb.
|
||||
|
||||
## Sorun Giderme
|
||||
|
||||
* Kimlik doğrulama hataları: `yarn auth:login` çalıştırın ve API anahtarınızın gerekli izinlere sahip olduğundan emin olun.
|
||||
* Kimlik doğrulama hataları: `yarn twenty auth:login` çalıştırın ve API anahtarınızın gerekli izinlere sahip olduğundan emin olun.
|
||||
* Sunucuya bağlanılamıyor: API URL’sini ve Twenty sunucusunun erişilebilir olduğunu doğrulayın.
|
||||
* Türler veya istemci eksik/eski: `yarn app:generate` çalıştırın.
|
||||
* Geliştirme modu eşitlenmiyor: `yarn app:dev`'in çalıştığından ve değişikliklerin ortamınız tarafından yok sayılmadığından emin olun.
|
||||
* Türler veya istemci eksik/eski: `yarn twenty app:dev` komutunu yeniden çalıştırın — tip tanımlı istemciyi otomatik olarak oluşturur.
|
||||
* Geliştirme modu eşitlenmiyor: `yarn twenty app:dev`'in çalıştığından ve değişikliklerin ortamınız tarafından yok sayılmadığından emin olun.
|
||||
|
||||
Discord Yardım Kanalı: https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -36,32 +36,32 @@ corepack enable
|
||||
yarn install
|
||||
|
||||
# 使用你的 API 密钥进行身份验证(系统会提示你)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# 启动开发模式:会将本地更改自动同步到你的工作区
|
||||
yarn app:dev
|
||||
yarn twenty app:dev
|
||||
```
|
||||
|
||||
从这里您可以:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new entity to your application (guided)
|
||||
yarn entity:add
|
||||
|
||||
# Generate a typed Twenty client and workspace entity types
|
||||
yarn app:generate
|
||||
yarn twenty entity:add
|
||||
|
||||
# Watch your application's function logs
|
||||
yarn function:logs
|
||||
yarn twenty function:logs
|
||||
|
||||
# Execute a function by name
|
||||
yarn function:execute -n my-function -p '{\"name\": \"test\"}'
|
||||
yarn twenty function:execute -n my-function -p '{"name": "test"}'
|
||||
|
||||
# Execute the post-install function
|
||||
yarn twenty function:execute --postInstall
|
||||
|
||||
# Uninstall the application from the current workspace
|
||||
yarn app:uninstall
|
||||
yarn twenty app:uninstall
|
||||
|
||||
# Display commands' help
|
||||
yarn help
|
||||
yarn twenty help
|
||||
```
|
||||
|
||||
另请参阅:[create-twenty-app](https://www.npmjs.com/package/create-twenty-app) 和 [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk) 的 CLI 参考页面。
|
||||
@@ -73,7 +73,7 @@ yarn help
|
||||
* 将一个最小的基础应用复制到 `my-twenty-app/` 中
|
||||
* 添加本地 `twenty-sdk` 依赖和 Yarn 4 配置
|
||||
* 创建与 `twenty` CLI 关联的配置文件和脚本
|
||||
* 生成默认的应用配置和默认的函数角色
|
||||
* Generates a default application config, a default function role, and a post-install function
|
||||
|
||||
一个新生成的脚手架应用如下所示:
|
||||
|
||||
@@ -89,20 +89,21 @@ my-twenty-app/
|
||||
eslint.config.mjs
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # 公共资源文件夹(图像、字体等)
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # 必需 - 主应用程序配置
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── roles/
|
||||
│ └── default-role.ts # 用于逻辑函数的默认角色
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── logic-functions/
|
||||
│ └── hello-world.ts # 示例逻辑函数
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
└── front-components/
|
||||
└── hello-world.tsx # 示例前端组件
|
||||
└── hello-world.tsx # Example front component
|
||||
```
|
||||
|
||||
总体来说:
|
||||
|
||||
* **package.json**:声明应用名称、版本、运行时(Node 24+、Yarn 4),并添加 `twenty-sdk`,以及诸如 `app:dev`、`app:generate`、`entity:add`、`function:logs`、`function:execute`、`app:uninstall` 等脚本和认证命令,它们都会委托给本地的 `twenty` CLI。
|
||||
* **package.json**:声明应用名称、版本、引擎(Node 24+、Yarn 4),并添加 `twenty-sdk` 以及一个 `twenty` 脚本,该脚本会委托给本地的 `twenty` CLI。 运行 `yarn twenty help` 以列出所有可用命令。
|
||||
* **.gitignore**:忽略常见产物,如 `node_modules`、`.yarn`、`generated/`(类型化客户端)、`dist/`、`build/`、覆盖率文件夹、日志文件以及 `.env*` 文件。
|
||||
* **yarn.lock**、**.yarnrc.yml**、**.yarn/**:锁定并配置项目使用的 Yarn 4 工具链。
|
||||
* **.nvmrc**:固定项目期望的 Node.js 版本。
|
||||
@@ -142,12 +143,12 @@ export default defineObject({
|
||||
|
||||
后续命令将添加更多文件和文件夹:
|
||||
|
||||
* `yarn app:generate` 将创建一个 `generated/` 文件夹(类型化 Twenty 客户端 + 工作空间类型)。
|
||||
* `yarn entity:add` 会在 `src/` 下为你的自定义对象、函数、前端组件或角色添加实体定义文件。
|
||||
* `yarn twenty app:dev` 将在 `node_modules/twenty-sdk/generated` 中自动生成一个类型化的 API 客户端(类型化的 Twenty 客户端 + 工作区类型)。
|
||||
* `yarn twenty entity:add` 会在 `src/` 下为你的自定义对象、函数、前端组件或角色添加实体定义文件。
|
||||
|
||||
## 身份验证
|
||||
|
||||
首次运行 `yarn auth:login` 时,你将被提示输入:
|
||||
首次运行 `yarn twenty auth:login` 时,你将被提示输入:
|
||||
|
||||
* API URL(默认为 http://localhost:3000 或你当前的工作空间配置)
|
||||
* API 密钥
|
||||
@@ -158,25 +159,25 @@ export default defineObject({
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Login interactively (recommended)
|
||||
yarn auth:login
|
||||
yarn twenty auth:login
|
||||
|
||||
# Login to a specific workspace profile
|
||||
yarn auth:login --workspace my-custom-workspace
|
||||
yarn twenty auth:login --workspace my-custom-workspace
|
||||
|
||||
# List all configured workspaces
|
||||
yarn auth:list
|
||||
yarn twenty auth:list
|
||||
|
||||
# Switch the default workspace (interactive)
|
||||
yarn auth:switch
|
||||
yarn twenty auth:switch
|
||||
|
||||
# Switch to a specific workspace
|
||||
yarn auth:switch production
|
||||
yarn twenty auth:switch production
|
||||
|
||||
# Check current authentication status
|
||||
yarn auth:status
|
||||
yarn twenty auth:status
|
||||
```
|
||||
|
||||
使用 `auth:switch` 切换工作空间后,后续所有命令将默认使用该工作空间。 你仍可通过 `--workspace <name>` 临时覆盖。
|
||||
使用 `yarn twenty auth:switch` 切换工作空间后,后续所有命令将默认使用该工作空间。 你仍可通过 `--workspace <name>` 临时覆盖。
|
||||
|
||||
## 使用 SDK 资源(类型与配置)
|
||||
|
||||
@@ -276,10 +277,14 @@ export default defineObject({
|
||||
* `universalIdentifier` 必须在各次部署间保持唯一且稳定。
|
||||
* 每个字段都需要 `name`、`type`、`label` 以及其自身稳定的 `universalIdentifier`。
|
||||
* `fields` 数组是可选的——你可以定义没有自定义字段的对象。
|
||||
* 你可以使用 `yarn entity:add` 脚手架创建新对象,它会引导你完成命名、字段和关系。
|
||||
* 你可以使用 `yarn twenty entity:add` 脚手架创建新对象,它会引导你完成命名、字段和关系。
|
||||
|
||||
<Note>
|
||||
**基础字段会自动创建。** 当你定义自定义对象时,Twenty 会自动添加 `name`、`createdAt`、`updatedAt`、`createdBy`、`position`、`deletedAt` 等标准字段。 你无需在 `fields` 数组中定义这些字段——只需添加你的自定义字段。
|
||||
**基础字段会自动创建。** 当你定义自定义对象时,Twenty 会自动添加标准字段
|
||||
例如 `id`、`name`、`createdAt`、`updatedAt`、`createdBy`、`updatedBy` 和 `deletedAt`。
|
||||
你无需在 `fields` 数组中定义这些字段——只需添加你的自定义字段。
|
||||
你可以通过在你的 `fields` 数组中定义一个同名字段来覆盖默认字段,
|
||||
但不建议这样做。
|
||||
</Note>
|
||||
|
||||
### 应用配置(application-config.ts)
|
||||
@@ -289,6 +294,7 @@ export default defineObject({
|
||||
* **应用的身份**:标识符、显示名称和描述。
|
||||
* **函数如何运行**:它们用于权限的角色。
|
||||
* **(可选)变量**:以环境变量形式提供给函数的键值对。
|
||||
* **(Optional) post-install function**: a logic function that runs after the app is installed.
|
||||
|
||||
使用 `defineApplication()` 定义你的应用配置:
|
||||
|
||||
@@ -296,6 +302,7 @@ export default defineObject({
|
||||
// src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
@@ -311,6 +318,7 @@ export default defineApplication({
|
||||
},
|
||||
},
|
||||
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -319,6 +327,7 @@ export default defineApplication({
|
||||
* `universalIdentifier` 字段是你拥有的确定性 ID;生成一次并在多次同步中保持稳定。
|
||||
* `applicationVariables` 会变成函数可用的环境变量(例如,`DEFAULT_RECIPIENT_NAME` 可作为 `process.env.DEFAULT_RECIPIENT_NAME` 使用)。
|
||||
* `defaultRoleUniversalIdentifier` 必须与角色文件一致(见下文)。
|
||||
* `postInstallLogicFunctionUniversalIdentifier` (optional) points to a logic function that runs automatically after the app is installed. See [Post-install functions](#post-install-functions).
|
||||
|
||||
#### 角色和权限
|
||||
|
||||
@@ -457,6 +466,55 @@ export default defineLogicFunction({
|
||||
* `triggers` 数组是可选的。 没有触发器的函数可作为实用函数,被其他函数调用。
|
||||
* 你可以在单个函数中混用多种触发器类型。
|
||||
|
||||
### Post-install functions
|
||||
|
||||
A post-install function is a logic function that runs automatically after your app is installed on a workspace. This is useful for one-time setup tasks such as seeding default data, creating initial records, or configuring workspace settings.
|
||||
|
||||
When you scaffold a new app with `create-twenty-app`, a post-install function is generated for you at `src/logic-functions/post-install.ts`:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/post-install.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
|
||||
export const POST_INSTALL_UNIVERSAL_IDENTIFIER = '<generated-uuid>';
|
||||
|
||||
const handler = async (): Promise<void> => {
|
||||
console.log('Post install logic function executed successfully!');
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
name: 'post-install',
|
||||
description: 'Runs after installation to set up the application.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
The function is wired into your app by referencing its universal identifier in `application-config.ts`:
|
||||
|
||||
```typescript
|
||||
import { POST_INSTALL_UNIVERSAL_IDENTIFIER } from 'src/logic-functions/post-install';
|
||||
|
||||
export default defineApplication({
|
||||
// ...
|
||||
postInstallLogicFunctionUniversalIdentifier: POST_INSTALL_UNIVERSAL_IDENTIFIER,
|
||||
});
|
||||
```
|
||||
|
||||
You can also manually execute the post-install function at any time using the CLI:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty function:execute --postInstall
|
||||
```
|
||||
|
||||
关键点:
|
||||
|
||||
* Post-install functions are standard logic functions — they use `defineLogicFunction()` like any other function.
|
||||
* The `postInstallLogicFunctionUniversalIdentifier` field in `defineApplication()` is optional. If omitted, no function runs after installation.
|
||||
* The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `function:execute --postInstall`.
|
||||
|
||||
### 路由触发器负载
|
||||
|
||||
<Warning>
|
||||
@@ -551,9 +609,74 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
你可以通过两种方式创建新函数:
|
||||
|
||||
* **脚手架生成**:运行 `yarn entity:add` 并选择添加新逻辑函数的选项。 这将生成一个包含处理程序和配置的入门文件。
|
||||
* **脚手架生成**:运行 `yarn twenty entity:add` 并选择添加新逻辑函数的选项。 这将生成一个包含处理程序和配置的入门文件。
|
||||
* **手动**:创建一个新的 `*.logic-function.ts` 文件,并使用 `defineLogicFunction()`,遵循相同的模式。
|
||||
|
||||
### 将逻辑函数标记为工具
|
||||
|
||||
逻辑函数可以作为供 AI 智能体和工作流使用的**工具**对外提供。 当函数被标记为工具时,Twenty 的 AI 功能即可发现它,并可在工作流自动化中将其选作一个步骤。
|
||||
|
||||
要将逻辑函数标记为工具,请设置 `isTool: true`,并提供 `toolInputSchema`,使用 [JSON Schema](https://json-schema.org/) 描述预期的输入参数:
|
||||
|
||||
```typescript
|
||||
// src/logic-functions/enrich-company.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import Twenty from '~/generated';
|
||||
|
||||
const handler = async (params: { companyName: string; domain?: string }) => {
|
||||
const client = new Twenty();
|
||||
|
||||
const result = await client.mutation({
|
||||
createTask: {
|
||||
__args: {
|
||||
data: {
|
||||
title: `Enrich data for ${params.companyName}`,
|
||||
body: `Domain: ${params.domain ?? 'unknown'}`,
|
||||
},
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
return { taskId: result.createTask.id };
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
|
||||
name: 'enrich-company',
|
||||
description: 'Enrich a company record with external data',
|
||||
timeoutSeconds: 10,
|
||||
handler,
|
||||
isTool: true,
|
||||
toolInputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
companyName: {
|
||||
type: 'string',
|
||||
description: 'The name of the company to enrich',
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
description: 'The company website domain (optional)',
|
||||
},
|
||||
},
|
||||
required: ['companyName'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
关键点:
|
||||
|
||||
* **`isTool`** (`boolean`, 默认: `false`): 当设置为 `true` 时,该函数会被注册为工具,并可供 AI 代理和工作流自动化使用。
|
||||
* **`toolInputSchema`** (`object`, 可选): 描述函数可接受参数的 JSON Schema 对象。 AI 代理使用此架构来理解该工具期望的输入并验证调用。 如果省略,架构将默认为 `{ type: 'object', properties: {} }`(无参数)。
|
||||
* 设置为 `isTool: false`(或未设置)的函数**不会**被暴露为工具。 它们仍可直接执行或被其他函数调用,但不会出现在工具发现中。
|
||||
* **工具命名**: 当作为工具对外暴露时,函数名会被自动规范化为 `logic_function_<name>`(转换为小写,非字母数字字符替换为下划线)。 例如,`enrich-company` 将变为 `logic_function_enrich_company`。
|
||||
* 你可以将 `isTool` 与触发器结合使用——一个函数既可以作为工具(由 AI 代理调用),也可以同时由事件(cron、数据库事件、路由)触发。
|
||||
|
||||
<Note>
|
||||
**写一个好的 `description`。** AI 代理会依赖该函数的 `description` 字段来决定何时使用该工具。 明确说明该工具的作用以及应在何时调用。
|
||||
</Note>
|
||||
|
||||
### 前端组件
|
||||
|
||||
前端组件使你可以构建在 Twenty 的 UI 中渲染的自定义 React 组件。 使用 `defineFrontComponent()` 以内置校验定义组件:
|
||||
@@ -584,16 +707,16 @@ export default defineFrontComponent({
|
||||
* 前端组件是在 Twenty 中的隔离上下文中渲染的 React 组件。
|
||||
* 使用 `*.front-component.tsx` 文件后缀以便自动检测。
|
||||
* `component` 字段引用你的 React 组件。
|
||||
* 组件会在 `yarn app:dev` 期间自动构建并同步。
|
||||
* 组件会在 `yarn twenty app:dev` 期间自动构建并同步。
|
||||
|
||||
你可以通过两种方式创建新的前端组件:
|
||||
|
||||
* **脚手架生成**:运行 `yarn entity:add` 并选择添加新前端组件的选项。
|
||||
* **脚手架生成**:运行 `yarn twenty entity:add` 并选择添加新前端组件的选项。
|
||||
* **手动**:创建一个新的 `*.front-component.tsx` 文件,并使用 `defineFrontComponent()`。
|
||||
|
||||
### 生成的类型化客户端
|
||||
|
||||
运行 yarn app:generate,根据你的工作空间模式在 generated/ 中创建本地类型化客户端。 在你的函数中使用它:
|
||||
类型化客户端由 `yarn twenty app:dev` 自动生成,并基于你的工作区架构存放在 `node_modules/twenty-sdk/generated`。 在你的函数中使用它:
|
||||
|
||||
```typescript
|
||||
import Twenty from '~/generated';
|
||||
@@ -602,7 +725,7 @@ const client = new Twenty();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
```
|
||||
|
||||
客户端会通过 `yarn app:generate` 重新生成。 在更改对象之后或接入新工作空间时,请重新运行。
|
||||
每当你的对象或字段发生变化时,`yarn twenty app:dev` 都会自动重新生成该客户端。
|
||||
|
||||
#### 逻辑函数中的运行时凭据
|
||||
|
||||
@@ -623,40 +746,29 @@ const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
|
||||
## 手动设置(不使用脚手架)
|
||||
|
||||
虽然我们建议使用 `create-twenty-app` 以获得最佳的上手体验,但你也可以手动设置项目。 不要全局安装 CLI。 相反,请将 `twenty-sdk` 添加为本地依赖,并在你的 package.json 中连接相关脚本:
|
||||
虽然我们建议使用 `create-twenty-app` 以获得最佳的上手体验,但你也可以手动设置项目。 不要全局安装 CLI。 相反,请将 `twenty-sdk` 添加为本地依赖,并在你的 package.json 中配置一个脚本:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D twenty-sdk
|
||||
```
|
||||
|
||||
然后添加如下脚本:
|
||||
然后添加一个 `twenty` 脚本:
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
"scripts": {
|
||||
"auth:login": "twenty auth:login",
|
||||
"auth:logout": "twenty auth:logout",
|
||||
"auth:status": "twenty auth:status",
|
||||
"auth:switch": "twenty auth:switch",
|
||||
"auth:list": "twenty auth:list",
|
||||
"app:dev": "twenty app:dev",
|
||||
"app:generate": "twenty app:generate",
|
||||
"app:uninstall": "twenty app:uninstall",
|
||||
"entity:add": "twenty entity:add",
|
||||
"function:logs": "twenty function:logs",
|
||||
"function:execute": "twenty function:execute",
|
||||
"help": "twenty help"
|
||||
"twenty": "twenty"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
现在你可以通过 Yarn 运行相同的命令,例如 `yarn app:dev`、`yarn app:generate` 等。
|
||||
现在你可以通过 `yarn twenty <command>` 运行所有命令,例如 `yarn twenty app:dev`、`yarn twenty help` 等。
|
||||
|
||||
## 故障排除
|
||||
|
||||
* 身份验证错误:运行 `yarn auth:login`,并确保你的 API 密钥具有所需权限。
|
||||
* 身份验证错误:运行 `yarn twenty auth:login`,并确保你的 API 密钥具有所需权限。
|
||||
* 无法连接到服务器:请验证 API URL,并确保 Twenty 服务器可达。
|
||||
* 类型或客户端缺失/过期:运行 `yarn app:generate`。
|
||||
* 开发模式未同步:确保 `yarn app:dev` 正在运行,并且你的环境不会忽略变更。
|
||||
* 类型或客户端缺失/过期:重启 `yarn twenty app:dev` — 它会自动生成类型化客户端。
|
||||
* 开发模式未同步:确保 `yarn twenty app:dev` 正在运行,并且你的环境不会忽略变更。
|
||||
|
||||
Discord 帮助频道:https://discord.com/channels/1130383047699738754/1130386664812982322
|
||||
|
||||
@@ -111,8 +111,8 @@ test('Create and update record', async ({ page }) => {
|
||||
|
||||
await companyRelationWidget.hover();
|
||||
await companyRelationWidget.locator('.tabler-icon-pencil').click();
|
||||
await page.getByRole('textbox', { name: 'Search' }).fill('Goog');
|
||||
await expect(page.getByRole('option', { name: 'Google' })).toBeVisible();
|
||||
await page.getByRole('textbox', { name: 'Search' }).fill('VMw');
|
||||
await expect(page.getByRole('option', { name: 'VMware' })).toBeVisible();
|
||||
const [updatePersonResponse] = await Promise.all([
|
||||
page.waitForResponse(async (response) => {
|
||||
if (!response.url().endsWith('/graphql')) {
|
||||
@@ -123,7 +123,7 @@ test('Create and update record', async ({ page }) => {
|
||||
|
||||
return requestBody.operationName === 'UpdateOnePerson';
|
||||
}),
|
||||
await page.getByRole('option', { name: 'Google' }).click({force: true})
|
||||
await page.getByRole('option', { name: 'VMware' }).click({force: true})
|
||||
]);
|
||||
|
||||
const body = await updatePersonResponse.json()
|
||||
@@ -153,6 +153,6 @@ test('Create and update record', async ({ page }) => {
|
||||
expect(findOnePersonReponseBody.data.person.linkedinLink.primaryLinkUrl).toBe('linkedin.com/johndoe');
|
||||
expect(findOnePersonReponseBody.data.person.phones.primaryPhoneNumber).toBe('611223344');
|
||||
expect(findOnePersonReponseBody.data.person.workPreference).toEqual(['HYBRID']);
|
||||
expect(findOnePersonReponseBody.data.person.company.name).toBe('Google');
|
||||
expect(findOnePersonReponseBody.data.person.company.name).toBe('VMware');
|
||||
|
||||
});
|
||||
|
||||
@@ -5,9 +5,17 @@
|
||||
"tags": ["scope:backend"],
|
||||
"targets": {
|
||||
"build": {
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"executor": "nx:run-commands",
|
||||
"cache": true,
|
||||
"inputs": ["production", "^production"],
|
||||
"outputs": ["{projectRoot}/dist"],
|
||||
"options": {
|
||||
"outputPath": "{projectRoot}/dist"
|
||||
"cwd": "{projectRoot}",
|
||||
"commands": [
|
||||
"npx vite build",
|
||||
"tsgo -p tsconfig.lib.json --declaration --emitDeclarationOnly --outDir dist --rootDir src --composite false && npx tsc-alias -p tsconfig.lib.json --outDir dist"
|
||||
],
|
||||
"parallel": false
|
||||
},
|
||||
"dependsOn": ["^build"]
|
||||
},
|
||||
|
||||
@@ -3,7 +3,6 @@ import react from '@vitejs/plugin-react-swc';
|
||||
import * as path from 'path';
|
||||
import { APP_LOCALES } from 'twenty-shared/translations';
|
||||
import { defineConfig } from 'vite';
|
||||
import dts from 'vite-plugin-dts';
|
||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||
|
||||
export default defineConfig({
|
||||
@@ -25,19 +24,13 @@ export default defineConfig({
|
||||
configPath: path.resolve(__dirname, './lingui.config.ts'),
|
||||
}),
|
||||
tsconfigPaths({
|
||||
root: __dirname
|
||||
}),
|
||||
dts({
|
||||
entryRoot: 'src',
|
||||
tsconfigPath: path.join(__dirname, 'tsconfig.lib.json'),
|
||||
root: __dirname,
|
||||
}),
|
||||
],
|
||||
|
||||
// Configuration for building your library.
|
||||
// See: https://vitejs.dev/guide/build.html#library-mode
|
||||
build: {
|
||||
outDir: './dist',
|
||||
reportCompressedSize: true,
|
||||
reportCompressedSize: false,
|
||||
commonjsOptions: {
|
||||
transformMixedEsModules: true,
|
||||
},
|
||||
|
||||
@@ -6,10 +6,6 @@ import {
|
||||
rule as effectComponents,
|
||||
RULE_NAME as effectComponentsName,
|
||||
} from './rules/effect-components';
|
||||
import {
|
||||
rule as exportComponentProps,
|
||||
RULE_NAME as exportComponentPropsName,
|
||||
} from './rules/export-component-props';
|
||||
import {
|
||||
rule as explicitBooleanPredicatesInIf,
|
||||
RULE_NAME as explicitBooleanPredicatesInIfName,
|
||||
@@ -99,7 +95,6 @@ module.exports = {
|
||||
rules: {
|
||||
[componentPropsNamingName]: componentPropsNaming,
|
||||
[effectComponentsName]: effectComponents,
|
||||
[exportComponentPropsName]: exportComponentProps,
|
||||
[matchingStateVariableName]: matchingStateVariable,
|
||||
[noHardcodedColorsName]: noHardcodedColors,
|
||||
[noStateUserefName]: noStateUseref,
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/**
|
||||
* @jest-environment node
|
||||
*/
|
||||
import { RuleTester } from 'eslint';
|
||||
|
||||
import { rule, RULE_NAME } from './export-component-props';
|
||||
|
||||
const typescriptParser = require('@typescript-eslint/parser');
|
||||
|
||||
const ruleTester = new RuleTester({
|
||||
languageOptions: {
|
||||
parser: typescriptParser,
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
ruleTester.run(RULE_NAME, rule as any, {
|
||||
valid: [
|
||||
{
|
||||
name: 'Props type is already exported',
|
||||
code: `
|
||||
export type MyComponentProps = { label: string };
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'Props interface is already exported',
|
||||
code: `
|
||||
export interface MyComponentProps { label: string }
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'Type that doesn\'t end with Props is ignored',
|
||||
code: `
|
||||
type MyComponentOptions = { flag: boolean };
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'Interface that doesn\'t end with Props is ignored',
|
||||
code: `
|
||||
interface MyComponentConfig { flag: boolean }
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'Props re-exported via export { FooProps } is treated as exported',
|
||||
code: `
|
||||
type MyComponentProps = { label: string };
|
||||
export { MyComponentProps };
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'Non-Props type is not required to be exported',
|
||||
code: `
|
||||
type InternalState = { count: number };
|
||||
`,
|
||||
},
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
name: 'Unexported Props type alias',
|
||||
code: `
|
||||
type MyComponentProps = { label: string };
|
||||
`,
|
||||
errors: [{ messageId: 'mustExportProps' }],
|
||||
output: `
|
||||
export type MyComponentProps = { label: string };
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'Unexported Props interface',
|
||||
code: `
|
||||
interface MyComponentProps { label: string }
|
||||
`,
|
||||
errors: [{ messageId: 'mustExportProps' }],
|
||||
output: `
|
||||
export interface MyComponentProps { label: string }
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'Unexported Props type used in a component',
|
||||
code: `
|
||||
type MyComponentProps = { label: string };
|
||||
export const MyComponent = ({ label }: MyComponentProps) => <div>{label}</div>;
|
||||
`,
|
||||
errors: [{ messageId: 'mustExportProps' }],
|
||||
output: `
|
||||
export type MyComponentProps = { label: string };
|
||||
export const MyComponent = ({ label }: MyComponentProps) => <div>{label}</div>;
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'Unexported Props type with non-exported component',
|
||||
code: `
|
||||
type MyComponentProps = { label: string };
|
||||
const MyComponent = ({ label }: MyComponentProps) => <div>{label}</div>;
|
||||
`,
|
||||
errors: [{ messageId: 'mustExportProps' }],
|
||||
output: `
|
||||
export type MyComponentProps = { label: string };
|
||||
const MyComponent = ({ label }: MyComponentProps) => <div>{label}</div>;
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'Unexported Props type defined after the component',
|
||||
code: `
|
||||
export const MyComponent = ({ label }: MyComponentProps) => <div>{label}</div>;
|
||||
type MyComponentProps = { label: string };
|
||||
`,
|
||||
errors: [{ messageId: 'mustExportProps' }],
|
||||
output: `
|
||||
export const MyComponent = ({ label }: MyComponentProps) => <div>{label}</div>;
|
||||
export type MyComponentProps = { label: string };
|
||||
`,
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -1,99 +0,0 @@
|
||||
import { ESLintUtils, TSESTree } from '@typescript-eslint/utils';
|
||||
import { isIdentifier } from '@typescript-eslint/utils/ast-utils';
|
||||
|
||||
export const RULE_NAME = 'export-component-props';
|
||||
|
||||
// NOTE: The rule will be available in ESLint configs as "@nx/workspace-export-component-props"
|
||||
export const rule = ESLintUtils.RuleCreator(() => __filename)({
|
||||
name: RULE_NAME,
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'Ensure types/interfaces ending with "Props" are exported',
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [],
|
||||
messages: {
|
||||
mustExportProps:
|
||||
"Props type '{{ typeName }}' must be exported.",
|
||||
},
|
||||
},
|
||||
defaultOptions: [],
|
||||
create: (context) => {
|
||||
const reExportedNames = new Set<string>();
|
||||
const unexportedPropsNodes = new Map<
|
||||
string,
|
||||
| TSESTree.TSTypeAliasDeclaration
|
||||
| TSESTree.TSInterfaceDeclaration
|
||||
>();
|
||||
|
||||
const collectUnexportedProps = (
|
||||
node:
|
||||
| TSESTree.TSTypeAliasDeclaration
|
||||
| TSESTree.TSInterfaceDeclaration,
|
||||
) => {
|
||||
const typeName = node.id.name;
|
||||
|
||||
if (!typeName.endsWith('Props')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isExported =
|
||||
node.parent?.type ===
|
||||
TSESTree.AST_NODE_TYPES.ExportNamedDeclaration;
|
||||
|
||||
if (!isExported) {
|
||||
unexportedPropsNodes.set(typeName, node);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
TSTypeAliasDeclaration: collectUnexportedProps,
|
||||
TSInterfaceDeclaration: collectUnexportedProps,
|
||||
|
||||
ExportNamedDeclaration: (
|
||||
node: TSESTree.ExportNamedDeclaration,
|
||||
) => {
|
||||
for (const specifier of node.specifiers) {
|
||||
if (
|
||||
specifier.type ===
|
||||
TSESTree.AST_NODE_TYPES.ExportSpecifier &&
|
||||
isIdentifier(specifier.local)
|
||||
) {
|
||||
const name = specifier.local.name;
|
||||
|
||||
if (name.endsWith('Props')) {
|
||||
reExportedNames.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
'Program:exit': () => {
|
||||
for (const [typeName, node] of unexportedPropsNodes) {
|
||||
if (reExportedNames.has(typeName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
context.report({
|
||||
node: node.id,
|
||||
messageId: 'mustExportProps',
|
||||
data: { typeName },
|
||||
fix: (fixer) => {
|
||||
const sourceCode = context.sourceCode;
|
||||
const firstToken = sourceCode.getFirstToken(node);
|
||||
const target = firstToken ?? node;
|
||||
|
||||
if (firstToken?.value === 'export') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return fixer.insertTextBefore(target, 'export ');
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -52,11 +52,11 @@ export const rule = createRule<[], 'restApiMethodsShouldBeGuarded'>({
|
||||
meta: {
|
||||
docs: {
|
||||
description:
|
||||
'REST API endpoints should have authentication guards (UserAuthGuard, WorkspaceAuthGuard, FilePathGuard, or FilesFieldGuard) or be explicitly marked as public (PublicEndpointGuard) and permission guards (SettingsPermissionsGuard or CustomPermissionGuard) to maintain our security model.',
|
||||
'REST API endpoints should have authentication guards (UserAuthGuard, WorkspaceAuthGuard, FilePathGuard, FileByIdGuard) or be explicitly marked as public (PublicEndpointGuard) and permission guards (SettingsPermissionsGuard or CustomPermissionGuard) to maintain our security model.',
|
||||
},
|
||||
messages: {
|
||||
restApiMethodsShouldBeGuarded:
|
||||
'All REST API controller endpoints must have authentication guards (@UseGuards(UserAuthGuard/WorkspaceAuthGuard/FilePathGuard/FileIdGuard/FilesFieldGuard/PublicEndpointGuard)) and permission guards (@UseGuards(..., SettingsPermissionsGuard(PermissionFlagType.XXX)), CustomPermissionGuard for custom logic, or NoPermissionGuard for special cases).',
|
||||
'All REST API controller endpoints must have authentication guards (@UseGuards(UserAuthGuard/WorkspaceAuthGuard/FilePathGuard/FileByIdGuard/PublicEndpointGuard)) and permission guards (@UseGuards(..., SettingsPermissionsGuard(PermissionFlagType.XXX)), CustomPermissionGuard for custom logic, or NoPermissionGuard for special cases).',
|
||||
},
|
||||
schema: [],
|
||||
hasSuggestions: false,
|
||||
|
||||
@@ -42,7 +42,7 @@ export const typedTokenHelpers = {
|
||||
TSESTree.AST_NODE_TYPES.Identifier &&
|
||||
decorator.expression.callee.name === 'UseGuards'
|
||||
) {
|
||||
// Check the arguments for UserAuthGuard, WorkspaceAuthGuard, PublicEndpoint, FilePathGuard, or FilesFieldGuard
|
||||
// Check the arguments for UserAuthGuard, WorkspaceAuthGuard, PublicEndpoint, FilePathGuard or FileByIdGuard
|
||||
return decorator.expression.arguments.some((arg) => {
|
||||
if (arg.type === TSESTree.AST_NODE_TYPES.Identifier) {
|
||||
return (
|
||||
@@ -50,7 +50,7 @@ export const typedTokenHelpers = {
|
||||
arg.name === 'WorkspaceAuthGuard' ||
|
||||
arg.name === 'PublicEndpointGuard' ||
|
||||
arg.name === 'FilePathGuard' ||
|
||||
arg.name === 'FilesFieldGuard'
|
||||
arg.name === 'FileByIdGuard'
|
||||
);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -28,6 +28,7 @@ module.exports = {
|
||||
'./src/modules/attachments/graphql/**/*.{ts,tsx}',
|
||||
'./src/modules/file/graphql/**/*.{ts,tsx}',
|
||||
'./src/modules/onboarding/graphql/**/*.{ts,tsx}',
|
||||
'./src/modules/front-components/graphql/**/*.{ts,tsx}',
|
||||
|
||||
'./src/modules/page-layout/widgets/**/graphql/**/*.{ts,tsx}',
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ process.env.TZ = 'GMT';
|
||||
// eslint-disable-next-line no-undef
|
||||
process.env.LC_ALL = 'en_US.UTF-8';
|
||||
const jestConfig = {
|
||||
silent: true,
|
||||
// For more information please have a look to official docs https://jestjs.io/docs/configuration/#prettierpath-string
|
||||
// Prettier v3 will should be supported in jest v30 https://github.com/jestjs/jest/releases/tag/v30.0.0-alpha.1
|
||||
prettierPath: null,
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
||||
import {
|
||||
ReadableStream as NodeReadableStream,
|
||||
TransformStream as NodeTransformStream,
|
||||
WritableStream as NodeWritableStream,
|
||||
} from 'node:stream/web';
|
||||
|
||||
import { i18n } from '@lingui/core';
|
||||
import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||
@@ -12,6 +17,27 @@ import { messages as enMessages } from '~/locales/generated/en';
|
||||
i18n.load({ [SOURCE_LOCALE]: enMessages });
|
||||
i18n.activate(SOURCE_LOCALE);
|
||||
|
||||
const globalWithWebStreams = globalThis as Record<string, unknown>;
|
||||
|
||||
if (globalWithWebStreams.TransformStream === undefined) {
|
||||
globalWithWebStreams.TransformStream = NodeTransformStream;
|
||||
}
|
||||
|
||||
if (globalWithWebStreams.ReadableStream === undefined) {
|
||||
globalWithWebStreams.ReadableStream = NodeReadableStream;
|
||||
}
|
||||
|
||||
if (globalWithWebStreams.WritableStream === undefined) {
|
||||
globalWithWebStreams.WritableStream = NodeWritableStream;
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
Object.defineProperty(window, 'scrollTo', {
|
||||
value: () => {},
|
||||
writable: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Add Jest matchers for toThrowError and other missing methods
|
||||
declare global {
|
||||
namespace jest {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -500,6 +500,7 @@ export enum WorkflowActionType {
|
||||
CREATE_RECORD = 'CREATE_RECORD',
|
||||
DELAY = 'DELAY',
|
||||
DELETE_RECORD = 'DELETE_RECORD',
|
||||
DRAFT_EMAIL = 'DRAFT_EMAIL',
|
||||
EMPTY = 'EMPTY',
|
||||
FILTER = 'FILTER',
|
||||
FIND_RECORDS = 'FIND_RECORDS',
|
||||
|
||||
@@ -9,6 +9,18 @@ export const useCopyToClipboard = () => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const copyToClipboard = async (valueAsString: string, message?: string) => {
|
||||
if (!window.isSecureContext) {
|
||||
enqueueErrorSnackBar({
|
||||
message: t`Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying.`,
|
||||
options: {
|
||||
icon: <IconExclamationCircle size={16} color="red" />,
|
||||
duration: 6000,
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(valueAsString);
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ msgstr "(gekies: {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -381,6 +382,11 @@ msgstr "{selectedCount} brontipes"
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "{serviceLabel}-diens is onbereikbaar"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -642,7 +648,7 @@ msgstr "Toeganklik in jou funksie via process.env.KEY"
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "Rekening"
|
||||
@@ -780,6 +786,11 @@ msgstr "Voeg 'n nodus by"
|
||||
msgid "Add a record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -794,7 +805,7 @@ msgstr "Voeg 'n Sneller by"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "Voeg rekening by"
|
||||
@@ -806,18 +817,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "Voeg Goedgekeurde Toegangsdomein by"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "Voeg Blokkie By"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr ""
|
||||
|
||||
@@ -1146,7 +1157,7 @@ msgid "Advanced objects"
|
||||
msgstr "Gevorderde voorwerpe"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
@@ -1824,6 +1835,7 @@ msgstr "Oplopend"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1831,7 +1843,7 @@ msgid "Ask AI"
|
||||
msgstr "Vra AI"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1956,7 +1968,7 @@ msgid "Attach files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "Aanhegsels"
|
||||
|
||||
@@ -2063,6 +2075,11 @@ msgstr "Beskikbaarheid"
|
||||
msgid "Available"
|
||||
msgstr "Beskikbaar"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2122,7 +2139,7 @@ msgid "Base Credits"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr ""
|
||||
|
||||
@@ -2180,7 +2197,7 @@ msgid "Blue"
|
||||
msgstr "Blou"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "Inhoud"
|
||||
|
||||
@@ -2307,6 +2324,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "Kalender"
|
||||
@@ -2359,6 +2377,11 @@ msgstr "Kalender aansig"
|
||||
msgid "Calendars"
|
||||
msgstr "Kalenders"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2469,13 +2492,13 @@ msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "Verander Kleur"
|
||||
|
||||
@@ -2495,11 +2518,6 @@ msgstr "Verander nodustipe"
|
||||
msgid "Change Password"
|
||||
msgstr "Verander Wagwoord"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "Verander Plan"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2700,6 +2718,11 @@ msgstr "Kliënt geheime"
|
||||
msgid "Client Settings"
|
||||
msgstr "Kliëntinstellings"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2742,6 +2765,7 @@ msgstr "Kodeer jou funksie"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3076,6 +3100,11 @@ msgstr "Konteksrekords"
|
||||
msgid "Context size"
|
||||
msgstr "Konteksgrootte"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3291,11 +3320,6 @@ msgstr "Tel unieke waardes"
|
||||
msgid "Country"
|
||||
msgstr "Land"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "Landkode"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4016,7 +4040,6 @@ msgstr "verwyder"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4035,6 +4058,7 @@ msgstr "verwyder"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4227,6 +4251,12 @@ msgstr "Verwyder jou hele werkruimte"
|
||||
msgid "Deleted"
|
||||
msgstr "Verwyder"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4699,6 +4729,7 @@ msgstr ""
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4727,7 +4758,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "E-pos na knipbord gekopieer"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "E-posredigeerder"
|
||||
|
||||
@@ -4809,6 +4840,7 @@ msgstr "E-posdomeine"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "E-posse"
|
||||
|
||||
@@ -4860,6 +4892,7 @@ msgstr "Leeg"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4880,6 +4913,7 @@ msgstr "Leë Inboks"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4978,22 +5012,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "Voer reeks items of veranderlike-uitdrukking in"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "Voer e-posonderwerp in"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
@@ -5075,6 +5109,11 @@ msgstr "Voer toetswaarde in"
|
||||
msgid "Enter text"
|
||||
msgstr "Voer teks in"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5471,6 +5510,7 @@ msgstr "Verlaat Instellings"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5822,7 +5862,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "Kon nie lêer oplaaai nie: {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "Kon nie beeld opgelaai word nie: "
|
||||
|
||||
@@ -6001,6 +6041,11 @@ msgstr ""
|
||||
msgid "File URL is not defined"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6104,6 +6149,7 @@ msgstr "Voornaam kan nie leeg wees nie"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "Vloei"
|
||||
@@ -6569,6 +6615,11 @@ msgstr "Versteek groep {groupValue}"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "Versteek versteekte groepe"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6880,6 +6931,7 @@ msgstr "Inligting"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "Invoer"
|
||||
|
||||
@@ -7937,6 +7989,11 @@ msgstr "Maksimum reeks"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "Maksimum e-posadresse"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8122,6 +8179,11 @@ msgstr "Minute"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "Minute tussen snellers"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8634,6 +8696,11 @@ msgstr "Geen beskikbare velde om te kies nie"
|
||||
msgid "No body"
|
||||
msgstr "Geen inhoud"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8664,7 +8731,6 @@ msgstr "Geen konteks is vir hierdie versoek voorsien nie"
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "Geen land nie"
|
||||
|
||||
@@ -9040,7 +9106,7 @@ msgstr "Node"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9102,7 +9168,13 @@ msgstr "Nie gedeel deur {notSharedByFullName} nie"
|
||||
msgid "Not synced"
|
||||
msgstr "Nie gesinkroniseer nie"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "Notas"
|
||||
@@ -9480,6 +9552,11 @@ msgstr ""
|
||||
msgid "Organization"
|
||||
msgstr "Organisasie"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9538,6 +9615,7 @@ msgstr "Onderbreking"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10039,6 +10117,11 @@ msgstr "Privaatheidsbeleid"
|
||||
msgid "Pro"
|
||||
msgstr "Pro"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10217,6 +10300,11 @@ msgstr "Lees dokumentasie"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11098,9 +11186,9 @@ msgstr ""
|
||||
msgid "Searched the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
@@ -11108,9 +11196,9 @@ msgstr ""
|
||||
msgid "Searching the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
@@ -11449,7 +11537,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "Stuur 'n uitnodiging e-pos na jou span"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "Stuur e-pos"
|
||||
@@ -11894,6 +11981,14 @@ msgstr "Spasies en komma - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "Spaans"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12050,7 +12145,7 @@ msgid "subheading"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Onderwerp"
|
||||
|
||||
@@ -12372,6 +12467,7 @@ msgid "Task Title"
|
||||
msgstr "Taaktitel"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "Take"
|
||||
@@ -12571,6 +12667,11 @@ msgstr "Daar is geen gekoppelde aktiwiteit by hierdie rekord nie."
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "Daar was 'n fout terwyl die wagwoord opgedateer is."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12586,6 +12687,11 @@ msgstr "derde"
|
||||
msgid "Third"
|
||||
msgstr "Derde"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12753,6 +12859,11 @@ msgstr "Dit sal jou twee-faktor-verifikasiemetode permanent uitvee.<0/>Aangesien
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "Dit sal die databasiswaarde na omgewing/verstekwaarde herstel. Die databasis oorskryding sal verwyder word en die stelsel sal die omgewingsinstellings gebruik."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12784,10 +12895,16 @@ msgid "Time zone"
|
||||
msgstr "Tydsone"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "Tydlyn"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12816,7 +12933,7 @@ msgid "title"
|
||||
msgstr "titel"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -13099,6 +13216,11 @@ msgstr "Twee-faktor magtiging-setup suksesvol voltooi!"
|
||||
msgid "Type"
|
||||
msgstr "Tipe"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13223,6 +13345,12 @@ msgstr "Onbekende veld"
|
||||
msgid "Unknown file"
|
||||
msgstr "Onbekende lêer"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13255,6 +13383,7 @@ msgstr ""
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13280,7 +13409,7 @@ msgid "Untitled role"
|
||||
msgstr "Ongenoemde rol"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "Ongenoemde Werkvloei"
|
||||
@@ -13387,7 +13516,7 @@ msgstr "Laai lêer op"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "Laai lêer op"
|
||||
|
||||
@@ -13691,8 +13820,6 @@ msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13948,6 +14075,11 @@ msgstr ""
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
@@ -106,6 +106,7 @@ msgstr "(المحدد: {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -381,6 +382,11 @@ msgstr "{selectedCount, plural, zero {لا أنواع مصادر} one {نوع م
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "خدمة {serviceLabel} غير قابلة للوصول"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -642,7 +648,7 @@ msgstr "يمكن الوصول إليه في دالتك عبر process.env.KEY"
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "الحساب"
|
||||
@@ -780,6 +786,11 @@ msgstr "إضافة عقدة"
|
||||
msgid "Add a record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -794,7 +805,7 @@ msgstr "إضافة مُشغِل"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "إضافة حساب"
|
||||
@@ -806,18 +817,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "إضافة نطاق وصول معتمد"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "إضافة بلوك"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr ""
|
||||
|
||||
@@ -1146,7 +1157,7 @@ msgid "Advanced objects"
|
||||
msgstr "كائنات متقدمة"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
@@ -1824,6 +1835,7 @@ msgstr "تصاعدي"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1831,7 +1843,7 @@ msgid "Ask AI"
|
||||
msgstr "اسأل الذكاء الاصطناعي"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1956,7 +1968,7 @@ msgid "Attach files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "المرفقات"
|
||||
|
||||
@@ -2063,6 +2075,11 @@ msgstr "التوفر"
|
||||
msgid "Available"
|
||||
msgstr "متاح"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2122,7 +2139,7 @@ msgid "Base Credits"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr ""
|
||||
|
||||
@@ -2180,7 +2197,7 @@ msgid "Blue"
|
||||
msgstr "أزرق"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "النص"
|
||||
|
||||
@@ -2307,6 +2324,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "تقويم"
|
||||
@@ -2359,6 +2377,11 @@ msgstr "عرض التقويم"
|
||||
msgid "Calendars"
|
||||
msgstr "التقاويم"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2469,13 +2492,13 @@ msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "تغيير اللون"
|
||||
|
||||
@@ -2495,11 +2518,6 @@ msgstr "تغيير نوع العقدة"
|
||||
msgid "Change Password"
|
||||
msgstr "تغيير كلمة السر"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "تغيير الخطة"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2700,6 +2718,11 @@ msgstr "سر العميل"
|
||||
msgid "Client Settings"
|
||||
msgstr "إعدادات العميل"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2742,6 +2765,7 @@ msgstr "برمج الوظيفة الخاصة بك"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3076,6 +3100,11 @@ msgstr "سجلات السياق"
|
||||
msgid "Context size"
|
||||
msgstr "حجم السياق"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3291,11 +3320,6 @@ msgstr "عدّ القيم الفريدة"
|
||||
msgid "Country"
|
||||
msgstr "البلد"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "رمز البلد"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4016,7 +4040,6 @@ msgstr "حذف"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4035,6 +4058,7 @@ msgstr "حذف"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4227,6 +4251,12 @@ msgstr "حذف مساحة العمل بشكل كامل"
|
||||
msgid "Deleted"
|
||||
msgstr "تم الحذف"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4699,6 +4729,7 @@ msgstr ""
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4727,7 +4758,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "تم نسخ البريد الإلكتروني إلى الحافظة"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "محرر البريد الإلكتروني"
|
||||
|
||||
@@ -4809,6 +4840,7 @@ msgstr "نطاقات البريد الإلكتروني"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "رسائل البريد الإلكتروني"
|
||||
|
||||
@@ -4860,6 +4892,7 @@ msgstr "فارغ"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4880,6 +4913,7 @@ msgstr "صندوق الوارد فارغ"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4978,22 +5012,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "أدخل مجموعة من العناصر أو تعبير متغير"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "أدخل موضوع البريد الإلكتروني"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
@@ -5075,6 +5109,11 @@ msgstr "أدخل قيمة الاختبار"
|
||||
msgid "Enter text"
|
||||
msgstr "أدخل نصًا"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5471,6 +5510,7 @@ msgstr "خروج من الإعدادات"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5822,7 +5862,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "فشل في تحميل الملف: {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "فشل في تحميل الصورة: "
|
||||
|
||||
@@ -6001,6 +6041,11 @@ msgstr ""
|
||||
msgid "File URL is not defined"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6104,6 +6149,7 @@ msgstr "لا يمكن أن يكون الاسم الأول فارغًا"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "تدفق"
|
||||
@@ -6569,6 +6615,11 @@ msgstr "إخفاء المجموعة {groupValue}"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "إخفاء المجموعات المخفية"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6880,6 +6931,7 @@ msgstr "معلومات"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "إدخال"
|
||||
|
||||
@@ -7937,6 +7989,11 @@ msgstr "المدى الأقصى"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "الحد الأقصى لعناوين البريد الإلكتروني"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8122,6 +8179,11 @@ msgstr "دقائق"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "دقائق بين المشغلات"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8634,6 +8696,11 @@ msgstr "لا توجد حقول متاحة للاختيار"
|
||||
msgid "No body"
|
||||
msgstr "لا يوجد متن"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8664,7 +8731,6 @@ msgstr "لم يتم توفير سياق لهذا الطلب"
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "لا دولة"
|
||||
|
||||
@@ -9040,7 +9106,7 @@ msgstr "عقدة"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9102,7 +9168,13 @@ msgstr "لم تتم المشاركة من قِبَل {notSharedByFullName}"
|
||||
msgid "Not synced"
|
||||
msgstr "غير متزامن"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "الملاحظات"
|
||||
@@ -9480,6 +9552,11 @@ msgstr ""
|
||||
msgid "Organization"
|
||||
msgstr "المؤسسة"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9538,6 +9615,7 @@ msgstr "انقطاع"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10039,6 +10117,11 @@ msgstr "\\\\"
|
||||
msgid "Pro"
|
||||
msgstr "محترف"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10217,6 +10300,11 @@ msgstr "اقرأ الوثائق"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11098,9 +11186,9 @@ msgstr ""
|
||||
msgid "Searched the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
@@ -11108,9 +11196,9 @@ msgstr ""
|
||||
msgid "Searching the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
@@ -11449,7 +11537,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "\\\\"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "إرسال البريد الإلكتروني"
|
||||
@@ -11894,6 +11981,14 @@ msgstr "المسافات والفاصلة - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "الإسبانية"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12050,7 +12145,7 @@ msgid "subheading"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "الموضوع"
|
||||
|
||||
@@ -12372,6 +12467,7 @@ msgid "Task Title"
|
||||
msgstr "عنوان المهمة"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "المهام"
|
||||
@@ -12571,6 +12667,11 @@ msgstr "لا توجد أنشطة مرتبطة بهذا السجل."
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "حدث خطأ أثناء تحديث كلمة المرور."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12586,6 +12687,11 @@ msgstr "ثالث"
|
||||
msgid "Third"
|
||||
msgstr "ثالث"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12753,6 +12859,11 @@ msgstr "سيؤدي ذلك إلى حذف طريقة المصادقة الثنائ
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "سيؤدي هذا إلى إعادة قيمة قاعدة البيانات إلى البيئة/القيمة الافتراضية. سيتم إزالة تجاوز قاعدة البيانات وسيستخدم النظام إعدادات البيئة."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12784,10 +12895,16 @@ msgid "Time zone"
|
||||
msgstr "المنطقة الزمنية"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "الجدول الزمني"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12816,7 +12933,7 @@ msgid "title"
|
||||
msgstr "العنوان"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -13099,6 +13216,11 @@ msgstr "تم إكمال إعداد المصادقة الثنائية بنجاح!
|
||||
msgid "Type"
|
||||
msgstr "النوع"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13223,6 +13345,12 @@ msgstr "حقل غير معروف"
|
||||
msgid "Unknown file"
|
||||
msgstr "ملف غير معروف"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13255,6 +13383,7 @@ msgstr ""
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13280,7 +13409,7 @@ msgid "Untitled role"
|
||||
msgstr "دور بدون عنوان"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "تدفق عمل بدون عنوان"
|
||||
@@ -13387,7 +13516,7 @@ msgstr "رفع الملف"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "رفع الملف"
|
||||
|
||||
@@ -13691,8 +13820,6 @@ msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13946,6 +14073,11 @@ msgstr ""
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
@@ -106,6 +106,7 @@ msgstr "(seleccionada: {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -381,6 +382,11 @@ msgstr "{selectedCount} tipus d'origen"
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "El servei {serviceLabel} és inaccessible"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -642,7 +648,7 @@ msgstr "Accessible a la teva funció mitjançant process.env.KEY"
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "Compte"
|
||||
@@ -780,6 +786,11 @@ msgstr "Afegeix un node"
|
||||
msgid "Add a record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -794,7 +805,7 @@ msgstr "Afegeix un desencadenant"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "Afegeix compte"
|
||||
@@ -806,18 +817,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "Afegeix un domini d'accés aprovat"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "Afegeix Bloc"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr ""
|
||||
|
||||
@@ -1146,7 +1157,7 @@ msgid "Advanced objects"
|
||||
msgstr "Objectes avançats"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
@@ -1824,6 +1835,7 @@ msgstr "Ascendent"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1831,7 +1843,7 @@ msgid "Ask AI"
|
||||
msgstr "Pregunta a l'IA"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1956,7 +1968,7 @@ msgid "Attach files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "Adjunts"
|
||||
|
||||
@@ -2063,6 +2075,11 @@ msgstr "Disponibilitat"
|
||||
msgid "Available"
|
||||
msgstr "Disponible"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2122,7 +2139,7 @@ msgid "Base Credits"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr ""
|
||||
|
||||
@@ -2180,7 +2197,7 @@ msgid "Blue"
|
||||
msgstr "Blau"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "Cos"
|
||||
|
||||
@@ -2307,6 +2324,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "Calendari"
|
||||
@@ -2359,6 +2377,11 @@ msgstr "Vista de calendari"
|
||||
msgid "Calendars"
|
||||
msgstr "Calendaris"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2469,13 +2492,13 @@ msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "Canvia Color"
|
||||
|
||||
@@ -2495,11 +2518,6 @@ msgstr "Canvia el tipus de node"
|
||||
msgid "Change Password"
|
||||
msgstr "Canvia la contrasenya"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "Canviar Pla"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2700,6 +2718,11 @@ msgstr "Secret del client"
|
||||
msgid "Client Settings"
|
||||
msgstr "Configuració del client"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2742,6 +2765,7 @@ msgstr "Programar la teva funció"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3076,6 +3100,11 @@ msgstr "Registres de context"
|
||||
msgid "Context size"
|
||||
msgstr "Mida del context"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3291,11 +3320,6 @@ msgstr "Compta valors únics"
|
||||
msgid "Country"
|
||||
msgstr "País"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "Codi de país"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4016,7 +4040,6 @@ msgstr "elimina"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4035,6 +4058,7 @@ msgstr "elimina"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4227,6 +4251,12 @@ msgstr "Esborrar tot l'espai de treball"
|
||||
msgid "Deleted"
|
||||
msgstr "Eliminat"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4699,6 +4729,7 @@ msgstr ""
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4727,7 +4758,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "Correu electrònic copiat al porta-retalls"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "Editor de correu electrònic"
|
||||
|
||||
@@ -4809,6 +4840,7 @@ msgstr "Dominis de correu"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "Correus electrònics"
|
||||
|
||||
@@ -4860,6 +4892,7 @@ msgstr "Buit"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4880,6 +4913,7 @@ msgstr "Bústia buida"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4978,22 +5012,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "Introduïu una matriu d'elements o una expressió de variable"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "Introdueix l'assumpte del correu"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
@@ -5075,6 +5109,11 @@ msgstr "Introdueix el valor de prova"
|
||||
msgid "Enter text"
|
||||
msgstr "Introdueix el text"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5471,6 +5510,7 @@ msgstr "Sortir de la configuració"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5822,7 +5862,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "No s'ha pogut carregar el fitxer: {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "Error en pujar la imatge: "
|
||||
|
||||
@@ -6001,6 +6041,11 @@ msgstr ""
|
||||
msgid "File URL is not defined"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6104,6 +6149,7 @@ msgstr "El nom no pot estar buit"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "Flux"
|
||||
@@ -6569,6 +6615,11 @@ msgstr "Amaga el grup {groupValue}"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "Amaga grups ocults"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6880,6 +6931,7 @@ msgstr "Informació"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "Entrada"
|
||||
|
||||
@@ -7937,6 +7989,11 @@ msgstr "Rang màxim"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "Quantitat màxima de correus electrònics"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8122,6 +8179,11 @@ msgstr "Minuts"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "Minuts entre els activadors"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8634,6 +8696,11 @@ msgstr "No hi ha camps disponibles per seleccionar"
|
||||
msgid "No body"
|
||||
msgstr "Sense cos"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8664,7 +8731,6 @@ msgstr "No s'ha proporcionat cap context per a aquesta sol·licitud"
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "Sense país"
|
||||
|
||||
@@ -9040,7 +9106,7 @@ msgstr "Node"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9102,7 +9168,13 @@ msgstr "No compartit per {notSharedByFullName}"
|
||||
msgid "Not synced"
|
||||
msgstr "No sincronitzat"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "Notes"
|
||||
@@ -9480,6 +9552,11 @@ msgstr ""
|
||||
msgid "Organization"
|
||||
msgstr "Organització"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9538,6 +9615,7 @@ msgstr "Interrupció"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10039,6 +10117,11 @@ msgstr "Política de Privacitat"
|
||||
msgid "Pro"
|
||||
msgstr "Pro"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10217,6 +10300,11 @@ msgstr "Llegeix la documentació"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11098,9 +11186,9 @@ msgstr ""
|
||||
msgid "Searched the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
@@ -11108,9 +11196,9 @@ msgstr ""
|
||||
msgid "Searching the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
@@ -11449,7 +11537,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "Envia un correu d'invitació al teu equip"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "Enviar correu electrònic"
|
||||
@@ -11894,6 +11981,14 @@ msgstr "Espais i coma - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "Espanyol"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12050,7 +12145,7 @@ msgid "subheading"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Assumpte"
|
||||
|
||||
@@ -12372,6 +12467,7 @@ msgid "Task Title"
|
||||
msgstr "Títol de la tasca"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "Tasques"
|
||||
@@ -12571,6 +12667,11 @@ msgstr "No hi ha cap activitat associada amb aquest registre."
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "S'ha produït un error en actualitzar la contrasenya."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12586,6 +12687,11 @@ msgstr "tercer"
|
||||
msgid "Third"
|
||||
msgstr "Tercer"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12753,6 +12859,11 @@ msgstr "Això suprimirà permanentment el teu mètode d'autenticació de dos fac
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "Això revertirà el valor de la base de dades al valor d'entorn/predeterminat. L'anul·lació de la base de dades serà eliminada i el sistema utilitzarà la configuració de l'entorn."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12784,10 +12895,16 @@ msgid "Time zone"
|
||||
msgstr "Zona horària"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "Cronologia"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12816,7 +12933,7 @@ msgid "title"
|
||||
msgstr "títol"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -13099,6 +13216,11 @@ msgstr "Configuració de l'autenticació de dos factors completada amb èxit!"
|
||||
msgid "Type"
|
||||
msgstr "Tipus"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13223,6 +13345,12 @@ msgstr "Camp desconegut"
|
||||
msgid "Unknown file"
|
||||
msgstr "Fitxer desconegut"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13255,6 +13383,7 @@ msgstr ""
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13280,7 +13409,7 @@ msgid "Untitled role"
|
||||
msgstr "Rol sense títol"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "Flux de treball sense títol"
|
||||
@@ -13387,7 +13516,7 @@ msgstr "Carrega fitxer"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "Carrega fitxer"
|
||||
|
||||
@@ -13691,8 +13820,6 @@ msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13948,6 +14075,11 @@ msgstr ""
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
@@ -106,6 +106,7 @@ msgstr "(vybráno: {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -381,6 +382,11 @@ msgstr "{selectedCount} typů zdrojů"
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "Služba {serviceLabel} je nedostupná"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -642,7 +648,7 @@ msgstr "Dostupné ve vaší funkci přes process.env.KEY"
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "Účet"
|
||||
@@ -780,6 +786,11 @@ msgstr "Přidat uzel"
|
||||
msgid "Add a record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -794,7 +805,7 @@ msgstr "Přidat spouštěč"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "Přidat účet"
|
||||
@@ -806,18 +817,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "Přidat schválenou přístupovou doménu"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "Přidat blok"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr ""
|
||||
|
||||
@@ -1146,7 +1157,7 @@ msgid "Advanced objects"
|
||||
msgstr "Pokročilé objekty"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
@@ -1824,6 +1835,7 @@ msgstr "Vzestupně"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1831,7 +1843,7 @@ msgid "Ask AI"
|
||||
msgstr "Zeptejte se AI"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1956,7 +1968,7 @@ msgid "Attach files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "Přílohy"
|
||||
|
||||
@@ -2063,6 +2075,11 @@ msgstr "Dostupnost"
|
||||
msgid "Available"
|
||||
msgstr "Dostupný"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2122,7 +2139,7 @@ msgid "Base Credits"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr ""
|
||||
|
||||
@@ -2180,7 +2197,7 @@ msgid "Blue"
|
||||
msgstr "Modrá"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "Text zprávy"
|
||||
|
||||
@@ -2307,6 +2324,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "Kalendář"
|
||||
@@ -2359,6 +2377,11 @@ msgstr "Kalendářní zobrazení"
|
||||
msgid "Calendars"
|
||||
msgstr "Kalendáře"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2469,13 +2492,13 @@ msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "Změnit barvu"
|
||||
|
||||
@@ -2495,11 +2518,6 @@ msgstr "Změnit typ uzlu"
|
||||
msgid "Change Password"
|
||||
msgstr "Změnit heslo"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "Změnit plán"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2700,6 +2718,11 @@ msgstr "Klientský tajný klíč"
|
||||
msgid "Client Settings"
|
||||
msgstr "Nastavení klienta"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2742,6 +2765,7 @@ msgstr "Naprogramujte svou funkci"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3076,6 +3100,11 @@ msgstr "Kontextové záznamy"
|
||||
msgid "Context size"
|
||||
msgstr "Velikost kontextu"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3291,11 +3320,6 @@ msgstr "Počet unikátních hodnot"
|
||||
msgid "Country"
|
||||
msgstr "Země"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "Kód země"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4016,7 +4040,6 @@ msgstr "smazat"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4035,6 +4058,7 @@ msgstr "smazat"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4227,6 +4251,12 @@ msgstr "Smazat celý pracovní prostor"
|
||||
msgid "Deleted"
|
||||
msgstr "Smazáno"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4699,6 +4729,7 @@ msgstr ""
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4727,7 +4758,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "Email zkopírován do schránky"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "Editor e-mailu"
|
||||
|
||||
@@ -4809,6 +4840,7 @@ msgstr "E-mailové domény"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "E-maily"
|
||||
|
||||
@@ -4860,6 +4892,7 @@ msgstr "Prázdné"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4880,6 +4913,7 @@ msgstr "Prázdná schránka"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4978,22 +5012,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "Zadejte pole položek nebo výraz proměnné"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "Zadejte předmět e-mailu"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
@@ -5075,6 +5109,11 @@ msgstr "Zadejte testovací hodnotu"
|
||||
msgid "Enter text"
|
||||
msgstr "Zadejte text"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5471,6 +5510,7 @@ msgstr "Opustit nastavení"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5822,7 +5862,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "Nepodařilo se nahrát soubor: {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "Nelze nahrát obrázek: "
|
||||
|
||||
@@ -6001,6 +6041,11 @@ msgstr ""
|
||||
msgid "File URL is not defined"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6104,6 +6149,7 @@ msgstr "Křestní jméno nesmí být prázdné"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "Tok"
|
||||
@@ -6569,6 +6615,11 @@ msgstr "Skrýt skupinu {groupValue}"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "Skrýt skryté skupiny"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6880,6 +6931,7 @@ msgstr "Informace"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "Vstup"
|
||||
|
||||
@@ -7937,6 +7989,11 @@ msgstr "Maximální rozsah"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "Maximální počet emailových adres"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8122,6 +8179,11 @@ msgstr "Minuty"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "Minuty mezi spouštěči"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8634,6 +8696,11 @@ msgstr "Žádná dostupná pole k výběru"
|
||||
msgid "No body"
|
||||
msgstr "Žádné tělo"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8664,7 +8731,6 @@ msgstr "Pro tento požadavek nebyl poskytnut žádný kontext"
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "Žádná země"
|
||||
|
||||
@@ -9040,7 +9106,7 @@ msgstr "Uzel"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9102,7 +9168,13 @@ msgstr "Nesdíleno uživatelem {notSharedByFullName}"
|
||||
msgid "Not synced"
|
||||
msgstr "Nesynchronizováno"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "Poznámky"
|
||||
@@ -9480,6 +9552,11 @@ msgstr ""
|
||||
msgid "Organization"
|
||||
msgstr "Organizace"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9538,6 +9615,7 @@ msgstr "Výpadek"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10039,6 +10117,11 @@ msgstr "Zásady ochrany osobních údajů"
|
||||
msgid "Pro"
|
||||
msgstr "Pro"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10217,6 +10300,11 @@ msgstr "Přečtěte si dokumentaci"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11098,9 +11186,9 @@ msgstr ""
|
||||
msgid "Searched the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
@@ -11108,9 +11196,9 @@ msgstr ""
|
||||
msgid "Searching the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
@@ -11449,7 +11537,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "Pošlete pozvánku e-mailem vašemu týmu"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "Odeslat e-mail"
|
||||
@@ -11894,6 +11981,14 @@ msgstr "Mezery a čárka - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "Španělština"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12050,7 +12145,7 @@ msgid "subheading"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Předmět"
|
||||
|
||||
@@ -12372,6 +12467,7 @@ msgid "Task Title"
|
||||
msgstr "Název úkolu"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "Úkoly"
|
||||
@@ -12571,6 +12667,11 @@ msgstr "S tímto záznamem není spojena žádná aktivita."
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "Během aktualizace hesla došlo k chybě."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12586,6 +12687,11 @@ msgstr "třetí"
|
||||
msgid "Third"
|
||||
msgstr "Třetí"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12753,6 +12859,11 @@ msgstr "Tímto bude vaše metoda dvoufaktorového ověřování trvale odstraně
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "Toto obnoví hodnotu databáze na hodnotu prostředí/výchozí hodnotu. Přepis databáze bude odstraněn a systém použije nastavení prostředí."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12784,10 +12895,16 @@ msgid "Time zone"
|
||||
msgstr "Časové pásmo"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "Časová osa"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12816,7 +12933,7 @@ msgid "title"
|
||||
msgstr "název"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -13099,6 +13216,11 @@ msgstr "Nastavení dvoufaktorového ověřování bylo úspěšně dokončeno!"
|
||||
msgid "Type"
|
||||
msgstr "Typ"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13223,6 +13345,12 @@ msgstr "Neznámé pole"
|
||||
msgid "Unknown file"
|
||||
msgstr "Neznámý soubor"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13255,6 +13383,7 @@ msgstr ""
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13280,7 +13409,7 @@ msgid "Untitled role"
|
||||
msgstr "Nepojmenovaná role"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "Nepojmenovaný Workflow"
|
||||
@@ -13387,7 +13516,7 @@ msgstr "Nahrát soubor"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "Nahrát soubor"
|
||||
|
||||
@@ -13691,8 +13820,6 @@ msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13948,6 +14075,11 @@ msgstr ""
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
@@ -106,6 +106,7 @@ msgstr "(valgt: {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -381,6 +382,11 @@ msgstr "{selectedCount} kildetyper"
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "Tjenesten {serviceLabel} kan ikke nås"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -642,7 +648,7 @@ msgstr "Tilgængelig i din funktion via process.env.KEY"
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "Konto"
|
||||
@@ -780,6 +786,11 @@ msgstr "Tilføj en node"
|
||||
msgid "Add a record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -794,7 +805,7 @@ msgstr "Tilføj en udløser"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "Tilføj konto"
|
||||
@@ -806,18 +817,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "Tilføj godkendt adgangsdomæne"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "Tilføj blok"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr ""
|
||||
|
||||
@@ -1146,7 +1157,7 @@ msgid "Advanced objects"
|
||||
msgstr "Avancerede objekter"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
@@ -1824,6 +1835,7 @@ msgstr "Stigende"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1831,7 +1843,7 @@ msgid "Ask AI"
|
||||
msgstr "Spørg AI"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1956,7 +1968,7 @@ msgid "Attach files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "Vedhæftninger"
|
||||
|
||||
@@ -2063,6 +2075,11 @@ msgstr "Tilgængelighed"
|
||||
msgid "Available"
|
||||
msgstr "Tilgængelig"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2122,7 +2139,7 @@ msgid "Base Credits"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr ""
|
||||
|
||||
@@ -2180,7 +2197,7 @@ msgid "Blue"
|
||||
msgstr "Blå"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "Indhold"
|
||||
|
||||
@@ -2307,6 +2324,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "Kalender"
|
||||
@@ -2359,6 +2377,11 @@ msgstr "Kalendervisning"
|
||||
msgid "Calendars"
|
||||
msgstr "Kalendere"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2469,13 +2492,13 @@ msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "Skift farve"
|
||||
|
||||
@@ -2495,11 +2518,6 @@ msgstr "Skift nodetype"
|
||||
msgid "Change Password"
|
||||
msgstr "Skift kodeord"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "Ændre Pakke"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2700,6 +2718,11 @@ msgstr "Klienthemmelighed"
|
||||
msgid "Client Settings"
|
||||
msgstr "Klientindstillinger"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2742,6 +2765,7 @@ msgstr "Kodedin funktion"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3076,6 +3100,11 @@ msgstr "Kontekstposter"
|
||||
msgid "Context size"
|
||||
msgstr "Kontekststørrelse"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3291,11 +3320,6 @@ msgstr "Tæl unikke værdier"
|
||||
msgid "Country"
|
||||
msgstr "Land"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "Landekode"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4016,7 +4040,6 @@ msgstr "slet"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4035,6 +4058,7 @@ msgstr "slet"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4227,6 +4251,12 @@ msgstr "Slet hele dit arbejdsområde"
|
||||
msgid "Deleted"
|
||||
msgstr "Slettet"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4699,6 +4729,7 @@ msgstr ""
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4727,7 +4758,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "Email kopieret til udklipsholder"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "Email Editor"
|
||||
|
||||
@@ -4809,6 +4840,7 @@ msgstr "E-mail-domæner"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "E-mails"
|
||||
|
||||
@@ -4860,6 +4892,7 @@ msgstr "Tom"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4880,6 +4913,7 @@ msgstr "Tom Indbakke"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4978,22 +5012,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "Indtast række af elementer eller variabeludtryk"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "Indtast emne for e-mail"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
@@ -5075,6 +5109,11 @@ msgstr "Indtast testværdi"
|
||||
msgid "Enter text"
|
||||
msgstr "Indtast tekst"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5471,6 +5510,7 @@ msgstr "Forlad indstillinger"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5822,7 +5862,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "Kunne ikke uploade fil: {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "Kunne ikke uploade billede: "
|
||||
|
||||
@@ -6001,6 +6041,11 @@ msgstr ""
|
||||
msgid "File URL is not defined"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6104,6 +6149,7 @@ msgstr "Fornavn må ikke være tomt"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "Strøm"
|
||||
@@ -6569,6 +6615,11 @@ msgstr "Skjul gruppe {groupValue}"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "Skjul skjulte grupper"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6880,6 +6931,7 @@ msgstr "Info"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "Input"
|
||||
|
||||
@@ -7937,6 +7989,11 @@ msgstr "Maksimumsgrænse"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "Maksimalt antal e-mailadresser"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8122,6 +8179,11 @@ msgstr "Minutter"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "Minutter mellem udløsere"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8634,6 +8696,11 @@ msgstr "Ingen tilgængelige felter for at vælge"
|
||||
msgid "No body"
|
||||
msgstr "Ingen body"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8664,7 +8731,6 @@ msgstr "Der blev ikke angivet nogen kontekst for denne anmodning"
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "Intet land"
|
||||
|
||||
@@ -9040,7 +9106,7 @@ msgstr "Node"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9102,7 +9168,13 @@ msgstr "Ikke delt af {notSharedByFullName}"
|
||||
msgid "Not synced"
|
||||
msgstr "Ikke synkroniseret"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "Noter"
|
||||
@@ -9480,6 +9552,11 @@ msgstr ""
|
||||
msgid "Organization"
|
||||
msgstr "Organisation"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9538,6 +9615,7 @@ msgstr "Nedetid"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10039,6 +10117,11 @@ msgstr "Privatlivspolitik"
|
||||
msgid "Pro"
|
||||
msgstr "Pro"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10217,6 +10300,11 @@ msgstr "Læs dokumentation"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11098,9 +11186,9 @@ msgstr ""
|
||||
msgid "Searched the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
@@ -11108,9 +11196,9 @@ msgstr ""
|
||||
msgid "Searching the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
@@ -11449,7 +11537,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "Send en invitationsemail til dit team"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "Send e-mail"
|
||||
@@ -11894,6 +11981,14 @@ msgstr "Mellemrum og komma - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "Spansk"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12050,7 +12145,7 @@ msgid "subheading"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Emne"
|
||||
|
||||
@@ -12372,6 +12467,7 @@ msgid "Task Title"
|
||||
msgstr "Opgavetitel"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "Opgaver"
|
||||
@@ -12571,6 +12667,11 @@ msgstr "Der er ingen aktivitet tilknyttet denne post."
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "Der opstod en fejl under opdatering af adgangskoden."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12586,6 +12687,11 @@ msgstr "tredje"
|
||||
msgid "Third"
|
||||
msgstr "Tredje"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12755,6 +12861,11 @@ msgstr "Dette vil permanent slette din tofaktorgodkendelsesmetode.<0/>Da 2FA er
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "Dette vil gendanne databaseværdien til miljø/standardværdi. Databasetilsidesættelsen vil blive fjernet, og systemet vil bruge miljøindstillingerne."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12786,10 +12897,16 @@ msgid "Time zone"
|
||||
msgstr "Tidszone"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "Tidslinje"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12818,7 +12935,7 @@ msgid "title"
|
||||
msgstr "titel"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -13101,6 +13218,11 @@ msgstr "Opsætning af to-faktor godkendelse blev gennemført med succes!"
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13225,6 +13347,12 @@ msgstr "Ukendt felt"
|
||||
msgid "Unknown file"
|
||||
msgstr "Ukendt fil"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13257,6 +13385,7 @@ msgstr ""
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13282,7 +13411,7 @@ msgid "Untitled role"
|
||||
msgstr "Uden titel rolle"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "Uden titel workflow"
|
||||
@@ -13389,7 +13518,7 @@ msgstr "Upload fil"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "Upload fil"
|
||||
|
||||
@@ -13693,8 +13822,6 @@ msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13950,6 +14077,11 @@ msgstr ""
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
@@ -106,6 +106,7 @@ msgstr "(ausgewählt: {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -381,6 +382,11 @@ msgstr "{selectedCount} Quelltypen"
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "{serviceLabel}-Dienst ist nicht erreichbar"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -642,7 +648,7 @@ msgstr "In Ihrer Funktion über process.env.KEY zugänglich"
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "Konto"
|
||||
@@ -780,6 +786,11 @@ msgstr "Knoten hinzufügen"
|
||||
msgid "Add a record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -794,7 +805,7 @@ msgstr "Einen Auslöser hinzufügen"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "Konto hinzufügen"
|
||||
@@ -806,18 +817,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "Genehmigte Zugriffsdomäne hinzufügen"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "Block hinzufügen"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr ""
|
||||
|
||||
@@ -1146,7 +1157,7 @@ msgid "Advanced objects"
|
||||
msgstr "Erweiterte Objekte"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
@@ -1824,6 +1835,7 @@ msgstr "Aufsteigend"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1831,7 +1843,7 @@ msgid "Ask AI"
|
||||
msgstr "AI fragen"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1956,7 +1968,7 @@ msgid "Attach files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "Anhänge"
|
||||
|
||||
@@ -2063,6 +2075,11 @@ msgstr "Verfügbarkeit"
|
||||
msgid "Available"
|
||||
msgstr "Verfügbar"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2122,7 +2139,7 @@ msgid "Base Credits"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr ""
|
||||
|
||||
@@ -2180,7 +2197,7 @@ msgid "Blue"
|
||||
msgstr "Blau"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "Inhalt"
|
||||
|
||||
@@ -2307,6 +2324,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "Kalender"
|
||||
@@ -2359,6 +2377,11 @@ msgstr "Kalenderansicht"
|
||||
msgid "Calendars"
|
||||
msgstr "Kalender"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2469,13 +2492,13 @@ msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "Farbe ändern"
|
||||
|
||||
@@ -2495,11 +2518,6 @@ msgstr "Knotentyp ändern"
|
||||
msgid "Change Password"
|
||||
msgstr "Passwort ändern"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "Plan ändern"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2700,6 +2718,11 @@ msgstr "Client-Geheimnis"
|
||||
msgid "Client Settings"
|
||||
msgstr "Client-Einstellungen"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2742,6 +2765,7 @@ msgstr "Funktion programmieren"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3076,6 +3100,11 @@ msgstr "Kontextdatensätze"
|
||||
msgid "Context size"
|
||||
msgstr "Kontextgröße"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3291,11 +3320,6 @@ msgstr "Eindeutige Werte zählen"
|
||||
msgid "Country"
|
||||
msgstr "Land"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "Ländercode"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4016,7 +4040,6 @@ msgstr "löschen"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4035,6 +4058,7 @@ msgstr "löschen"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4227,6 +4251,12 @@ msgstr "Gesamten Arbeitsbereich löschen"
|
||||
msgid "Deleted"
|
||||
msgstr "Gelöscht"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4699,6 +4729,7 @@ msgstr ""
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4727,7 +4758,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "E-Mail in die Zwischenablage kopiert"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "E-Mail-Editor"
|
||||
|
||||
@@ -4809,6 +4840,7 @@ msgstr "E-Mail-Domänen"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "E-Mails"
|
||||
|
||||
@@ -4860,6 +4892,7 @@ msgstr "Leer"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4880,6 +4913,7 @@ msgstr "Leerer Posteingang"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4978,22 +5012,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "Geben Sie ein Array von Elementen oder eine Variablen-Ausdruck ein"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "Geben Sie den E-Mail-Betreff ein"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
@@ -5075,6 +5109,11 @@ msgstr "Testwert eingeben"
|
||||
msgid "Enter text"
|
||||
msgstr "Text eingeben"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5471,6 +5510,7 @@ msgstr "Einstellungen verlassen"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5822,7 +5862,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "Datei konnte nicht hochgeladen werden: {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "Fehler beim Hochladen des Bildes: "
|
||||
|
||||
@@ -6001,6 +6041,11 @@ msgstr ""
|
||||
msgid "File URL is not defined"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6104,6 +6149,7 @@ msgstr "Vorname darf nicht leer sein"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "Fluss"
|
||||
@@ -6569,6 +6615,11 @@ msgstr "Gruppe {groupValue} ausblenden"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "Verborgene Gruppen ausblenden"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6880,6 +6931,7 @@ msgstr "Informationen"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "Eingabe"
|
||||
|
||||
@@ -7937,6 +7989,11 @@ msgstr "Maximaler Bereich"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "Maximale E-Mail-Adressen"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8122,6 +8179,11 @@ msgstr "Minuten"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "Minuten zwischen Auslösern"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8634,6 +8696,11 @@ msgstr "Keine verfügbaren Felder zur Auswahl"
|
||||
msgid "No body"
|
||||
msgstr "Kein Body"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8664,7 +8731,6 @@ msgstr "Für diese Anfrage wurde kein Kontext bereitgestellt"
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "Kein Land"
|
||||
|
||||
@@ -9040,7 +9106,7 @@ msgstr "Knoten"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9102,7 +9168,13 @@ msgstr "Nicht geteilt von {notSharedByFullName}"
|
||||
msgid "Not synced"
|
||||
msgstr "Nicht synchronisiert"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "Notizen"
|
||||
@@ -9480,6 +9552,11 @@ msgstr ""
|
||||
msgid "Organization"
|
||||
msgstr "Organisation"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9538,6 +9615,7 @@ msgstr "Ausfall"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10039,6 +10117,11 @@ msgstr "Datenschutzrichtlinie"
|
||||
msgid "Pro"
|
||||
msgstr "Pro"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10217,6 +10300,11 @@ msgstr "Dokumentation lesen"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11098,9 +11186,9 @@ msgstr ""
|
||||
msgid "Searched the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
@@ -11108,9 +11196,9 @@ msgstr ""
|
||||
msgid "Searching the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
@@ -11449,7 +11537,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "Einladung per E-Mail an Ihr Team senden"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "E-Mail senden"
|
||||
@@ -11894,6 +11981,14 @@ msgstr "Leerzeichen und Komma - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "Spanisch"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12050,7 +12145,7 @@ msgid "subheading"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Betreff"
|
||||
|
||||
@@ -12372,6 +12467,7 @@ msgid "Task Title"
|
||||
msgstr "Aufgabentitel"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "Aufgaben"
|
||||
@@ -12571,6 +12667,11 @@ msgstr "Mit diesem Datensatz ist keine Aktivität verknüpft."
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "Beim Aktualisieren des Passworts ist ein Fehler aufgetreten."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12586,6 +12687,11 @@ msgstr "drittes"
|
||||
msgid "Third"
|
||||
msgstr "Drittes"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12753,6 +12859,11 @@ msgstr "Dies wird Ihre Zwei-Faktor-Authentifizierung dauerhaft löschen.<0/>Da 2
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "Dies wird den Datenbankwert auf den Umwelt-/Standardwert zurücksetzen. Der Datenbanküberschreibung wird entfernt und das System wird die Umgebungsanstellungen verwenden."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12784,10 +12895,16 @@ msgid "Time zone"
|
||||
msgstr "Zeitzone"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "Zeitleiste"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12816,7 +12933,7 @@ msgid "title"
|
||||
msgstr "titel"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -13099,6 +13216,11 @@ msgstr "Einrichtung der Zwei-Faktor-Authentifizierung erfolgreich abgeschlossen!
|
||||
msgid "Type"
|
||||
msgstr "Typ"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13223,6 +13345,12 @@ msgstr "Unbekanntes Feld"
|
||||
msgid "Unknown file"
|
||||
msgstr "Unbekannte Datei"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13255,6 +13383,7 @@ msgstr ""
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13280,7 +13409,7 @@ msgid "Untitled role"
|
||||
msgstr "Unbenannte Rolle"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "Unbenannter Workflow"
|
||||
@@ -13387,7 +13516,7 @@ msgstr "Datei hochladen"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "Datei hochladen"
|
||||
|
||||
@@ -13691,8 +13820,6 @@ msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13948,6 +14075,11 @@ msgstr ""
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
@@ -106,6 +106,7 @@ msgstr "(επιλεγμένο: {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -381,6 +382,11 @@ msgstr "{selectedCount} τύποι πηγής"
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "Η υπηρεσία {serviceLabel} είναι απρόσιτη"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -642,7 +648,7 @@ msgstr "Προσβάσιμο στη λειτουργία σας μέσω process
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "Λογαριασμός"
|
||||
@@ -780,6 +786,11 @@ msgstr "Προσθήκη κόμβου"
|
||||
msgid "Add a record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -794,7 +805,7 @@ msgstr "Προσθήκη Ενεργοποίησης"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "Προσθήκη λογαριασμού"
|
||||
@@ -806,18 +817,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "Προσθήκη Εγκεκριμένου Τομέα Πρόσβασης"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "Προσθήκη Μπλοκ"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr ""
|
||||
|
||||
@@ -1146,7 +1157,7 @@ msgid "Advanced objects"
|
||||
msgstr "Προχωρημένα αντικείμενα"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
@@ -1824,6 +1835,7 @@ msgstr "Αύξουσα"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1831,7 +1843,7 @@ msgid "Ask AI"
|
||||
msgstr "Ρώτησε την AI"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1956,7 +1968,7 @@ msgid "Attach files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "Συνημμένα"
|
||||
|
||||
@@ -2063,6 +2075,11 @@ msgstr "Διαθεσιμότητα"
|
||||
msgid "Available"
|
||||
msgstr "Διαθέσιμο"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2122,7 +2139,7 @@ msgid "Base Credits"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr ""
|
||||
|
||||
@@ -2180,7 +2197,7 @@ msgid "Blue"
|
||||
msgstr "Μπλε"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "Κείμενο"
|
||||
|
||||
@@ -2307,6 +2324,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "Ημερολόγιο"
|
||||
@@ -2359,6 +2377,11 @@ msgstr "Προβολή Ημερολογίου"
|
||||
msgid "Calendars"
|
||||
msgstr "Ημερολόγια"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2469,13 +2492,13 @@ msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "Αλλαγή Χρώματος"
|
||||
|
||||
@@ -2495,11 +2518,6 @@ msgstr "Αλλαγή τύπου κόμβου"
|
||||
msgid "Change Password"
|
||||
msgstr "Αλλαγή Κωδικού"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "Αλλαγή σχεδίου"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2700,6 +2718,11 @@ msgstr "Μυστικό Πελάτη"
|
||||
msgid "Client Settings"
|
||||
msgstr "Ρυθμίσεις Πελάτη"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2742,6 +2765,7 @@ msgstr "Κωδικοποιήστε τη λειτουργία σας"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3076,6 +3100,11 @@ msgstr "Εγγραφές πλαισίου"
|
||||
msgid "Context size"
|
||||
msgstr "Μέγεθος πλαισίου"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3291,11 +3320,6 @@ msgstr "Καταμέτρηση μοναδικών τιμών"
|
||||
msgid "Country"
|
||||
msgstr "Χώρα"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "Κωδικός χώρας"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4016,7 +4040,6 @@ msgstr "διαγραφή"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4035,6 +4058,7 @@ msgstr "διαγραφή"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4227,6 +4251,12 @@ msgstr "Διαγραφή ολόκληρου του χώρου εργασίας
|
||||
msgid "Deleted"
|
||||
msgstr "Διαγράφηκε"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4699,6 +4729,7 @@ msgstr ""
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4727,7 +4758,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "Το email αντιγράφηκε στο πρόχειρο"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "Επεξεργαστής Email"
|
||||
|
||||
@@ -4809,6 +4840,7 @@ msgstr "Περιοχές Email"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "Ηλεκτρονικά ταχυδρομεία"
|
||||
|
||||
@@ -4860,6 +4892,7 @@ msgstr "Κενό"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4880,6 +4913,7 @@ msgstr "Άδειο Γραμματοκιβώτιο"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4978,22 +5012,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "Εισάγετε έναν πίνακα αντικειμένων ή μια μεταβλητή έκφραση"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "Εισάγετε θέμα email"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
@@ -5075,6 +5109,11 @@ msgstr "Εισάγετε δοκιμαστική τιμή"
|
||||
msgid "Enter text"
|
||||
msgstr "Εισάγετε κείμενο"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5471,6 +5510,7 @@ msgstr "Έξοδος από Ρυθμίσεις"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5822,7 +5862,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "Απέτυχε η μεταφόρτωση αρχείου: {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "Αποτυχία μεταφόρτωσης εικόνας: "
|
||||
|
||||
@@ -6001,6 +6041,11 @@ msgstr ""
|
||||
msgid "File URL is not defined"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6104,6 +6149,7 @@ msgstr "Το μικρό όνομα δεν μπορεί να είναι κενό"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "Ροή"
|
||||
@@ -6569,6 +6615,11 @@ msgstr "Απόκρυψη ομάδας {groupValue}"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "Απόκρυψη κρυφών ομάδων"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6880,6 +6931,7 @@ msgstr "Πληροφορίες"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "Εισαγωγή"
|
||||
|
||||
@@ -7937,6 +7989,11 @@ msgstr "Μέγιστο εύρος"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "Μέγιστος αριθμός διευθύνσεων email"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8122,6 +8179,11 @@ msgstr "Λεπτά"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "Λεπτά μεταξύ ενεργοποιήσεων"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8634,6 +8696,11 @@ msgstr "Δεν υπάρχουν διαθέσιμα πεδία για επιλο
|
||||
msgid "No body"
|
||||
msgstr "Χωρίς σώμα"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8664,7 +8731,6 @@ msgstr "Δεν παρέχεται πλαίσιο για αυτό το αίτημ
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "Χωρίς χώρα"
|
||||
|
||||
@@ -9040,7 +9106,7 @@ msgstr "Κόμβος"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9102,7 +9168,13 @@ msgstr "Δεν κοινοποιήθηκε από τον/την {notSharedByFullN
|
||||
msgid "Not synced"
|
||||
msgstr "Δεν συγχρονίζεται"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "Σημειώματα"
|
||||
@@ -9480,6 +9552,11 @@ msgstr ""
|
||||
msgid "Organization"
|
||||
msgstr "Οργανωτικός"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9538,6 +9615,7 @@ msgstr "Διακοπή λειτουργίας"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10039,6 +10117,11 @@ msgstr "Πολιτική Απορρήτου"
|
||||
msgid "Pro"
|
||||
msgstr "Pro"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10217,6 +10300,11 @@ msgstr "Διαβάστε την τεκμηρίωση"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11098,9 +11186,9 @@ msgstr ""
|
||||
msgid "Searched the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
@@ -11108,9 +11196,9 @@ msgstr ""
|
||||
msgid "Searching the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
@@ -11449,7 +11537,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "Στείλτε ένα email πρόσκλησης στην ομάδα σας"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "Αποστολή Email"
|
||||
@@ -11896,6 +11983,14 @@ msgstr "Κενά και κόμμα - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "Ισπανικά"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12052,7 +12147,7 @@ msgid "subheading"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Θέμα"
|
||||
|
||||
@@ -12374,6 +12469,7 @@ msgid "Task Title"
|
||||
msgstr "Τίτλος εργασίας"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "Εργασίες"
|
||||
@@ -12573,6 +12669,11 @@ msgstr "Δεν υπάρχει δραστηριότητα που να σχετί
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "Παρουσιάστηκε σφάλμα κατά την ενημέρωση του κωδικού πρόσβασης."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12588,6 +12689,11 @@ msgstr "τρίτος"
|
||||
msgid "Third"
|
||||
msgstr "Τρίτος"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12757,6 +12863,11 @@ msgstr "Αυτό θα διαγράψει μόνιμα τη μέθοδο ελέγ
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "Αυτό θα επαναφέρει την τιμή της βάσης δεδομένων στην προεπιλεγμένη/τιμή περιβάλλοντος. Η υπερισχύ του περιβάλλοντος βάσης δεδομένων θα αφαιρεθεί και το σύστημα θα χρησιμοποιήσει τις ρυθμίσεις περιβάλλοντος."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12788,10 +12899,16 @@ msgid "Time zone"
|
||||
msgstr "Ζώνη ώρας"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "Χρονολόγιο"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12820,7 +12937,7 @@ msgid "title"
|
||||
msgstr "τίτλος"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -13103,6 +13220,11 @@ msgstr "Η εγκατάσταση δύο παραγοντικής ταυτοπο
|
||||
msgid "Type"
|
||||
msgstr "Τύπος"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13227,6 +13349,12 @@ msgstr "Άγνωστο πεδίο"
|
||||
msgid "Unknown file"
|
||||
msgstr "Άγνωστο αρχείο"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13259,6 +13387,7 @@ msgstr ""
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13284,7 +13413,7 @@ msgid "Untitled role"
|
||||
msgstr "Χωρίς τίτλο ρόλος"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "Άτιτλη Εργασία"
|
||||
@@ -13391,7 +13520,7 @@ msgstr "Ανέβασμα αρχείου"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "Ανέβασμα αρχείου"
|
||||
|
||||
@@ -13695,8 +13824,6 @@ msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13952,6 +14079,11 @@ msgstr ""
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
@@ -101,6 +101,7 @@ msgstr "(selected: {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -376,6 +377,11 @@ msgstr "{selectedCount} source types"
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "{serviceLabel} service is unreachable"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr "{stepCount, plural, one {# step} other {# steps}}"
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -637,7 +643,7 @@ msgstr "Accessible in your function via process.env.KEY"
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "Account"
|
||||
@@ -775,6 +781,11 @@ msgstr "Add a node"
|
||||
msgid "Add a record"
|
||||
msgstr "Add a record"
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr "Add a Section"
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -789,7 +800,7 @@ msgstr "Add a Trigger"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "Add account"
|
||||
@@ -801,18 +812,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "Add Approved Access Domain"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr "Add BCC"
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "Add Block"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr "Add CC"
|
||||
|
||||
@@ -1141,7 +1152,7 @@ msgid "Advanced objects"
|
||||
msgstr "Advanced objects"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr "Advanced options"
|
||||
|
||||
@@ -1819,6 +1830,7 @@ msgstr "Ascending"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1826,7 +1838,7 @@ msgid "Ask AI"
|
||||
msgstr "Ask AI"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr "Ask, search or make anything..."
|
||||
|
||||
@@ -1951,7 +1963,7 @@ msgid "Attach files"
|
||||
msgstr "Attach files"
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "Attachments"
|
||||
|
||||
@@ -2058,6 +2070,11 @@ msgstr "Availability"
|
||||
msgid "Available"
|
||||
msgstr "Available"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr "Available as tool"
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2117,7 +2134,7 @@ msgid "Base Credits"
|
||||
msgstr "Base Credits"
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr "BCC"
|
||||
|
||||
@@ -2175,7 +2192,7 @@ msgid "Blue"
|
||||
msgstr "Blue"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "Body"
|
||||
|
||||
@@ -2302,6 +2319,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "Calendar"
|
||||
@@ -2354,6 +2372,11 @@ msgstr "Calendar View"
|
||||
msgid "Calendars"
|
||||
msgstr "Calendars"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr "Calling Code"
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2464,13 +2487,13 @@ msgid "Category"
|
||||
msgstr "Category"
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr "CC"
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "Change Color"
|
||||
|
||||
@@ -2490,11 +2513,6 @@ msgstr "Change node type"
|
||||
msgid "Change Password"
|
||||
msgstr "Change Password"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "Change Plan"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2695,6 +2713,11 @@ msgstr "Client Secret"
|
||||
msgid "Client Settings"
|
||||
msgstr "Client Settings"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2737,6 +2760,7 @@ msgstr "Code your function"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3071,6 +3095,11 @@ msgstr "Context records"
|
||||
msgid "Context size"
|
||||
msgstr "Context size"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr "Context window"
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3286,11 +3315,6 @@ msgstr "Count unique values"
|
||||
msgid "Country"
|
||||
msgstr "Country"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "Country Code"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4011,7 +4035,6 @@ msgstr "delete"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4030,6 +4053,7 @@ msgstr "delete"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4222,6 +4246,12 @@ msgstr "Delete your whole workspace"
|
||||
msgid "Deleted"
|
||||
msgstr "Deleted"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr "Deleted record"
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4694,6 +4724,7 @@ msgstr "else if"
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4722,7 +4753,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "Email copied to clipboard"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "Email Editor"
|
||||
|
||||
@@ -4804,6 +4835,7 @@ msgstr "Emailing Domains"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "Emails"
|
||||
|
||||
@@ -4855,6 +4887,7 @@ msgstr "Empty"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4875,6 +4908,7 @@ msgstr "Empty Inbox"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4973,22 +5007,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "Enter array of items or variable expression"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr "Enter BCC emails, comma-separated"
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr "Enter CC emails, comma-separated"
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "Enter email subject"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr "Enter emails, comma-separated"
|
||||
|
||||
@@ -5070,6 +5104,11 @@ msgstr "Enter test value"
|
||||
msgid "Enter text"
|
||||
msgstr "Enter text"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr "Enter text or type '/' for commands"
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5466,6 +5505,7 @@ msgstr "Exit Settings"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5817,7 +5857,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "Failed to upload file: {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "Failed to upload image: "
|
||||
|
||||
@@ -5996,6 +6036,11 @@ msgstr "File upload failed"
|
||||
msgid "File URL is not defined"
|
||||
msgstr "File URL is not defined"
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr "Files"
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6099,6 +6144,7 @@ msgstr "First name can not be empty"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "Flow"
|
||||
@@ -6564,6 +6610,11 @@ msgstr "Hide group {groupValue}"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "Hide hidden groups"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr "Home"
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6875,6 +6926,7 @@ msgstr "Infos"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "Input"
|
||||
|
||||
@@ -7932,6 +7984,11 @@ msgstr "Max range"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "Maximum email addresses"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr "Maximum execution time in seconds (1-900)"
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8117,6 +8174,11 @@ msgstr "Minutes"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "Minutes between triggers"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr "Missing email draft permission."
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8629,6 +8691,11 @@ msgstr "No available fields to select"
|
||||
msgid "No body"
|
||||
msgstr "No body"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr "No calling code"
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8659,7 +8726,6 @@ msgstr "No context was provided for this request"
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "No country"
|
||||
|
||||
@@ -9035,7 +9101,7 @@ msgstr "Node"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9097,7 +9163,13 @@ msgstr "Not shared by {notSharedByFullName}"
|
||||
msgid "Not synced"
|
||||
msgstr "Not synced"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr "Note"
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "Notes"
|
||||
@@ -9475,6 +9547,11 @@ msgstr "Ordered List"
|
||||
msgid "Organization"
|
||||
msgstr "Organization"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr "Organization plan"
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9533,6 +9610,7 @@ msgstr "Outage"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10034,6 +10112,11 @@ msgstr "Privacy Policy"
|
||||
msgid "Pro"
|
||||
msgstr "Pro"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr "Pro plan"
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10212,6 +10295,11 @@ msgstr "Read documentation"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "Read-only — managed by Twenty"
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr "Reauthorize"
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11093,20 +11181,20 @@ msgstr "Search..."
|
||||
msgid "Searched the web"
|
||||
msgstr "Searched the web"
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgstr "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr "Searched the web for {query}"
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web"
|
||||
msgstr "Searching the web"
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgstr "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr "Searching the web for {query}"
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
#: src/modules/billing/components/SubscriptionPrice.tsx
|
||||
@@ -11444,7 +11532,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "Send an invite email to your team"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "Send Email"
|
||||
@@ -11889,6 +11976,14 @@ msgstr "Spaces and comma - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "Spanish"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr "Split multiple values"
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12045,7 +12140,7 @@ msgid "subheading"
|
||||
msgstr "subheading"
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Subject"
|
||||
|
||||
@@ -12367,6 +12462,7 @@ msgid "Task Title"
|
||||
msgstr "Task Title"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "Tasks"
|
||||
@@ -12566,6 +12662,11 @@ msgstr "There is no activity associated with this record."
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "There was an error while updating password."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr "Thinking"
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12581,6 +12682,11 @@ msgstr "third"
|
||||
msgid "Third"
|
||||
msgstr "Third"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12750,6 +12856,11 @@ msgstr "This will permanently delete your two factor authentication method.<0/>S
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr "Thought"
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12781,10 +12892,16 @@ msgid "Time zone"
|
||||
msgstr "Time zone"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "Timeline"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr "Timeout"
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12813,7 +12930,7 @@ msgid "title"
|
||||
msgstr "title"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr "To"
|
||||
|
||||
@@ -13096,6 +13213,11 @@ msgstr "Two-factor authentication setup completed successfully!"
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr "Type '/' for commands, '@' for mentions"
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13220,6 +13342,12 @@ msgstr "Unknown field"
|
||||
msgid "Unknown file"
|
||||
msgstr "Unknown file"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr "Unknown object"
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13252,6 +13380,7 @@ msgstr "Unordered list with bullets"
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13277,7 +13406,7 @@ msgid "Untitled role"
|
||||
msgstr "Untitled role"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "Untitled Workflow"
|
||||
@@ -13384,7 +13513,7 @@ msgstr "Upload file"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "Upload File"
|
||||
|
||||
@@ -13688,8 +13817,6 @@ msgid "View Logs"
|
||||
msgstr "View Logs"
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13945,6 +14072,11 @@ msgstr "When a new lead is created with source \"Website\", assign it to the sal
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
@@ -106,6 +106,7 @@ msgstr "(seleccionado: {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -381,6 +382,11 @@ msgstr "{selectedCount} tipos de origen"
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "El servicio {serviceLabel} no es accesible"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -642,7 +648,7 @@ msgstr "Accesible en tu función mediante process.env.KEY"
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "Cuenta"
|
||||
@@ -780,6 +786,11 @@ msgstr "Añadir un nodo"
|
||||
msgid "Add a record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -794,7 +805,7 @@ msgstr "Agregar un disparador"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "Agregar cuenta"
|
||||
@@ -806,18 +817,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "Añadir Dominio de Acceso Aprobado"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "Agregar Bloque"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr ""
|
||||
|
||||
@@ -1146,7 +1157,7 @@ msgid "Advanced objects"
|
||||
msgstr "Objetos avanzados"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
@@ -1824,6 +1835,7 @@ msgstr "Ascendente"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1831,7 +1843,7 @@ msgid "Ask AI"
|
||||
msgstr "Preguntar a IA"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1956,7 +1968,7 @@ msgid "Attach files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "Adjuntos"
|
||||
|
||||
@@ -2063,6 +2075,11 @@ msgstr "Disponibilidad"
|
||||
msgid "Available"
|
||||
msgstr "Disponible"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2122,7 +2139,7 @@ msgid "Base Credits"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr ""
|
||||
|
||||
@@ -2180,7 +2197,7 @@ msgid "Blue"
|
||||
msgstr "Azul"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "Cuerpo"
|
||||
|
||||
@@ -2307,6 +2324,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "Calendario"
|
||||
@@ -2359,6 +2377,11 @@ msgstr "Vista del calendario"
|
||||
msgid "Calendars"
|
||||
msgstr "Calendarios"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2469,13 +2492,13 @@ msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "Cambiar Color"
|
||||
|
||||
@@ -2495,11 +2518,6 @@ msgstr "Cambiar tipo de nodo"
|
||||
msgid "Change Password"
|
||||
msgstr "Cambiar contraseña"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "Cambiar plan"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2700,6 +2718,11 @@ msgstr "Secreto del cliente"
|
||||
msgid "Client Settings"
|
||||
msgstr "Configuración de Cliente"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2742,6 +2765,7 @@ msgstr "Codificar su función"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3076,6 +3100,11 @@ msgstr "Registros de contexto"
|
||||
msgid "Context size"
|
||||
msgstr "Tamaño del contexto"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3291,11 +3320,6 @@ msgstr "Contar valores únicos"
|
||||
msgid "Country"
|
||||
msgstr "País"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "Código de país"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4016,7 +4040,6 @@ msgstr "eliminar"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4035,6 +4058,7 @@ msgstr "eliminar"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4227,6 +4251,12 @@ msgstr "Eliminar todo el espacio de trabajo"
|
||||
msgid "Deleted"
|
||||
msgstr "Eliminado"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4699,6 +4729,7 @@ msgstr ""
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4727,7 +4758,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "Correo electrónico copiado al portapapeles"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "Editor de Correo Electrónico"
|
||||
|
||||
@@ -4809,6 +4840,7 @@ msgstr "Dominios de correo electrónico"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "Correos electrónicos"
|
||||
|
||||
@@ -4860,6 +4892,7 @@ msgstr "Vacío"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4880,6 +4913,7 @@ msgstr "Bandeja de entrada vacía"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4978,22 +5012,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "Ingrese un arreglo de elementos o expresión de variable"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "Introduce el asunto del correo"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
@@ -5075,6 +5109,11 @@ msgstr "Introduce el valor de prueba"
|
||||
msgid "Enter text"
|
||||
msgstr "Introduce texto"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5471,6 +5510,7 @@ msgstr "Salir de Configuración"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5822,7 +5862,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "Falló al subir el archivo: {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "Error al subir la imagen: "
|
||||
|
||||
@@ -6001,6 +6041,11 @@ msgstr ""
|
||||
msgid "File URL is not defined"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6104,6 +6149,7 @@ msgstr "El nombre no puede estar vacío"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "Flujo"
|
||||
@@ -6569,6 +6615,11 @@ msgstr "Ocultar grupo {groupValue}"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "Ocultar grupos ocultos"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6880,6 +6931,7 @@ msgstr "Información"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "Entrada"
|
||||
|
||||
@@ -7937,6 +7989,11 @@ msgstr "Rango máximo"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "Máximo de direcciones de correo electrónico"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8122,6 +8179,11 @@ msgstr "Minutos"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "Minutos entre activadores"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8634,6 +8696,11 @@ msgstr "No hay campos disponibles para seleccionar"
|
||||
msgid "No body"
|
||||
msgstr "Sin cuerpo"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8664,7 +8731,6 @@ msgstr "No se proporcionó contexto para esta solicitud"
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "Sin país"
|
||||
|
||||
@@ -9040,7 +9106,7 @@ msgstr "Nodo"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9102,7 +9168,13 @@ msgstr "No compartido por {notSharedByFullName}"
|
||||
msgid "Not synced"
|
||||
msgstr "No sincronizado"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "Notas"
|
||||
@@ -9480,6 +9552,11 @@ msgstr "Lista ordenada"
|
||||
msgid "Organization"
|
||||
msgstr "Organización"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9538,6 +9615,7 @@ msgstr "Interrupción"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10039,6 +10117,11 @@ msgstr "Política de privacidad"
|
||||
msgid "Pro"
|
||||
msgstr "Pro"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10217,6 +10300,11 @@ msgstr "Leer documentación"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11098,9 +11186,9 @@ msgstr ""
|
||||
msgid "Searched the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
@@ -11108,9 +11196,9 @@ msgstr ""
|
||||
msgid "Searching the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
@@ -11449,7 +11537,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "Enviar una invitación por correo electrónico a tu equipo"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "Enviar correo electrónico"
|
||||
@@ -11894,6 +11981,14 @@ msgstr "Espacios y coma - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "Español"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12050,7 +12145,7 @@ msgid "subheading"
|
||||
msgstr "sub encabezado"
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Asunto"
|
||||
|
||||
@@ -12372,6 +12467,7 @@ msgid "Task Title"
|
||||
msgstr "Título de la tarea"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "Tareas"
|
||||
@@ -12571,6 +12667,11 @@ msgstr "No hay actividad asociada con este registro."
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "Hubo un error al actualizar la contraseña."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12586,6 +12687,11 @@ msgstr "tercero"
|
||||
msgid "Third"
|
||||
msgstr "Tercero"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12755,6 +12861,11 @@ msgstr "Esto eliminará permanentemente tu método de autenticación de dos fact
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "Esto revertirá el valor de la base de datos al valor de entorno/predeterminado. Se eliminará la anulación de la base de datos y el sistema utilizará la configuración del entorno."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12786,10 +12897,16 @@ msgid "Time zone"
|
||||
msgstr "Zona horaria"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "Cronología"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12818,7 +12935,7 @@ msgid "title"
|
||||
msgstr "título"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -13101,6 +13218,11 @@ msgstr "¡La configuración de la autenticación de dos factores se completó co
|
||||
msgid "Type"
|
||||
msgstr "Tipo"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13225,6 +13347,12 @@ msgstr "Campo desconocido"
|
||||
msgid "Unknown file"
|
||||
msgstr "Archivo desconocido"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13257,6 +13385,7 @@ msgstr "Lista sin ordenar con puntos"
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13282,7 +13411,7 @@ msgid "Untitled role"
|
||||
msgstr "Rol sin título"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "Flujo de trabajo sin título"
|
||||
@@ -13389,7 +13518,7 @@ msgstr "Subir archivo"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "Subir archivo"
|
||||
|
||||
@@ -13693,8 +13822,6 @@ msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13950,6 +14077,11 @@ msgstr ""
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
@@ -106,6 +106,7 @@ msgstr "(valittu: {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -381,6 +382,11 @@ msgstr "{selectedCount} lähdetyyppiä"
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "Palveluun {serviceLabel} ei saada yhteyttä"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -642,7 +648,7 @@ msgstr "Käytettävissä funktiossasi process.env.KEY:n kautta"
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "Tili"
|
||||
@@ -780,6 +786,11 @@ msgstr "Lisää solmu"
|
||||
msgid "Add a record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -794,7 +805,7 @@ msgstr "Lisää laukaisin"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "Lisää käyttäjätili"
|
||||
@@ -806,18 +817,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "Lisää Hyväksytty Pääsytunnusalue"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "Lisää lohko"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr ""
|
||||
|
||||
@@ -1146,7 +1157,7 @@ msgid "Advanced objects"
|
||||
msgstr "Edistykselliset objektit"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
@@ -1824,6 +1835,7 @@ msgstr "Nouseva"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1831,7 +1843,7 @@ msgid "Ask AI"
|
||||
msgstr "Kysy AI:lta"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1956,7 +1968,7 @@ msgid "Attach files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "Liitteet"
|
||||
|
||||
@@ -2063,6 +2075,11 @@ msgstr "Saatavuus"
|
||||
msgid "Available"
|
||||
msgstr "Saatavilla"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2122,7 +2139,7 @@ msgid "Base Credits"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr ""
|
||||
|
||||
@@ -2180,7 +2197,7 @@ msgid "Blue"
|
||||
msgstr "Sininen"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "Sisältö"
|
||||
|
||||
@@ -2307,6 +2324,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "Kalenteri"
|
||||
@@ -2359,6 +2377,11 @@ msgstr "Kalenterinäkymä"
|
||||
msgid "Calendars"
|
||||
msgstr "Kalenterit"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2469,13 +2492,13 @@ msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "Vaihda väri"
|
||||
|
||||
@@ -2495,11 +2518,6 @@ msgstr "Vaihda solmun tyyppi"
|
||||
msgid "Change Password"
|
||||
msgstr "Vaihda salasana"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "Muuta suunnitelmaa"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2700,6 +2718,11 @@ msgstr "Asiakkaan salaisuus"
|
||||
msgid "Client Settings"
|
||||
msgstr "Asiakasasetukset"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2742,6 +2765,7 @@ msgstr "Koodaa funktiosi"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3076,6 +3100,11 @@ msgstr "Kontekstitietueet"
|
||||
msgid "Context size"
|
||||
msgstr "Kontekstin koko"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3291,11 +3320,6 @@ msgstr "Laske yksilölliset arvot"
|
||||
msgid "Country"
|
||||
msgstr "Maa"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "Maakoodi"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4016,7 +4040,6 @@ msgstr "poista"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4035,6 +4058,7 @@ msgstr "poista"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4227,6 +4251,12 @@ msgstr "Poista koko työtilasi"
|
||||
msgid "Deleted"
|
||||
msgstr "Poistettu"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4699,6 +4729,7 @@ msgstr ""
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4727,7 +4758,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "Sähköposti kopioitu leikepöydälle"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "Sähköpostieditori"
|
||||
|
||||
@@ -4809,6 +4840,7 @@ msgstr "Sähköpostitoimialueet"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "Sähköpostit"
|
||||
|
||||
@@ -4860,6 +4892,7 @@ msgstr "Tyhjä"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4880,6 +4913,7 @@ msgstr "Tyhjä Saapuneet"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4978,22 +5012,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "Syötä kohteiden taulukko tai muuttujan lauseke"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "Anna sähköpostin aihe"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
@@ -5075,6 +5109,11 @@ msgstr "Syötä testiarvo"
|
||||
msgid "Enter text"
|
||||
msgstr "Syötä teksti"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5471,6 +5510,7 @@ msgstr "Poistu asetuksista"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5822,7 +5862,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "Tiedostoa ei voitu ladata: {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "Kuvan lataus epäonnistui: "
|
||||
|
||||
@@ -6001,6 +6041,11 @@ msgstr ""
|
||||
msgid "File URL is not defined"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6104,6 +6149,7 @@ msgstr "Etunimi ei saa olla tyhjä"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "Virtaus"
|
||||
@@ -6569,6 +6615,11 @@ msgstr "Piilota ryhmä {groupValue}"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "Piilota piilotetut ryhmät"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6880,6 +6931,7 @@ msgstr "Tiedot"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "Syöttö"
|
||||
|
||||
@@ -7937,6 +7989,11 @@ msgstr "Maksimirajoitus"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "Sähköpostiosoitteiden enimmäismäärä"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8122,6 +8179,11 @@ msgstr "Minuutit"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "Minuutit liipaisimien välillä"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8634,6 +8696,11 @@ msgstr "Ei valittavissa olevia kenttiä"
|
||||
msgid "No body"
|
||||
msgstr "Ei viestirunkoa"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8664,7 +8731,6 @@ msgstr "Tälle pyynnölle ei annettu kontekstia"
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "Ei maata"
|
||||
|
||||
@@ -9040,7 +9106,7 @@ msgstr "Solmu"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9102,7 +9168,13 @@ msgstr "Ei jaettu käyttäjän {notSharedByFullName} toimesta"
|
||||
msgid "Not synced"
|
||||
msgstr "Ei synkronoitu"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "Muistiinpanot"
|
||||
@@ -9480,6 +9552,11 @@ msgstr ""
|
||||
msgid "Organization"
|
||||
msgstr "Organisaatio"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9538,6 +9615,7 @@ msgstr "Katkos"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10039,6 +10117,11 @@ msgstr "Tietosuojakäytäntö"
|
||||
msgid "Pro"
|
||||
msgstr "Pro"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10217,6 +10300,11 @@ msgstr "Lue dokumentaatio"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11098,9 +11186,9 @@ msgstr ""
|
||||
msgid "Searched the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
@@ -11108,9 +11196,9 @@ msgstr ""
|
||||
msgid "Searching the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
@@ -11449,7 +11537,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "Lähetä kutsusähköposti tiimillesi"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "Lähetä sähköposti"
|
||||
@@ -11894,6 +11981,14 @@ msgstr "Välilyöntejä ja pilkku - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "Espanja"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12050,7 +12145,7 @@ msgid "subheading"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Aihe"
|
||||
|
||||
@@ -12372,6 +12467,7 @@ msgid "Task Title"
|
||||
msgstr "Tehtävän otsikko"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "Tehtävät"
|
||||
@@ -12571,6 +12667,11 @@ msgstr "Tähän tietueeseen ei liity aktiivisuutta."
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "Salasanan päivityksessä tapahtui virhe."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12586,6 +12687,11 @@ msgstr "kolmas"
|
||||
msgid "Third"
|
||||
msgstr "Kolmas"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12753,6 +12859,11 @@ msgstr "Tämä poistaa pysyvästi kaksivaiheisen todennustapasi.<0/>Koska 2FA on
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "Tämä palauttaa tietokannan arvon ympäristö/oletusarvoksi. Tietokannan ohitus poistetaan ja järjestelmä käyttää ympäristöasetuksia."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12784,10 +12895,16 @@ msgid "Time zone"
|
||||
msgstr "Aikavyöhyke"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "Aikajana"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12816,7 +12933,7 @@ msgid "title"
|
||||
msgstr "otsikko"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -13099,6 +13216,11 @@ msgstr "Kaksivaiheisen todennuksen asennus on valmis!"
|
||||
msgid "Type"
|
||||
msgstr "Tyyppi"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13223,6 +13345,12 @@ msgstr "Tuntematon kenttä"
|
||||
msgid "Unknown file"
|
||||
msgstr "Tuntematon tiedosto"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13255,6 +13383,7 @@ msgstr ""
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13280,7 +13409,7 @@ msgid "Untitled role"
|
||||
msgstr "Nimetön rooli"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "Nimetön työnkulku"
|
||||
@@ -13387,7 +13516,7 @@ msgstr "Lataa tiedosto"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "Lataa tiedosto"
|
||||
|
||||
@@ -13691,8 +13820,6 @@ msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13948,6 +14075,11 @@ msgstr ""
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
@@ -106,6 +106,7 @@ msgstr "(sélectionné : {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -381,6 +382,11 @@ msgstr "{selectedCount} types de source"
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "Le service {serviceLabel} est inaccessible"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -642,7 +648,7 @@ msgstr "Accessible dans votre fonction via process.env.KEY"
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "Compte"
|
||||
@@ -780,6 +786,11 @@ msgstr "Ajouter un nœud"
|
||||
msgid "Add a record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -794,7 +805,7 @@ msgstr "Ajouter un déclencheur"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "Ajouter un compte"
|
||||
@@ -806,18 +817,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "Ajouter un domaine d'accès approuvé"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "Ajouter un bloc"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr ""
|
||||
|
||||
@@ -1146,7 +1157,7 @@ msgid "Advanced objects"
|
||||
msgstr "Objets avancés"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
@@ -1824,6 +1835,7 @@ msgstr "Ascendant"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1831,7 +1843,7 @@ msgid "Ask AI"
|
||||
msgstr "Demander à l'IA"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1956,7 +1968,7 @@ msgid "Attach files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "Pièces jointes"
|
||||
|
||||
@@ -2063,6 +2075,11 @@ msgstr "Disponibilité"
|
||||
msgid "Available"
|
||||
msgstr "Disponible"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2122,7 +2139,7 @@ msgid "Base Credits"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr ""
|
||||
|
||||
@@ -2180,7 +2197,7 @@ msgid "Blue"
|
||||
msgstr "Bleu"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "Corps du message"
|
||||
|
||||
@@ -2307,6 +2324,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "Calendrier"
|
||||
@@ -2359,6 +2377,11 @@ msgstr "Vue Calendrier"
|
||||
msgid "Calendars"
|
||||
msgstr "Calendriers"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2469,13 +2492,13 @@ msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "Changer la couleur"
|
||||
|
||||
@@ -2495,11 +2518,6 @@ msgstr "Changer le type de nœud"
|
||||
msgid "Change Password"
|
||||
msgstr "Changer le mot de passe"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "Changer de plan"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2700,6 +2718,11 @@ msgstr "Secret client"
|
||||
msgid "Client Settings"
|
||||
msgstr "Paramètres du client"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2742,6 +2765,7 @@ msgstr "Coder votre fonction"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3076,6 +3100,11 @@ msgstr "Enregistrements de contexte"
|
||||
msgid "Context size"
|
||||
msgstr "Taille du contexte"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3291,11 +3320,6 @@ msgstr "Compter les valeurs uniques"
|
||||
msgid "Country"
|
||||
msgstr "Pays"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "Code du pays"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4016,7 +4040,6 @@ msgstr "supprimer"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4035,6 +4058,7 @@ msgstr "supprimer"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4227,6 +4251,12 @@ msgstr "Supprimer l'ensemble de l'espace de travail"
|
||||
msgid "Deleted"
|
||||
msgstr "Supprimé"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4699,6 +4729,7 @@ msgstr ""
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4727,7 +4758,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "Email copié dans le presse-papiers"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "Éditeur d’Email"
|
||||
|
||||
@@ -4809,6 +4840,7 @@ msgstr "Domaines d'envoi d'e-mail"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "Courriels"
|
||||
|
||||
@@ -4860,6 +4892,7 @@ msgstr "Vide"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4880,6 +4913,7 @@ msgstr "Boîte de réception vide"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4978,22 +5012,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "Entrez un tableau d'articles ou une expression de variable"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "Saisissez l'objet de l'e-mail"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
@@ -5075,6 +5109,11 @@ msgstr "Saisissez une valeur de test"
|
||||
msgid "Enter text"
|
||||
msgstr "Saisissez du texte"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5471,6 +5510,7 @@ msgstr "Quitter les paramètres"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5822,7 +5862,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "Échec du téléchargement du fichier : {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "Échec du téléchargement de l'image : "
|
||||
|
||||
@@ -6001,6 +6041,11 @@ msgstr ""
|
||||
msgid "File URL is not defined"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6104,6 +6149,7 @@ msgstr "Le prénom ne peut pas être vide"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "Flux"
|
||||
@@ -6569,6 +6615,11 @@ msgstr "Masquer le groupe {groupValue}"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "Masquer les groupes cachés"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6880,6 +6931,7 @@ msgstr "Informations"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "Entrée "
|
||||
|
||||
@@ -7937,6 +7989,11 @@ msgstr "Portée max"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "Adresses e-mail maximales"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8122,6 +8179,11 @@ msgstr "Minutes"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "Minutes entre déclencheurs"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8634,6 +8696,11 @@ msgstr "Aucun champ disponible à sélectionner"
|
||||
msgid "No body"
|
||||
msgstr "Aucun corps"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8664,7 +8731,6 @@ msgstr "Aucun contexte n'a été fourni pour cette requête"
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "Aucun pays"
|
||||
|
||||
@@ -9040,7 +9106,7 @@ msgstr "Nœud"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9102,7 +9168,13 @@ msgstr "Non partagé par {notSharedByFullName}"
|
||||
msgid "Not synced"
|
||||
msgstr "Non synchronisé"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "Notes"
|
||||
@@ -9480,6 +9552,11 @@ msgstr ""
|
||||
msgid "Organization"
|
||||
msgstr "Organisation"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9538,6 +9615,7 @@ msgstr "Panne"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10039,6 +10117,11 @@ msgstr "Politique de confidentialité"
|
||||
msgid "Pro"
|
||||
msgstr "Pro"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10217,6 +10300,11 @@ msgstr "Lire la documentation"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11098,9 +11186,9 @@ msgstr ""
|
||||
msgid "Searched the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
@@ -11108,9 +11196,9 @@ msgstr ""
|
||||
msgid "Searching the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
@@ -11449,7 +11537,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "Envoyer un email d'invitation à votre équipe"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "Envoyer l'email"
|
||||
@@ -11894,6 +11981,14 @@ msgstr "Espaces et virgule - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "Espagnol"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12050,7 +12145,7 @@ msgid "subheading"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Objet"
|
||||
|
||||
@@ -12372,6 +12467,7 @@ msgid "Task Title"
|
||||
msgstr "Titre de la tâche"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "Tâches"
|
||||
@@ -12571,6 +12667,11 @@ msgstr "Aucune activité n'est associée à cet enregistrement."
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "Une erreur est survenue lors de la mise à jour du mot de passe."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12586,6 +12687,11 @@ msgstr "troisième"
|
||||
msgid "Third"
|
||||
msgstr "Troisième"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12755,6 +12861,11 @@ msgstr "Cela supprimera définitivement votre méthode d'authentification à deu
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "Cela restaurera la valeur de la base de données à la valeur d'environnement/ou par défaut. La surcharge de la base de données sera supprimée et le système utilisera les paramètres d'environnement."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12786,10 +12897,16 @@ msgid "Time zone"
|
||||
msgstr "Fuseau horaire"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "Chronologie"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12818,7 +12935,7 @@ msgid "title"
|
||||
msgstr "titre"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -13101,6 +13218,11 @@ msgstr "Configuration de l'authentification à deux facteurs terminée avec succ
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13225,6 +13347,12 @@ msgstr "Champ inconnu"
|
||||
msgid "Unknown file"
|
||||
msgstr "Fichier inconnu"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13257,6 +13385,7 @@ msgstr ""
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13282,7 +13411,7 @@ msgid "Untitled role"
|
||||
msgstr "Role sans titre"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "Workflow sans titre"
|
||||
@@ -13389,7 +13518,7 @@ msgstr "Téléverser le fichier"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "Téléverser le fichier"
|
||||
|
||||
@@ -13693,8 +13822,6 @@ msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13950,6 +14077,11 @@ msgstr ""
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -106,6 +106,7 @@ msgstr "(נבחר: {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -381,6 +382,11 @@ msgstr "{selectedCount} סוגי מקורות"
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "השירות {serviceLabel} אינו נגיש"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -642,7 +648,7 @@ msgstr "זמין בפונקציה שלך דרך process.env.KEY"
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "חשבון"
|
||||
@@ -780,6 +786,11 @@ msgstr "הוסף צומת"
|
||||
msgid "Add a record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -794,7 +805,7 @@ msgstr "הוסף טריגר"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "הוסף חשבון"
|
||||
@@ -806,18 +817,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "הוסף דומיין עם גישה מאושרת"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "הוסף בלוק"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr ""
|
||||
|
||||
@@ -1146,7 +1157,7 @@ msgid "Advanced objects"
|
||||
msgstr "אובייקטים מתקדמים"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
@@ -1824,6 +1835,7 @@ msgstr "עולה"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1831,7 +1843,7 @@ msgid "Ask AI"
|
||||
msgstr "שאל את ה-AI"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1956,7 +1968,7 @@ msgid "Attach files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "קבצים מצורפים"
|
||||
|
||||
@@ -2063,6 +2075,11 @@ msgstr "זמינות"
|
||||
msgid "Available"
|
||||
msgstr "זמין"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2122,7 +2139,7 @@ msgid "Base Credits"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr ""
|
||||
|
||||
@@ -2180,7 +2197,7 @@ msgid "Blue"
|
||||
msgstr "כחול"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "גוף"
|
||||
|
||||
@@ -2307,6 +2324,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "לוח שנה"
|
||||
@@ -2359,6 +2377,11 @@ msgstr "תצוגת לוח שנה"
|
||||
msgid "Calendars"
|
||||
msgstr "לוחות שנה"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2469,13 +2492,13 @@ msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "שנה צבע"
|
||||
|
||||
@@ -2495,11 +2518,6 @@ msgstr "שנה סוג צומת"
|
||||
msgid "Change Password"
|
||||
msgstr "שנה סיסמה"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "שנה תוכנית"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2700,6 +2718,11 @@ msgstr "סוד של לקוח"
|
||||
msgid "Client Settings"
|
||||
msgstr "הגדרות לקוח"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2742,6 +2765,7 @@ msgstr "קודד את הפונקציה שלך"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3076,6 +3100,11 @@ msgstr "רשומות הקשר"
|
||||
msgid "Context size"
|
||||
msgstr "גודל הקשר"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3291,11 +3320,6 @@ msgstr "ספור ערכים ייחודיים"
|
||||
msgid "Country"
|
||||
msgstr "מדינה"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "קוד מדינה"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4016,7 +4040,6 @@ msgstr "מחק"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4035,6 +4058,7 @@ msgstr "מחק"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4227,6 +4251,12 @@ msgstr "מחק את כל מרחב העבודה שלך"
|
||||
msgid "Deleted"
|
||||
msgstr "נמחק"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4699,6 +4729,7 @@ msgstr ""
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4727,7 +4758,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "האימייל הועתק ללוח הגזירים"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "עורך האימיילים"
|
||||
|
||||
@@ -4809,6 +4840,7 @@ msgstr "<span dir=\"rtl\">דומיינים לשליחת מיילים</span>"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "דוא\"לים"
|
||||
|
||||
@@ -4860,6 +4892,7 @@ msgstr "ריק"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4880,6 +4913,7 @@ msgstr "תיבת דואר ריקה"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4978,22 +5012,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "הזן מערך של פריטים או ביטוי משתנה"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "הזן נושא הודעה"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
@@ -5075,6 +5109,11 @@ msgstr "הזן ערך בדיקה"
|
||||
msgid "Enter text"
|
||||
msgstr "הזן טקסט"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5471,6 +5510,7 @@ msgstr "יציאה מהגדרות"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5822,7 +5862,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "לא הצליח להעלות קובץ: {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "העלאת תמונה נכשלה: "
|
||||
|
||||
@@ -6001,6 +6041,11 @@ msgstr ""
|
||||
msgid "File URL is not defined"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6104,6 +6149,7 @@ msgstr "שם פרטי לא יכול להיות ריק"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "זרם"
|
||||
@@ -6569,6 +6615,11 @@ msgstr "הסתר קבוצה {groupValue}"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "הסתר קבוצות מוסתרות"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6880,6 +6931,7 @@ msgstr "מידע"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "קלט"
|
||||
|
||||
@@ -7937,6 +7989,11 @@ msgstr "טווח מקסימלי"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "מקסימום כתובות דואר אלקטרוני"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8122,6 +8179,11 @@ msgstr "דקות"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "דקות בין הפעלות"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8634,6 +8696,11 @@ msgstr "אין שדות זמינים לבחירה"
|
||||
msgid "No body"
|
||||
msgstr "ללא גוף"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8664,7 +8731,6 @@ msgstr "לא סופק הקשר לבקשה זו"
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "אין מדינה"
|
||||
|
||||
@@ -9040,7 +9106,7 @@ msgstr "צומת"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9102,7 +9168,13 @@ msgstr "לא שותף על ידי {notSharedByFullName}"
|
||||
msgid "Not synced"
|
||||
msgstr "לא מסונכרן"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "הערות"
|
||||
@@ -9480,6 +9552,11 @@ msgstr ""
|
||||
msgid "Organization"
|
||||
msgstr "ארגון"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9538,6 +9615,7 @@ msgstr "השבתה"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10039,6 +10117,11 @@ msgstr "מדיניות הפרטיות"
|
||||
msgid "Pro"
|
||||
msgstr "מקצועי"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10217,6 +10300,11 @@ msgstr "עיין/י בתיעוד"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11098,9 +11186,9 @@ msgstr ""
|
||||
msgid "Searched the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
@@ -11108,9 +11196,9 @@ msgstr ""
|
||||
msgid "Searching the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
@@ -11449,7 +11537,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "\\"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "שלח דוא\"ל"
|
||||
@@ -11894,6 +11981,14 @@ msgstr "רווחים ופסיק - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "\\"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12050,7 +12145,7 @@ msgid "subheading"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "נושא"
|
||||
|
||||
@@ -12372,6 +12467,7 @@ msgid "Task Title"
|
||||
msgstr "כותרת המשימה"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "משימות"
|
||||
@@ -12571,6 +12667,11 @@ msgstr "אין פעילות מקושרת לרשומה זו."
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "אירעה תקלה בעדכון הסיסמה."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12586,6 +12687,11 @@ msgstr "שלישי"
|
||||
msgid "Third"
|
||||
msgstr "שלישי"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12753,6 +12859,11 @@ msgstr "פעולה זו תמחק לצמיתות את שיטת האימות הד
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "פעולה זו תחזיר את הערך של בסיס הנתונים לערך הסביבה/ערך ברירת המחדל. המעקף של בסיס הנתונים יוסר והמערכת תשתמש בהגדרות הסביבה."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12784,10 +12895,16 @@ msgid "Time zone"
|
||||
msgstr "אזור זמן"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "ציר זמן"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12816,7 +12933,7 @@ msgid "title"
|
||||
msgstr "כותרת"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -13099,6 +13216,11 @@ msgstr "הגדרת האימות הדו-שלבי הושלמה בהצלחה!"
|
||||
msgid "Type"
|
||||
msgstr "סוג"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13223,6 +13345,12 @@ msgstr "שדה לא ידוע"
|
||||
msgid "Unknown file"
|
||||
msgstr "קובץ לא ידוע"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13255,6 +13383,7 @@ msgstr ""
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13280,7 +13409,7 @@ msgid "Untitled role"
|
||||
msgstr "תפקיד ללא כותרת"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "תהליך עבודה ללא כותרת"
|
||||
@@ -13387,7 +13516,7 @@ msgstr "העלה קובץ"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "העלה קובץ"
|
||||
|
||||
@@ -13691,8 +13820,6 @@ msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13948,6 +14075,11 @@ msgstr ""
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
@@ -106,6 +106,7 @@ msgstr "(kiválasztva: {selectedIconKey})"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "[empty string]"
|
||||
@@ -381,6 +382,11 @@ msgstr "{selectedCount} forrástípus"
|
||||
msgid "{serviceLabel} service is unreachable"
|
||||
msgstr "A(z) {serviceLabel} szolgáltatás nem érhető el"
|
||||
|
||||
#. js-lingui-id: 8vJ+2V
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "{stepCount, plural, one {# step} other {# steps}}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Bzjg0/
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
msgid "{stepNumber}. Calendar"
|
||||
@@ -642,7 +648,7 @@ msgstr "A függvényben a process.env.KEY-en keresztül érhető el"
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepCalendar.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/pages/settings/accounts/SettingsAccounts.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsConnectedAccountsTableHeader.tsx
|
||||
msgid "Account"
|
||||
msgstr "Fiók"
|
||||
@@ -780,6 +786,11 @@ msgstr "Csomópont hozzáadása"
|
||||
msgid "Add a record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: r8W+9y
|
||||
#: src/modules/page-layout/widgets/fields/components/FieldsConfigurationSectionEditor.tsx
|
||||
msgid "Add a Section"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: eMc2xs
|
||||
#: src/modules/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement.tsx
|
||||
msgid "Add a step"
|
||||
@@ -794,7 +805,7 @@ msgstr "Adj hozzá egy ravaszt"
|
||||
|
||||
#. js-lingui-id: MPPZ54
|
||||
#: src/pages/settings/accounts/SettingsAccountsConfigurationStepEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx
|
||||
msgid "Add account"
|
||||
msgstr "Fiók hozzáadása"
|
||||
@@ -806,18 +817,18 @@ msgid "Add Approved Access Domain"
|
||||
msgstr "Jóváhagyott hozzáférési tartomány hozzáadása"
|
||||
|
||||
#. js-lingui-id: Qi4JMf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add BCC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: We0vOO
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Add Block"
|
||||
msgstr "Blokk hozzáadása"
|
||||
|
||||
#. js-lingui-id: 02qdT/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Add CC"
|
||||
msgstr ""
|
||||
|
||||
@@ -1146,7 +1157,7 @@ msgid "Advanced objects"
|
||||
msgstr "Haladó objektumok"
|
||||
|
||||
#. js-lingui-id: x4BdSX
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
@@ -1824,6 +1835,7 @@ msgstr "Növekvő"
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
#: src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx
|
||||
#: src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts
|
||||
#: src/modules/command-menu/components/CommandMenuAskAIInfo.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
@@ -1831,7 +1843,7 @@ msgid "Ask AI"
|
||||
msgstr "Kérdezze a MI-t"
|
||||
|
||||
#. js-lingui-id: mc9nK2
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/hooks/useAIChatEditor.ts
|
||||
msgid "Ask, search or make anything..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1956,7 +1968,7 @@ msgid "Attach files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: w/Sphq
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Attachments"
|
||||
msgstr "Csatolmányok"
|
||||
|
||||
@@ -2063,6 +2075,11 @@ msgstr "Elérhetőség"
|
||||
msgid "Available"
|
||||
msgstr "Elérhető"
|
||||
|
||||
#. js-lingui-id: 06gA3L
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Available as tool"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: oD38t2
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Available tools"
|
||||
@@ -2122,7 +2139,7 @@ msgid "Base Credits"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
msgstr ""
|
||||
|
||||
@@ -2180,7 +2197,7 @@ msgid "Blue"
|
||||
msgstr "Kék"
|
||||
|
||||
#. js-lingui-id: bGQplw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Body"
|
||||
msgstr "Szövegtörzs"
|
||||
|
||||
@@ -2307,6 +2324,7 @@ msgstr "caldav.example.com"
|
||||
#. js-lingui-id: AjVXBS
|
||||
#: src/modules/views/view-picker/constants/ViewPickerTypeSelectOptions.ts
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
|
||||
msgid "Calendar"
|
||||
msgstr "Naptár"
|
||||
@@ -2359,6 +2377,11 @@ msgstr "Naptár nézet"
|
||||
msgid "Calendars"
|
||||
msgstr "Naptárak"
|
||||
|
||||
#. js-lingui-id: qIlodj
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Calling Code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: msssZq
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm.tsx
|
||||
msgid "Can't change API names for standard objects"
|
||||
@@ -2469,13 +2492,13 @@ msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardBlockDragHandleMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
msgid "Change Color"
|
||||
msgstr "Szín módosítása"
|
||||
|
||||
@@ -2495,11 +2518,6 @@ msgstr "Csere csomópont típus"
|
||||
msgid "Change Password"
|
||||
msgstr "Jelszó megváltoztatása"
|
||||
|
||||
#. js-lingui-id: wRtBJP
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Change Plan"
|
||||
msgstr "Terv módosítása"
|
||||
|
||||
#. js-lingui-id: EYSFEW
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "Change subdomain?"
|
||||
@@ -2700,6 +2718,11 @@ msgstr "Ügyféltitok"
|
||||
msgid "Client Settings"
|
||||
msgstr "Kliens beállítások"
|
||||
|
||||
#. js-lingui-id: mekEJ5
|
||||
#: src/hooks/useCopyToClipboard.tsx
|
||||
msgid "Clipboard requires a secure connection (HTTPS). Please access this app over HTTPS to enable copying."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yz7wBu
|
||||
#: src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx
|
||||
msgid "Close"
|
||||
@@ -2742,6 +2765,7 @@ msgstr "Kódold a funkciódat"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Collapse"
|
||||
@@ -3076,6 +3100,11 @@ msgstr "Környezet rekordjai"
|
||||
msgid "Context size"
|
||||
msgstr "Környezet mérete"
|
||||
|
||||
#. js-lingui-id: LXIm4m
|
||||
#: src/modules/ai/components/internal/AIChatContextUsageButton.tsx
|
||||
msgid "Context window"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: xGVfLh
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
#: src/pages/onboarding/SyncEmails.tsx
|
||||
@@ -3291,11 +3320,6 @@ msgstr "Egyedi értékek számlálása"
|
||||
msgid "Country"
|
||||
msgstr "Ország"
|
||||
|
||||
#. js-lingui-id: j2OqfX
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormPhoneFieldInput.tsx
|
||||
msgid "Country Code"
|
||||
msgstr "Országkód"
|
||||
|
||||
#. js-lingui-id: gJdfqX
|
||||
#: src/modules/metadata-error-handler/hooks/useMetadataErrorHandler.ts
|
||||
msgid "create"
|
||||
@@ -4016,7 +4040,6 @@ msgstr "törlés"
|
||||
#: src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerEditButton.tsx
|
||||
#: src/modules/views/view-picker/components/ViewPickerCreateButton.tsx
|
||||
#: src/modules/ui/input/editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/settings/security/components/SSO/SettingsSecuritySSORowDropdownMenu.tsx
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTabEnvironmentVariableTableRow.tsx
|
||||
#: src/modules/settings/emailing-domains/components/SettingsEmailingDomainRowDropdownMenu.tsx
|
||||
@@ -4035,6 +4058,7 @@ msgstr "törlés"
|
||||
#: src/modules/navigation-menu-item/components/NavigationMenuItemFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/favorites/components/FavoriteFolderNavigationDrawerItemDropdown.tsx
|
||||
#: src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
#: src/modules/activities/files/components/AttachmentDropdown.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
#: src/modules/action-menu/mock/action-menu-actions.mock.tsx
|
||||
@@ -4227,6 +4251,12 @@ msgstr "Az egész munkaterület törlése"
|
||||
msgid "Deleted"
|
||||
msgstr "Törölve"
|
||||
|
||||
#. js-lingui-id: oAhMKF
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Deleted record"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: WH/5rN
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Deleted records"
|
||||
@@ -4699,6 +4729,7 @@ msgstr ""
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
#: src/pages/auth/PasswordReset.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/security/components/SettingsSecurityEditableProfileFields.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTableHeader.tsx
|
||||
#: src/modules/settings/roles/role-assignment/components/SettingsRoleAssignmentTable.tsx
|
||||
@@ -4727,7 +4758,7 @@ msgid "Email copied to clipboard"
|
||||
msgstr "E-mail vágólapra másolva"
|
||||
|
||||
#. js-lingui-id: GXLHVG
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Email Editor"
|
||||
msgstr "Email szerkesztő"
|
||||
|
||||
@@ -4809,6 +4840,7 @@ msgstr "Emailküldési Tartományok"
|
||||
#: src/pages/settings/accounts/SettingsAccountsEmails.tsx
|
||||
#: src/modules/settings/hooks/useSettingsNavigationItems.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Emails"
|
||||
msgstr "Emailek"
|
||||
|
||||
@@ -4860,6 +4892,7 @@ msgstr "Üres"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Array"
|
||||
@@ -4880,6 +4913,7 @@ msgstr "Üres Postafiók"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Empty Object"
|
||||
@@ -4978,22 +5012,22 @@ msgid "Enter array of items or variable expression"
|
||||
msgstr "Adja meg az elemek tömbjét vagy a változó kifejezést"
|
||||
|
||||
#. js-lingui-id: Pfwdl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter BCC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mPsuKh
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter CC emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: MJoxIi
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter email subject"
|
||||
msgstr "Adja meg az e-mail tárgyát"
|
||||
|
||||
#. js-lingui-id: TRQdC1
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Enter emails, comma-separated"
|
||||
msgstr ""
|
||||
|
||||
@@ -5075,6 +5109,11 @@ msgstr "Adja meg a tesztértéket"
|
||||
msgid "Enter text"
|
||||
msgstr "Írjon be szöveget"
|
||||
|
||||
#. js-lingui-id: +rrO69
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
|
||||
msgid "Enter text or type '/' for commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: yZMXC2
|
||||
#: src/modules/advanced-text-editor/hooks/useAdvancedTextEditor.ts
|
||||
msgid "Enter text or Type '/' for commands"
|
||||
@@ -5471,6 +5510,7 @@ msgstr "Kilépés a beállításokból"
|
||||
#: src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/meta-types/display/components/JsonFieldDisplay.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
#: src/modules/ai/components/RoutingDebugDisplay.tsx
|
||||
msgid "Expand"
|
||||
@@ -5822,7 +5862,7 @@ msgid "Failed to upload file: {fileName}"
|
||||
msgstr "Fájl feltöltése nem sikerült: {fileName}"
|
||||
|
||||
#. js-lingui-id: wJb11y
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Failed to upload image: "
|
||||
msgstr "Nem sikerült feltölteni a képet: "
|
||||
|
||||
@@ -6001,6 +6041,11 @@ msgstr ""
|
||||
msgid "File URL is not defined"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: sER+bs
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: o7J4JM
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/ai/components/SettingsSkillsTable.tsx
|
||||
@@ -6104,6 +6149,7 @@ msgstr "A keresztnév nem lehet üres"
|
||||
|
||||
#. js-lingui-id: ylQd2j
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/utils/getActionHeaderTypeOrThrow.ts
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction.tsx
|
||||
msgid "Flow"
|
||||
msgstr "Folyamat"
|
||||
@@ -6569,6 +6615,11 @@ msgstr "Csoport elrejtése: {groupValue}"
|
||||
msgid "Hide hidden groups"
|
||||
msgstr "Rejtett csoportok elrejtése"
|
||||
|
||||
#. js-lingui-id: i0qMbr
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Xkd22/
|
||||
#: src/modules/page-layout/utils/getWidgetTitle.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/GraphTypeInformation.ts
|
||||
@@ -6880,6 +6931,7 @@ msgstr "Információk"
|
||||
#: src/modules/settings/logic-functions/components/tabs/SettingsLogicFunctionTestTab.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Input"
|
||||
msgstr "Bemenet"
|
||||
|
||||
@@ -7937,6 +7989,11 @@ msgstr "Maximális tartomány"
|
||||
msgid "Maximum email addresses"
|
||||
msgstr "Maximális email címek"
|
||||
|
||||
#. js-lingui-id: 9UHNQc
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Maximum execution time in seconds (1-900)"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PAhTVY
|
||||
#: src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldMaxValuesForm.tsx
|
||||
msgid "Maximum files"
|
||||
@@ -8122,6 +8179,11 @@ msgstr "Percek"
|
||||
msgid "Minutes between triggers"
|
||||
msgstr "Percek a triggerek között"
|
||||
|
||||
#. js-lingui-id: URVUmK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Missing email draft permission."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mibKsa
|
||||
#: src/modules/activities/tasks/components/TaskGroups.tsx
|
||||
msgid "Mission accomplished!"
|
||||
@@ -8634,6 +8696,11 @@ msgstr "Nincsenek kiválasztható mezők"
|
||||
msgid "No body"
|
||||
msgstr "Nincs törzs"
|
||||
|
||||
#. js-lingui-id: c3+z7H
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCallingCodeSelectInput.tsx
|
||||
msgid "No calling code"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: OTe3RI
|
||||
#: src/pages/settings/domains/SettingsDomain.tsx
|
||||
msgid "No change detected"
|
||||
@@ -8664,7 +8731,6 @@ msgstr "Ehhez a kéréshez nem lett kontextus megadva"
|
||||
#: src/modules/settings/data-model/fields/forms/phones/components/SettingsDataModelFieldPhonesForm.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountrySelectInput.tsx
|
||||
#: src/modules/object-record/record-field/ui/form-types/components/FormCountryCodeSelectInput.tsx
|
||||
msgid "No country"
|
||||
msgstr "Nincs ország"
|
||||
|
||||
@@ -9040,7 +9106,7 @@ msgstr "Csomópont"
|
||||
|
||||
#. js-lingui-id: EdQY6l
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/http-request-action/components/BodyInput.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/settings/data-model/objects/forms/components/SettingsDataModelObjectIdentifiersForm.tsx
|
||||
#: src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx
|
||||
#: src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
|
||||
@@ -9102,7 +9168,13 @@ msgstr "Nem osztotta meg {notSharedByFullName}"
|
||||
msgid "Not synced"
|
||||
msgstr "Nincs szinkronizálva"
|
||||
|
||||
#. js-lingui-id: KiJn9B
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 1DBGsz
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Notes"
|
||||
msgstr "Jegyzetek"
|
||||
@@ -9480,6 +9552,11 @@ msgstr ""
|
||||
msgid "Organization"
|
||||
msgstr "Szervezet"
|
||||
|
||||
#. js-lingui-id: zi/p7n
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Organization plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: nV6twc
|
||||
#: src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions.tsx
|
||||
msgid "Organize"
|
||||
@@ -9538,6 +9615,7 @@ msgstr "Leállás"
|
||||
#: src/modules/logic-functions/components/LogicFunctionExecutionResult.tsx
|
||||
#: src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStepContent.tsx
|
||||
#: src/modules/ai/components/ToolStepRenderer.tsx
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
#: src/modules/ai/components/TerminalOutput.tsx
|
||||
#: src/modules/ai/components/CodeExecutionDisplay.tsx
|
||||
msgid "Output"
|
||||
@@ -10039,6 +10117,11 @@ msgstr "Adatvédelmi irányelvek"
|
||||
msgid "Pro"
|
||||
msgstr "Pro"
|
||||
|
||||
#. js-lingui-id: r5je1s
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
msgid "Pro plan"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: k1ifdL
|
||||
#: src/modules/workflow/components/WorkflowStepExecutionResult.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/UploadStep/components/DropZone.tsx
|
||||
@@ -10217,6 +10300,11 @@ msgstr "Dokumentáció olvasása"
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Reauthorize"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: BT7pY+
|
||||
#: src/modules/settings/profile/components/SetOrChangePassword.tsx
|
||||
msgid "Receive an email containing password set link"
|
||||
@@ -11098,9 +11186,9 @@ msgstr ""
|
||||
msgid "Searched the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: KLJPmq
|
||||
#. js-lingui-id: J7YRXR
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searched the web for '{query}'"
|
||||
msgid "Searched the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: AyoeWR
|
||||
@@ -11108,9 +11196,9 @@ msgstr ""
|
||||
msgid "Searching the web"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: dW40bt
|
||||
#. js-lingui-id: BOCV5/
|
||||
#: src/modules/ai/utils/getToolDisplayMessage.ts
|
||||
msgid "Searching the web for '{query}'"
|
||||
msgid "Searching the web for {query}"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8sgZS9
|
||||
@@ -11449,7 +11537,6 @@ msgid "Send an invite email to your team"
|
||||
msgstr "Invitáló e-mail küldése a csapatnak"
|
||||
|
||||
#. js-lingui-id: i/TzEU
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useActionRolePermissionFlagConfig.ts
|
||||
msgid "Send Email"
|
||||
msgstr "E-mail küldése"
|
||||
@@ -11894,6 +11981,14 @@ msgstr "Szóközök és vessző - {spacesAndCommaExample}"
|
||||
msgid "Spanish"
|
||||
msgstr "Spanyol"
|
||||
|
||||
#. js-lingui-id: gsifzp
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/utils/__tests__/shouldHideChartSetting.test.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
|
||||
msgid "Split multiple values"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: vnS6Rf
|
||||
#: src/pages/settings/security/SettingsSecurity.tsx
|
||||
msgid "SSO"
|
||||
@@ -12050,7 +12145,7 @@ msgid "subheading"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Tárgy"
|
||||
|
||||
@@ -12372,6 +12467,7 @@ msgid "Task Title"
|
||||
msgstr "Feladat címe"
|
||||
|
||||
#. js-lingui-id: GtycJ/
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
|
||||
msgid "Tasks"
|
||||
msgstr "Feladatok"
|
||||
@@ -12571,6 +12667,11 @@ msgstr "Ehhez a rekordhoz nem tartozik tevékenység."
|
||||
msgid "There was an error while updating password."
|
||||
msgstr "Hiba történt a jelszó frissítése közben."
|
||||
|
||||
#. js-lingui-id: AUV+TY
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thinking"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Ed99mE
|
||||
#: src/modules/ai/components/ReasoningSummaryDisplay.tsx
|
||||
msgid "Thinking..."
|
||||
@@ -12586,6 +12687,11 @@ msgstr "harmadik"
|
||||
msgid "Third"
|
||||
msgstr "Harmadik"
|
||||
|
||||
#. js-lingui-id: 9BFd/R
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "This account is connected, but we don't have permission to draft emails on your behalf yet. You'll be redirected to approve this access."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4vGCD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx
|
||||
msgid "This action can return up to {maxRecordsFormatted} records."
|
||||
@@ -12753,6 +12859,11 @@ msgstr "Ez véglegesen törli a kétlépcsős hitelesítési módszerét.<0/>Miv
|
||||
msgid "This will revert the database value to environment/default value. The database override will be removed and the system will use the environment settings."
|
||||
msgstr "Ez visszaállítja az adatbázis értéket a környezet/alapértelmezett értékre. Az adatbázis felülbírálat eltávolításra kerül, a rendszer pedig a környezet beállításait fogja használni."
|
||||
|
||||
#. js-lingui-id: f8HOUp
|
||||
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
|
||||
msgid "Thought"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 5g/sE8
|
||||
#: src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
|
||||
msgid "Tidy up"
|
||||
@@ -12784,10 +12895,16 @@ msgid "Time zone"
|
||||
msgstr "Időzóna"
|
||||
|
||||
#. js-lingui-id: cklVjM
|
||||
#: src/modules/page-layout/constants/StandardPageLayoutTabTitleTranslations.ts
|
||||
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCalendarViewContent.tsx
|
||||
msgid "Timeline"
|
||||
msgstr "Idővonal"
|
||||
|
||||
#. js-lingui-id: xY9s5E
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "Timeout"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8TMaZI
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
#: src/pages/settings/security/event-logs/components/EventLogResultsTable.tsx
|
||||
@@ -12816,7 +12933,7 @@ msgid "title"
|
||||
msgstr "cím"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -13099,6 +13216,11 @@ msgstr "Kétfaktoros hitelesítési beállítás sikeresen befejezve!"
|
||||
msgid "Type"
|
||||
msgstr "Típus"
|
||||
|
||||
#. js-lingui-id: SKD2e4
|
||||
#: src/modules/activities/components/ActivityRichTextEditor.tsx
|
||||
msgid "Type '/' for commands, '@' for mentions"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qzD6hf
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuTopBar.tsx
|
||||
@@ -13223,6 +13345,12 @@ msgstr "Ismeretlen mező"
|
||||
msgid "Unknown file"
|
||||
msgstr "Ismeretlen fájl"
|
||||
|
||||
#. js-lingui-id: num3KD
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/blocknote-editor/blocks/MentionInlineContent.tsx
|
||||
msgid "Unknown object"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: GQCXQS
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
#: src/pages/onboarding/internal/ChooseYourPlanContent.tsx
|
||||
@@ -13255,6 +13383,7 @@ msgstr ""
|
||||
#: src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/object-record/components/RecordChip.tsx
|
||||
#: src/modules/mention/components/MentionRecordChip.tsx
|
||||
#: src/modules/command-menu/components/CommandMenuContextChip.tsx
|
||||
#: src/modules/ai/components/RecordLink.tsx
|
||||
#: src/modules/ai/components/AIChatThreadGroup.tsx
|
||||
@@ -13280,7 +13409,7 @@ msgid "Untitled role"
|
||||
msgstr "Cím nélküli szerep"
|
||||
|
||||
#. js-lingui-id: p1M9l4
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionSendEmail.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCode.tsx
|
||||
msgid "Untitled Workflow"
|
||||
msgstr "Cím nélküli munkafolyamat"
|
||||
@@ -13387,7 +13516,7 @@ msgstr "Fájl feltöltése"
|
||||
|
||||
#. js-lingui-id: IQ3gAw
|
||||
#: src/modules/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer.tsx
|
||||
#: src/modules/activities/blocks/components/FileBlock.tsx
|
||||
#: src/modules/blocknote-editor/blocks/FileBlock.tsx
|
||||
msgid "Upload File"
|
||||
msgstr "Fájl feltöltése"
|
||||
|
||||
@@ -13691,8 +13820,6 @@ msgid "View Logs"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ecVcAx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/ai/components/AIChatTab.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
#: src/modules/action-menu/actions/record-agnostic-actions/constants/RecordAgnosticActionsConfig.tsx
|
||||
msgid "View Previous AI Chats"
|
||||
@@ -13948,6 +14075,11 @@ msgstr ""
|
||||
msgid "When any deal with amount over $100,000 has its stage or amount updated, send a notification to the sales channel with the deal name, company, new stage, amount and owner."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8jc/Xn
|
||||
#: src/modules/settings/logic-functions/components/SettingsLogicFunctionNewForm.tsx
|
||||
msgid "When enabled, AI agents and workflow automations can discover and call this function"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: C51ilI
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeysNew.tsx
|
||||
msgid "When the API key will expire."
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user