Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc6c6c16c9 | ||
|
|
6e23ca35e6 | ||
|
|
96a242eb7d | ||
|
|
d97a1cfc27 | ||
|
|
c844109ffc | ||
|
|
dd2a09576b | ||
|
|
fe07de63b0 | ||
|
|
1c9fc94c1f | ||
|
|
d10ef156c1 | ||
|
|
d3ec64072b | ||
|
|
1b14e7e1f1 | ||
|
|
6ad9566043 | ||
|
|
f39fccc3c4 | ||
|
|
ac1ec91f25 | ||
|
|
d324bbfc25 | ||
|
|
7c2a9abed4 | ||
|
|
c0c0cbb896 | ||
|
|
a2188cb0eb | ||
|
|
23874848a4 | ||
|
|
b23d2b4e73 | ||
|
|
601dc02ed7 | ||
|
|
2d552fc9fd | ||
|
|
f33ad53e72 | ||
|
|
7053e1bbc5 | ||
|
|
955aa9191f | ||
|
|
3f87d27d5d | ||
|
|
68cd2f6d61 | ||
|
|
8c9228cb2b | ||
|
|
35b76539cc | ||
|
|
ea4ef99565 | ||
|
|
c7d1cd11e0 | ||
|
|
83d30f8b76 | ||
|
|
aec43da1e2 | ||
|
|
646edec104 | ||
|
|
ea572975d8 | ||
|
|
8acfacc69c | ||
|
|
4aa1d71b12 | ||
|
|
7bf309ba73 | ||
|
|
8d61bb9ae6 | ||
|
|
0d44d7c6d7 | ||
|
|
d3f0162cf5 | ||
|
|
3a1e112b86 | ||
|
|
e062343802 | ||
|
|
3747af4b5a | ||
|
|
bad488494f | ||
|
|
f25e040712 | ||
|
|
265b2582ee | ||
|
|
ed912ec548 | ||
|
|
563e27831b | ||
|
|
9cc794ddb6 | ||
|
|
80c5cfc2ec | ||
|
|
804e0539d9 | ||
|
|
4db7ae20c4 | ||
|
|
8da69e0f77 | ||
|
|
282ee9ac42 | ||
|
|
0b44c9e4e5 | ||
|
|
e1a58df140 | ||
|
|
93c0c98495 | ||
|
|
f8c3960cf2 | ||
|
|
d562a384c2 | ||
|
|
90597e47ca | ||
|
|
b55765a991 | ||
|
|
0b8421a45a | ||
|
|
4ba2f3b184 | ||
|
|
8543576dae |
@@ -158,7 +158,7 @@ jobs:
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
NODE_OPTIONS: '--max-old-space-size=4096'
|
||||
NODE_OPTIONS: '--max-old-space-size=6144'
|
||||
TASK_CACHE_KEY: front-task-${{ matrix.task }}
|
||||
strategy:
|
||||
matrix:
|
||||
|
||||
@@ -144,15 +144,15 @@ jobs:
|
||||
exit 1
|
||||
- name: Server / Check for Pending Migrations
|
||||
run: |
|
||||
CORE_MIGRATION_OUTPUT=$(npx nx run twenty-server:typeorm migration:generate core-migration-check -d src/database/typeorm/core/core.datasource.ts || true)
|
||||
CORE_MIGRATION_OUTPUT=$(npx nx database:migrate:generate twenty-server -- --name core-migration-check || true)
|
||||
|
||||
CORE_MIGRATION_FILE=$(ls packages/twenty-server/*core-migration-check.ts 2>/dev/null || echo "")
|
||||
CORE_MIGRATION_FILE=$(ls packages/twenty-server/src/database/typeorm/core/migrations/common/*core-migration-check.ts 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$CORE_MIGRATION_FILE" ]; then
|
||||
echo "::error::Unexpected migration files were generated. Please create a proper migration manually."
|
||||
echo "::error::Unexpected migration files were generated. Please run 'npx nx database:migrate:generate twenty-server -- --name <migration-name>' and commit the result."
|
||||
echo "$CORE_MIGRATION_OUTPUT"
|
||||
|
||||
rm -f packages/twenty-server/*core-migration-check.ts
|
||||
rm -f packages/twenty-server/src/database/typeorm/core/migrations/common/*core-migration-check.ts
|
||||
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
"cache": false,
|
||||
"options": {
|
||||
"cwd": "{projectRoot}",
|
||||
"command": "npm pkg set version={args.releaseVersion}"
|
||||
"command": "node -e \"const fs=require('fs'),p=JSON.parse(fs.readFileSync('package.json','utf8'));p.version='{args.releaseVersion}';fs.writeFileSync('package.json',JSON.stringify(p,null,2)+'\\n');\""
|
||||
}
|
||||
},
|
||||
"storybook:build": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-twenty-app",
|
||||
"version": "0.8.0-canary.9",
|
||||
"version": "0.8.0",
|
||||
"description": "Command-line interface to create Twenty application",
|
||||
"main": "dist/cli.cjs",
|
||||
"bin": "dist/cli.cjs",
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.*
|
||||
.yarn
|
||||
|
||||
# codegen
|
||||
generated
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# dev
|
||||
/dist/
|
||||
|
||||
.twenty
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# env files (can opt-in for committing if needed)
|
||||
.env*
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
*.d.ts
|
||||
@@ -0,0 +1 @@
|
||||
24.5.0
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["typescript"],
|
||||
"categories": {
|
||||
"correctness": "off"
|
||||
},
|
||||
"ignorePatterns": ["node_modules", "dist"],
|
||||
"rules": {
|
||||
"no-unused-vars": "off",
|
||||
|
||||
"typescript/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"argsIgnorePattern": "^_"
|
||||
}
|
||||
],
|
||||
"typescript/no-explicit-any": "off"
|
||||
}
|
||||
}
|
||||
@@ -2,22 +2,18 @@
|
||||
|
||||
Updates Last interaction and Interaction status fields based on last email date
|
||||
|
||||
## Requirements
|
||||
- an `apiKey` - go to Settings > API & Webhooks to generate one
|
||||
|
||||
## Setup
|
||||
1. Add and synchronize app
|
||||
Add and synchronize app
|
||||
```bash
|
||||
cd packages/twenty-apps/community/last-email-interaction
|
||||
yarn auth
|
||||
yarn sync
|
||||
yarn twenty remote add
|
||||
yarn twenty install
|
||||
```
|
||||
2. Go to Settings > Integrations > Last email interaction > Settings and add required variables
|
||||
|
||||
## Flow
|
||||
- Checks if fields are created, if not, creates them on fly
|
||||
- Extracts the datetime of message and calculates the last interaction status
|
||||
- Fetches all users and companies connected to them and updates their Last interaction and Interaction status fields
|
||||
- Extracts the datetime of fetched message and calculates the last interaction status
|
||||
- Fetches all users and companies connected to the message and updates their Last interaction and Interaction status fields
|
||||
|
||||
## Todo:
|
||||
- update app with generated Twenty object once extending objects is possible
|
||||
## Notes
|
||||
- Upon install, creates fields to Person and Company objects
|
||||
- Every day at midnight app goes through all companies and people records and updates their Interaction status based on Last interaction date
|
||||
@@ -1,23 +0,0 @@
|
||||
import { type ApplicationConfig } from 'twenty-sdk';
|
||||
|
||||
const config: ApplicationConfig = {
|
||||
universalIdentifier: '718ed9ab-53fc-49c8-8deb-0cff78ecf0d2',
|
||||
displayName: 'Last email interaction',
|
||||
description:
|
||||
'Updates Last interaction and Interaction status fields based on last received email',
|
||||
icon: "IconMailFast",
|
||||
applicationVariables: {
|
||||
TWENTY_API_KEY: {
|
||||
universalIdentifier: 'aae3f523-4c1f-4805-b3ee-afeb676c381e',
|
||||
isSecret: true,
|
||||
description: 'Required to send requests to Twenty',
|
||||
},
|
||||
TWENTY_API_URL: {
|
||||
universalIdentifier: '6d19bb04-45bb-46aa-a4e5-4a2682c7b19d',
|
||||
isSecret: false,
|
||||
description: 'Optional, defaults to cloud API URL',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -9,19 +9,23 @@
|
||||
},
|
||||
"packageManager": "[email protected]",
|
||||
"dependencies": {
|
||||
"axios": "^1.12.2",
|
||||
"twenty-sdk": "0.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.7.2"
|
||||
"axios": "1.14.0",
|
||||
"twenty-sdk": "0.8.0"
|
||||
},
|
||||
"scripts": {
|
||||
"auth": "twenty auth login",
|
||||
"dev": "twenty app dev",
|
||||
"sync": "twenty app sync",
|
||||
"uninstall": "twenty app uninstall",
|
||||
"logs": "twenty app logs",
|
||||
"create-entity": "twenty app add",
|
||||
"help": "twenty --help"
|
||||
"twenty": "twenty",
|
||||
"lint": "oxlint -c .oxlintrc.json .",
|
||||
"lint:fix": "oxlint --fix -c .oxlintrc.json .",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.7.2",
|
||||
"@types/react": "^18.2.0",
|
||||
"oxlint": "^0.16.0",
|
||||
"react": "^18.2.0",
|
||||
"typescript": "^5.9.3",
|
||||
"vite-tsconfig-paths": "^4.2.1",
|
||||
"vitest": "^3.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { defineApplication } from 'twenty-sdk';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '718ed9ab-53fc-49c8-8deb-0cff78ecf0d2',
|
||||
displayName: 'Last email interaction',
|
||||
description:
|
||||
'Updates Last interaction and Interaction status fields based on last received email',
|
||||
icon: "IconMailFast",
|
||||
defaultRoleUniversalIdentifier: '7a66af97-5056-45b2-96a9-c89f0fd181d1',
|
||||
});
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
import { defineField, FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS } from 'twenty-sdk';
|
||||
|
||||
export default defineField({
|
||||
universalIdentifier: '9378751e-c23b-4e84-887d-2905cb8359b4',
|
||||
name: 'interactionStatus',
|
||||
label: 'Interaction status',
|
||||
type: FieldType.SELECT,
|
||||
objectUniversalIdentifier:
|
||||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
|
||||
description: 'Indicates the health of relation',
|
||||
options: [
|
||||
{
|
||||
id: '39d54a6b-5a0e-4209-9a59-2a2d7b8c462b',
|
||||
color: 'green',
|
||||
label: 'Recent',
|
||||
value: 'RECENT',
|
||||
position: 1,
|
||||
},
|
||||
{
|
||||
id: '7377d6c5-a75c-453e-a1a1-63fb9cba4e26',
|
||||
color: 'yellow',
|
||||
label: 'Active',
|
||||
value: 'ACTIVE',
|
||||
position: 2,
|
||||
},
|
||||
{
|
||||
id: 'a8b99246-237f-4715-b21f-94a3ae14994e',
|
||||
color: 'sky',
|
||||
label: 'Cooling',
|
||||
value: 'COOLING',
|
||||
position: 3,
|
||||
},
|
||||
{
|
||||
id: '1f05d528-eaab-4639-aba1-328050a87220',
|
||||
color: 'gray',
|
||||
label: 'Dormant',
|
||||
value: 'DORMANT',
|
||||
position: 4,
|
||||
},
|
||||
],
|
||||
});
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import {
|
||||
defineField,
|
||||
FieldType,
|
||||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
|
||||
} from 'twenty-sdk';
|
||||
|
||||
export default defineField({
|
||||
universalIdentifier: '2f195c4c-1db1-4bbe-80b6-25c2f63168b0',
|
||||
name: 'lastInteraction',
|
||||
label: 'Last interaction',
|
||||
type: FieldType.DATE_TIME,
|
||||
objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
|
||||
description: 'Date when the last interaction happened',
|
||||
});
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
import { defineField, FieldType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS } from 'twenty-sdk';
|
||||
|
||||
export default defineField({
|
||||
universalIdentifier: 'fa342e26-9742-4db8-85b4-4d78ba18482f',
|
||||
name: 'interactionStatus',
|
||||
label: 'Interaction status',
|
||||
type: FieldType.SELECT,
|
||||
objectUniversalIdentifier:
|
||||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.universalIdentifier,
|
||||
description: 'Indicates the health of relation',
|
||||
options: [
|
||||
{
|
||||
id: '1dfbfa99-35fb-43af-8c14-74e682a8121b',
|
||||
color: 'green',
|
||||
label: 'Recent',
|
||||
value: 'RECENT',
|
||||
position: 1,
|
||||
},
|
||||
{
|
||||
id: '955788e8-6d64-45ba-80ea-a1a5446a0ae7',
|
||||
color: 'yellow',
|
||||
label: 'Active',
|
||||
value: 'ACTIVE',
|
||||
position: 2,
|
||||
},
|
||||
{
|
||||
id: '7b84ca72-fac5-4c6d-ab08-b148e4b3efdf',
|
||||
color: 'sky',
|
||||
label: 'Cooling',
|
||||
value: 'COOLING',
|
||||
position: 3,
|
||||
},
|
||||
{
|
||||
id: '04dea3e5-ec26-41cf-b23f-37abab67827a',
|
||||
color: 'gray',
|
||||
label: 'Dormant',
|
||||
value: 'DORMANT',
|
||||
position: 4,
|
||||
},
|
||||
],
|
||||
});
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import {
|
||||
defineField,
|
||||
FieldType,
|
||||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
|
||||
} from 'twenty-sdk';
|
||||
|
||||
export default defineField({
|
||||
universalIdentifier: 'bec14de7-6683-4784-91ba-62d83b5f30f7',
|
||||
name: 'lastInteraction',
|
||||
label: 'Last interaction',
|
||||
type: FieldType.DATE_TIME,
|
||||
objectUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.universalIdentifier,
|
||||
description: 'Date when the last interaction happened',
|
||||
});
|
||||
@@ -1,270 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import { type FunctionConfig } from 'twenty-sdk';
|
||||
|
||||
const TWENTY_API_KEY = process.env.TWENTY_API_KEY ?? '';
|
||||
const TWENTY_URL =
|
||||
process.env.TWENTY_API_URL !== '' && process.env.TWENTY_API_URL !== undefined
|
||||
? `${process.env.TWENTY_API_URL}/rest`
|
||||
: 'https://api.twenty.com/rest';
|
||||
|
||||
const create_last_interaction = (id: string) => {
|
||||
return {
|
||||
method: 'POST',
|
||||
url: `${TWENTY_URL}/metadata/fields`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${TWENTY_API_KEY}`,
|
||||
},
|
||||
data: {
|
||||
type: 'DATE_TIME',
|
||||
objectMetadataId: `${id}`,
|
||||
name: 'lastInteraction',
|
||||
label: 'Last interaction',
|
||||
description: 'Date when the last interaction happened',
|
||||
icon: 'IconCalendarClock',
|
||||
defaultValue: null,
|
||||
isNullable: true,
|
||||
settings: {},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const create_interaction_status = (id: string) => {
|
||||
return {
|
||||
method: 'POST',
|
||||
url: `${TWENTY_URL}/metadata/fields`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${TWENTY_API_KEY}`,
|
||||
},
|
||||
data: {
|
||||
type: 'SELECT',
|
||||
objectMetadataId: `${id}`,
|
||||
name: 'interactionStatus',
|
||||
label: 'Interaction status',
|
||||
description: 'Indicates the health of relation',
|
||||
icon: 'IconProgress',
|
||||
defaultValue: null,
|
||||
isNullable: true,
|
||||
settings: {},
|
||||
options: [
|
||||
{
|
||||
color: 'green',
|
||||
label: 'Recent',
|
||||
value: 'RECENT',
|
||||
position: 1,
|
||||
},
|
||||
{
|
||||
color: 'yellow',
|
||||
label: 'Active',
|
||||
value: 'ACTIVE',
|
||||
position: 2,
|
||||
},
|
||||
{
|
||||
color: 'sky',
|
||||
label: 'Cooling',
|
||||
value: 'COOLING',
|
||||
position: 3,
|
||||
},
|
||||
{
|
||||
color: 'gray',
|
||||
label: 'Dormant',
|
||||
value: 'DORMANT',
|
||||
position: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const calculateStatus = (date: string) => {
|
||||
const day = 1000 * 60 * 60 * 24;
|
||||
const now = Date.now();
|
||||
const messageDate = Date.parse(date);
|
||||
const deltaTime = now - messageDate;
|
||||
return deltaTime < 7 * day
|
||||
? 'RECENT'
|
||||
: deltaTime < 30 * day
|
||||
? 'ACTIVE'
|
||||
: deltaTime < 90 * day
|
||||
? 'COOLING'
|
||||
: 'DORMANT';
|
||||
};
|
||||
|
||||
const updateInteractionStatus = async (objectName: string, id: string, messageDate: string, status: string) => {
|
||||
const options = {
|
||||
method: 'PATCH',
|
||||
url: `${TWENTY_URL}/${objectName}/${id}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${TWENTY_API_KEY}`,
|
||||
},
|
||||
data: {
|
||||
lastInteraction: messageDate,
|
||||
interactionStatus: status
|
||||
}
|
||||
};
|
||||
try {
|
||||
const response = await axios.request(options);
|
||||
if (response.status === 200) {
|
||||
console.log('Successfully updated company last interaction field');
|
||||
}
|
||||
} catch (error) {
|
||||
if (axios.isAxiosError(error)) {
|
||||
throw error;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
const fetchRelatedCompanyId = async (id: string) => {
|
||||
const options = {
|
||||
method: 'GET',
|
||||
url: `${TWENTY_URL}/people/${id}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${TWENTY_API_KEY}`,
|
||||
},
|
||||
};
|
||||
try {
|
||||
const req = await axios.request(options);
|
||||
if (req.status === 200 && req.data.person.companyId !== null && req.data.person.companyId !== undefined) {
|
||||
return req.data.person.companyId;
|
||||
}
|
||||
} catch (error) {
|
||||
if (axios.isAxiosError(error)) {
|
||||
throw error;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export const main = async (params: {
|
||||
properties: Record<string, any>;
|
||||
recordId: string;
|
||||
userId: string;
|
||||
}): Promise<object | undefined> => {
|
||||
if (TWENTY_API_KEY === '') {
|
||||
console.log("Function exited as API key or URL hasn't been set properly");
|
||||
return {};
|
||||
}
|
||||
const { properties, recordId } = params;
|
||||
// Check if fields are created
|
||||
const options = {
|
||||
method: 'GET',
|
||||
url: `${TWENTY_URL}/metadata/objects`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${TWENTY_API_KEY}`,
|
||||
},
|
||||
};
|
||||
try {
|
||||
const response = await axios.request(options);
|
||||
const objects = response.data.data.objects;
|
||||
const company_object = objects.find(
|
||||
(object: any) => object.nameSingular === 'company',
|
||||
);
|
||||
const company_last_interaction = company_object.fields.find(
|
||||
(field: any) => field.name === 'lastInteraction',
|
||||
);
|
||||
const company_interaction_status = company_object.fields.find(
|
||||
(field: any) => field.name === 'interactionStatus',
|
||||
);
|
||||
const person_object = objects.find(
|
||||
(object: any) => object.nameSingular === 'person',
|
||||
);
|
||||
const person_last_interaction = person_object.fields.find(
|
||||
(field: any) => field.name === 'lastInteraction',
|
||||
);
|
||||
const person_interaction_status = person_object.fields.find(
|
||||
(field: any) => field.name === 'interactionStatus',
|
||||
);
|
||||
// If not, create them
|
||||
if (company_last_interaction === undefined) {
|
||||
const response2 = await axios.request(
|
||||
create_last_interaction(company_object.id),
|
||||
);
|
||||
if (response2.status === 201) {
|
||||
console.log('Successfully created company last interaction field');
|
||||
}
|
||||
}
|
||||
if (company_interaction_status === undefined) {
|
||||
const response2 = await axios.request(
|
||||
create_interaction_status(company_object.id),
|
||||
);
|
||||
if (response2.status === 201) {
|
||||
console.log('Successfully created company interaction status field');
|
||||
}
|
||||
}
|
||||
if (person_last_interaction === undefined) {
|
||||
const response2 = await axios.request(
|
||||
create_last_interaction(person_object.id),
|
||||
);
|
||||
if (response2.status === 201) {
|
||||
console.log('Successfully created person last interaction field');
|
||||
}
|
||||
}
|
||||
if (person_interaction_status === undefined) {
|
||||
const response2 = await axios.request(
|
||||
create_interaction_status(person_object.id),
|
||||
);
|
||||
if (response2.status === 201) {
|
||||
console.log('Successfully created person interaction status field');
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the timestamp of message
|
||||
const messageDate = properties.after.receivedAt;
|
||||
const interactionStatus = calculateStatus(messageDate);
|
||||
|
||||
// Get the details of person and related company
|
||||
const messageOptions = {
|
||||
method: 'GET',
|
||||
url: `${TWENTY_URL}/messages/${recordId}?depth=1`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${TWENTY_API_KEY}`,
|
||||
},
|
||||
};
|
||||
const messageDetails = await axios.request(messageOptions);
|
||||
const peopleIds: string[] = [];
|
||||
for (const participant of messageDetails.data.messages
|
||||
.messageParticipants) {
|
||||
peopleIds.push(participant.personId);
|
||||
}
|
||||
|
||||
const companiesIds = [];
|
||||
for (const id of peopleIds) {
|
||||
companiesIds.push(await fetchRelatedCompanyId(id));
|
||||
}
|
||||
// Update the field value depending on the timestamp
|
||||
for (const id of peopleIds) {
|
||||
await updateInteractionStatus("people", id, messageDate, interactionStatus);
|
||||
}
|
||||
|
||||
for (const id of companiesIds) {
|
||||
await updateInteractionStatus("companies", id, messageDate, interactionStatus);
|
||||
}
|
||||
} catch (error) {
|
||||
if (axios.isAxiosError(error)) {
|
||||
console.error(error.message);
|
||||
return {};
|
||||
}
|
||||
console.error(error);
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
export const config: FunctionConfig = {
|
||||
universalIdentifier: '683966a0-b60a-424e-86b1-7448c9191bde',
|
||||
name: 'test',
|
||||
triggers: [
|
||||
{
|
||||
universalIdentifier: 'f4f1e127-87f0-4dcf-99fe-8061adf5cbe6',
|
||||
type: 'databaseEvent',
|
||||
eventName: 'message.created',
|
||||
},
|
||||
{
|
||||
universalIdentifier: '4c17878f-b6b3-4d0a-8de6-967b1cb55002',
|
||||
type: 'databaseEvent',
|
||||
eventName: 'message.updated',
|
||||
},
|
||||
],
|
||||
};
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
import { calculateStatus } from '../shared/calculate-status';
|
||||
|
||||
const fetchAllPeople = async () => {
|
||||
const client = new CoreApiClient();
|
||||
const result = await client.query({
|
||||
people: {
|
||||
__args: {
|
||||
filter: {
|
||||
/*
|
||||
lastInteraction: {
|
||||
is: 'NOT_NULL',
|
||||
},
|
||||
*/
|
||||
},
|
||||
},
|
||||
edges: {
|
||||
node: {
|
||||
id: true,
|
||||
lastInteraction: true,
|
||||
interactionStatus: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!result.people) {
|
||||
throw new Error('Could not find any people');
|
||||
}
|
||||
return result.people.edges;
|
||||
}
|
||||
|
||||
const fetchAllCompanies = async () => {
|
||||
const client = new CoreApiClient();
|
||||
const result = await client.query({
|
||||
companies: {
|
||||
__args: {
|
||||
filter: {
|
||||
/* how to fetch fields added in fields folder?
|
||||
lastInteraction: {
|
||||
is: 'NOT_NULL',
|
||||
},
|
||||
*/
|
||||
},
|
||||
},
|
||||
edges: {
|
||||
node: {
|
||||
id: true,
|
||||
lastInteraction: true,
|
||||
interactionStatus: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!result.companies) {
|
||||
throw new Error('Could not find any companies');
|
||||
}
|
||||
return result.companies.edges;
|
||||
}
|
||||
|
||||
const updateCompany = async (
|
||||
companyId: string,
|
||||
updateData: Record<string, string>,
|
||||
) => {
|
||||
const client = new CoreApiClient();
|
||||
const result = await client.mutation({
|
||||
updateCompany: {
|
||||
__args: {
|
||||
id: companyId,
|
||||
data: updateData,
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
if (!result.updateCompany) {
|
||||
throw new Error(`Failed to update company ${companyId}`);
|
||||
}
|
||||
};
|
||||
|
||||
const updatePerson = async (
|
||||
personId: string,
|
||||
updateData: Record<string, string>,
|
||||
) => {
|
||||
const client = new CoreApiClient();
|
||||
const result = await client.mutation({
|
||||
updatePerson: {
|
||||
__args: {
|
||||
id: personId,
|
||||
data: updateData,
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
if (!result.updatePerson) {
|
||||
throw new Error(`Failed to update person ${personId}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handler = async () => {
|
||||
const people = await fetchAllPeople();
|
||||
for (const person of people) {
|
||||
const interactionStatus = calculateStatus(person.node.lastInteraction as string);
|
||||
if (interactionStatus !== person.node.interactionStatus) {
|
||||
await updatePerson(person.node.id, {interactionStatus: interactionStatus});
|
||||
}
|
||||
}
|
||||
const companies = await fetchAllCompanies();
|
||||
for (const company of companies) {
|
||||
const interactionStatus = calculateStatus(company.node.lastInteraction as string);
|
||||
if (interactionStatus !== company.node.interactionStatus) {
|
||||
await updateCompany(company.node.id, {interactionStatus: interactionStatus});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: 'c79f1f30-f369-4264-9e5b-c183577bc709',
|
||||
name: 'on-cron-job',
|
||||
description:
|
||||
'Runs daily at midnight and updates all companies and people with correct interaction status',
|
||||
timeoutSeconds: 5,
|
||||
handler,
|
||||
cronTriggerSettings: {
|
||||
pattern: '0 0 * * *', // runs daily at midnight
|
||||
},
|
||||
});
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
import {
|
||||
DatabaseEventPayload,
|
||||
defineLogicFunction,
|
||||
ObjectRecordCreateEvent,
|
||||
} from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
import { calculateStatus } from '../shared/calculate-status';
|
||||
|
||||
|
||||
const fetchMessageParticipants = async (messageId: string) => {
|
||||
const client = new CoreApiClient();
|
||||
const result = await client.query({
|
||||
messageParticipants: {
|
||||
__args: {
|
||||
filter: {
|
||||
messageId: {
|
||||
eq: messageId,
|
||||
},
|
||||
},
|
||||
},
|
||||
edges: {
|
||||
node: {
|
||||
personId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
let people: string[] = [];
|
||||
if (result.messageParticipants === undefined) {
|
||||
return people;
|
||||
}
|
||||
for (const person of result.messageParticipants.edges) {
|
||||
if (person.node.personId !== undefined) {
|
||||
people.push(person.node.personId);
|
||||
}
|
||||
}
|
||||
return people;
|
||||
};
|
||||
|
||||
const fetchRelatedCompany = async (personId: string) => {
|
||||
const client = new CoreApiClient();
|
||||
const result = await client.query({
|
||||
people: {
|
||||
__args: {
|
||||
filter: {
|
||||
id: {
|
||||
eq: personId,
|
||||
},
|
||||
},
|
||||
},
|
||||
edges: {
|
||||
node: {
|
||||
company: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (
|
||||
result.people === undefined ||
|
||||
result.people.edges[0].node.company === undefined
|
||||
) {
|
||||
throw new Error(`Failed to fetch related company of person ${personId}`);
|
||||
}
|
||||
return result.people.edges[0].node.company.id;
|
||||
};
|
||||
|
||||
const updateCompany = async (
|
||||
companyId: string,
|
||||
updateData: Record<string, string>,
|
||||
) => {
|
||||
const client = new CoreApiClient();
|
||||
const result = await client.mutation({
|
||||
updateCompany: {
|
||||
__args: {
|
||||
id: companyId,
|
||||
data: updateData,
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
if (!result.updateCompany) {
|
||||
throw new Error(`Failed to update company ${companyId}`);
|
||||
}
|
||||
};
|
||||
|
||||
const updatePerson = async (
|
||||
personId: string,
|
||||
updateData: Record<string, string>,
|
||||
) => {
|
||||
const client = new CoreApiClient();
|
||||
const result = await client.mutation({
|
||||
updatePerson: {
|
||||
__args: {
|
||||
id: personId,
|
||||
data: updateData,
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
if (!result.updatePerson) {
|
||||
throw new Error(`Failed to update person ${personId}`);
|
||||
}
|
||||
};
|
||||
|
||||
type Message = {
|
||||
receivedAt: string;
|
||||
};
|
||||
|
||||
type MessageCreatedEvent = DatabaseEventPayload<
|
||||
ObjectRecordCreateEvent<Message>
|
||||
>;
|
||||
|
||||
const handler = async (
|
||||
event: MessageCreatedEvent,
|
||||
): Promise<object | undefined> => {
|
||||
const { properties, recordId } = event;
|
||||
const interactionStatus = calculateStatus(properties.after.receivedAt);
|
||||
const peopleIds: string[] = [];
|
||||
peopleIds.push(...(await fetchMessageParticipants(recordId)));
|
||||
const updateData = {
|
||||
lastInteraction: properties.after.receivedAt,
|
||||
interactionStatus: interactionStatus,
|
||||
};
|
||||
for (const person of peopleIds) {
|
||||
const companyId = await fetchRelatedCompany(person);
|
||||
await updatePerson(person, updateData);
|
||||
await updateCompany(companyId, updateData);
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: '543432c2-6509-4ee9-90ec-15ffb4d7abfc',
|
||||
name: 'on-message-created',
|
||||
description: 'Triggered when new message is created',
|
||||
timeoutSeconds: 5,
|
||||
handler,
|
||||
databaseEventTriggerSettings: {
|
||||
eventName: 'message.created',
|
||||
},
|
||||
});
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
import {
|
||||
DatabaseEventPayload,
|
||||
defineLogicFunction,
|
||||
ObjectRecordCreateEvent,
|
||||
} from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
import { calculateStatus } from '../shared/calculate-status';
|
||||
|
||||
|
||||
const fetchMessageParticipants = async (messageId: string) => {
|
||||
const client = new CoreApiClient();
|
||||
const result = await client.query({
|
||||
messageParticipants: {
|
||||
__args: {
|
||||
filter: {
|
||||
messageId: {
|
||||
eq: messageId,
|
||||
},
|
||||
},
|
||||
},
|
||||
edges: {
|
||||
node: {
|
||||
personId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
let people: string[] = [];
|
||||
if (result.messageParticipants === undefined) {
|
||||
return people;
|
||||
}
|
||||
for (const person of result.messageParticipants.edges) {
|
||||
if (person.node.personId !== undefined) {
|
||||
people.push(person.node.personId);
|
||||
}
|
||||
}
|
||||
return people;
|
||||
};
|
||||
|
||||
const fetchRelatedCompany = async (personId: string) => {
|
||||
const client = new CoreApiClient();
|
||||
const result = await client.query({
|
||||
people: {
|
||||
__args: {
|
||||
filter: {
|
||||
id: {
|
||||
eq: personId,
|
||||
},
|
||||
},
|
||||
},
|
||||
edges: {
|
||||
node: {
|
||||
company: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (
|
||||
result.people === undefined ||
|
||||
result.people.edges[0].node.company === undefined
|
||||
) {
|
||||
throw new Error(`Failed to fetch related company of person ${personId}`);
|
||||
}
|
||||
return result.people.edges[0].node.company.id;
|
||||
};
|
||||
|
||||
const updateCompany = async (
|
||||
companyId: string,
|
||||
updateData: Record<string, string>,
|
||||
) => {
|
||||
const client = new CoreApiClient();
|
||||
const result = await client.mutation({
|
||||
updateCompany: {
|
||||
__args: {
|
||||
id: companyId,
|
||||
data: updateData,
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
if (!result.updateCompany) {
|
||||
throw new Error(`Failed to update company ${companyId}`);
|
||||
}
|
||||
};
|
||||
|
||||
const updatePerson = async (
|
||||
personId: string,
|
||||
updateData: Record<string, string>,
|
||||
) => {
|
||||
const client = new CoreApiClient();
|
||||
const result = await client.mutation({
|
||||
updatePerson: {
|
||||
__args: {
|
||||
id: personId,
|
||||
data: updateData,
|
||||
},
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
if (!result.updatePerson) {
|
||||
throw new Error(`Failed to update person ${personId}`);
|
||||
}
|
||||
};
|
||||
|
||||
type Message = {
|
||||
receivedAt: string;
|
||||
};
|
||||
|
||||
type MessageCreatedEvent = DatabaseEventPayload<
|
||||
ObjectRecordCreateEvent<Message>
|
||||
>;
|
||||
|
||||
const handler = async (
|
||||
event: MessageCreatedEvent,
|
||||
): Promise<object | undefined> => {
|
||||
const { properties, recordId } = event;
|
||||
const interactionStatus = calculateStatus(properties.after.receivedAt);
|
||||
const peopleIds: string[] = [];
|
||||
peopleIds.push(...(await fetchMessageParticipants(recordId)));
|
||||
const updateData = {
|
||||
lastInteraction: properties.after.receivedAt,
|
||||
interactionStatus: interactionStatus,
|
||||
};
|
||||
for (const person of peopleIds) {
|
||||
const companyId = await fetchRelatedCompany(person);
|
||||
await updatePerson(person, updateData);
|
||||
await updateCompany(companyId, updateData);
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
export default defineLogicFunction({
|
||||
universalIdentifier: '9bfcb3e4-9119-4b65-b6e9-d395d0764ce5',
|
||||
name: 'on-message-updated',
|
||||
description: 'Triggered when message is updated',
|
||||
timeoutSeconds: 5,
|
||||
handler,
|
||||
databaseEventTriggerSettings: {
|
||||
eventName: 'message.updated',
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
export const calculateStatus = (date: string) => {
|
||||
const day = 1000 * 60 * 60 * 24;
|
||||
const now = Date.now();
|
||||
const messageDate = Date.parse(date);
|
||||
const deltaTime = now - messageDate;
|
||||
return deltaTime < 7 * day
|
||||
? 'RECENT'
|
||||
: deltaTime < 30 * day
|
||||
? 'ACTIVE'
|
||||
: deltaTime < 90 * day
|
||||
? 'COOLING'
|
||||
: 'DORMANT';
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"types": [
|
||||
"vitest/globals"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-client-sdk",
|
||||
"version": "0.8.0-canary.9",
|
||||
"version": "0.8.0",
|
||||
"sideEffects": false,
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { readFile } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { getIntrospectionQuery, buildClientSchema, printSchema } from 'graphql';
|
||||
import { buildClientSchema, getIntrospectionQuery, printSchema } from 'graphql';
|
||||
|
||||
import { generateMetadataClient } from '../src/generate/generate-metadata-client';
|
||||
|
||||
|
||||
@@ -921,6 +921,7 @@ enum WidgetType {
|
||||
WORKFLOW_RUN
|
||||
FRONT_COMPONENT
|
||||
RECORD_TABLE
|
||||
EMAIL_THREAD
|
||||
}
|
||||
|
||||
union PageLayoutWidgetPosition = PageLayoutWidgetGridPosition | PageLayoutWidgetVerticalListPosition | PageLayoutWidgetCanvasPosition
|
||||
@@ -948,7 +949,7 @@ type PageLayoutWidgetCanvasPosition {
|
||||
layoutMode: PageLayoutTabLayoutMode!
|
||||
}
|
||||
|
||||
union WidgetConfiguration = AggregateChartConfiguration | StandaloneRichTextConfiguration | PieChartConfiguration | LineChartConfiguration | IframeConfiguration | GaugeChartConfiguration | BarChartConfiguration | CalendarConfiguration | FrontComponentConfiguration | EmailsConfiguration | FieldConfiguration | FieldRichTextConfiguration | FieldsConfiguration | FilesConfiguration | NotesConfiguration | TasksConfiguration | TimelineConfiguration | ViewConfiguration | RecordTableConfiguration | WorkflowConfiguration | WorkflowRunConfiguration | WorkflowVersionConfiguration
|
||||
union WidgetConfiguration = AggregateChartConfiguration | StandaloneRichTextConfiguration | PieChartConfiguration | LineChartConfiguration | IframeConfiguration | GaugeChartConfiguration | BarChartConfiguration | CalendarConfiguration | FrontComponentConfiguration | EmailsConfiguration | EmailThreadConfiguration | FieldConfiguration | FieldRichTextConfiguration | FieldsConfiguration | FilesConfiguration | NotesConfiguration | TasksConfiguration | TimelineConfiguration | ViewConfiguration | RecordTableConfiguration | WorkflowConfiguration | WorkflowRunConfiguration | WorkflowVersionConfiguration
|
||||
|
||||
type AggregateChartConfiguration {
|
||||
configurationType: WidgetConfigurationType!
|
||||
@@ -989,6 +990,7 @@ enum WidgetConfigurationType {
|
||||
WORKFLOW_RUN
|
||||
FRONT_COMPONENT
|
||||
RECORD_TABLE
|
||||
EMAIL_THREAD
|
||||
}
|
||||
|
||||
type StandaloneRichTextConfiguration {
|
||||
@@ -1154,6 +1156,10 @@ type EmailsConfiguration {
|
||||
configurationType: WidgetConfigurationType!
|
||||
}
|
||||
|
||||
type EmailThreadConfiguration {
|
||||
configurationType: WidgetConfigurationType!
|
||||
}
|
||||
|
||||
type FieldConfiguration {
|
||||
configurationType: WidgetConfigurationType!
|
||||
fieldMetadataId: String!
|
||||
@@ -1724,16 +1730,16 @@ enum FeatureFlagKey {
|
||||
IS_AI_ENABLED
|
||||
IS_COMMAND_MENU_ITEM_ENABLED
|
||||
IS_MARKETPLACE_ENABLED
|
||||
IS_MARKETPLACE_SETTING_TAB_VISIBLE
|
||||
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED
|
||||
IS_PUBLIC_DOMAIN_ENABLED
|
||||
IS_EMAILING_DOMAIN_ENABLED
|
||||
IS_JUNCTION_RELATIONS_ENABLED
|
||||
IS_DRAFT_EMAIL_ENABLED
|
||||
IS_CONNECTED_ACCOUNT_MIGRATED
|
||||
IS_USAGE_ANALYTICS_ENABLED
|
||||
IS_RICH_TEXT_V1_MIGRATED
|
||||
IS_DIRECT_GRAPHQL_EXECUTION_ENABLED
|
||||
IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED
|
||||
IS_CONNECTED_ACCOUNT_MIGRATED
|
||||
IS_RECORD_TABLE_WIDGET_ENABLED
|
||||
IS_DATASOURCE_MIGRATED
|
||||
}
|
||||
@@ -2542,7 +2548,7 @@ type ConnectedImapSmtpCaldavAccount {
|
||||
id: UUID!
|
||||
handle: String!
|
||||
provider: String!
|
||||
accountOwnerId: UUID!
|
||||
userWorkspaceId: UUID!
|
||||
connectionParameters: ImapSmtpCaldavConnectionParameters
|
||||
}
|
||||
|
||||
@@ -2633,6 +2639,8 @@ enum EngineComponentKey {
|
||||
VIEW_PREVIOUS_AI_CHATS
|
||||
TRIGGER_WORKFLOW_VERSION
|
||||
FRONT_COMPONENT_RENDERER
|
||||
REPLY_TO_EMAIL_THREAD
|
||||
COMPOSE_EMAIL
|
||||
DELETE_SINGLE_RECORD
|
||||
DELETE_MULTIPLE_RECORDS
|
||||
RESTORE_SINGLE_RECORD
|
||||
@@ -2756,6 +2764,26 @@ type DuplicatedDashboard {
|
||||
updatedAt: String!
|
||||
}
|
||||
|
||||
type ConnectedAccountDTO {
|
||||
id: UUID!
|
||||
handle: String!
|
||||
provider: String!
|
||||
lastCredentialsRefreshedAt: DateTime
|
||||
authFailedAt: DateTime
|
||||
handleAliases: [String!]
|
||||
scopes: [String!]
|
||||
connectionParameters: ImapSmtpCaldavConnectionParameters
|
||||
lastSignedInAt: DateTime
|
||||
userWorkspaceId: UUID!
|
||||
createdAt: DateTime!
|
||||
updatedAt: DateTime!
|
||||
}
|
||||
|
||||
type SendEmailOutput {
|
||||
success: Boolean!
|
||||
error: String
|
||||
}
|
||||
|
||||
type EventLogRecord {
|
||||
event: String!
|
||||
timestamp: DateTime!
|
||||
@@ -2924,20 +2952,6 @@ enum CalendarChannelContactAutoCreationPolicy {
|
||||
NONE
|
||||
}
|
||||
|
||||
type ConnectedAccountDTO {
|
||||
id: UUID!
|
||||
handle: String!
|
||||
provider: String!
|
||||
lastCredentialsRefreshedAt: DateTime
|
||||
authFailedAt: DateTime
|
||||
handleAliases: [String!]
|
||||
scopes: [String!]
|
||||
lastSignedInAt: DateTime
|
||||
userWorkspaceId: UUID!
|
||||
createdAt: DateTime!
|
||||
updatedAt: DateTime!
|
||||
}
|
||||
|
||||
type MessageChannel {
|
||||
id: UUID!
|
||||
visibility: MessageChannelVisibility!
|
||||
@@ -3013,7 +3027,7 @@ type MessageFolder {
|
||||
name: String
|
||||
isSentFolder: Boolean!
|
||||
isSynced: Boolean!
|
||||
parentFolderId: UUID
|
||||
parentFolderId: String
|
||||
externalId: String
|
||||
pendingSyncAction: MessageFolderPendingSyncAction!
|
||||
messageChannelId: UUID!
|
||||
@@ -3220,7 +3234,6 @@ type Query {
|
||||
findApplicationRegistrationStats(id: String!): ApplicationRegistrationStats!
|
||||
findApplicationRegistrationVariables(applicationRegistrationId: String!): [ApplicationRegistrationVariable!]!
|
||||
applicationRegistrationTarballUrl(id: String!): String
|
||||
getApplicationShareLink(id: String!): String!
|
||||
currentUser: User!
|
||||
currentWorkspace: Workspace!
|
||||
getPublicWorkspaceDataByDomain(origin: String): PublicWorkspaceData!
|
||||
@@ -3370,6 +3383,7 @@ enum UsageOperationType {
|
||||
AI_WORKFLOW_TOKEN
|
||||
WORKFLOW_EXECUTION
|
||||
CODE_EXECUTION
|
||||
WEB_SEARCH
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
@@ -3445,6 +3459,7 @@ type Mutation {
|
||||
updatePageLayout(id: String!, input: UpdatePageLayoutInput!): PageLayout!
|
||||
destroyPageLayout(id: String!): Boolean!
|
||||
updatePageLayoutWithTabsAndWidgets(id: String!, input: UpdatePageLayoutWithTabsInput!): PageLayout!
|
||||
resetPageLayoutWidgetToDefault(id: String!): PageLayoutWidget!
|
||||
createPageLayoutWidget(input: CreatePageLayoutWidgetInput!): PageLayoutWidget!
|
||||
updatePageLayoutWidget(id: String!, input: UpdatePageLayoutWidgetInput!): PageLayoutWidget!
|
||||
destroyPageLayoutWidget(id: String!): Boolean!
|
||||
@@ -3545,6 +3560,7 @@ type Mutation {
|
||||
deleteSSOIdentityProvider(input: DeleteSsoInput!): DeleteSso!
|
||||
editSSOIdentityProvider(input: EditSsoInput!): EditSso!
|
||||
impersonate(userId: UUID!, workspaceId: UUID!): Impersonate!
|
||||
sendEmail(input: SendEmailInput!): SendEmailOutput!
|
||||
startChannelSync(connectedAccountId: UUID!): ChannelSyncSuccess!
|
||||
saveImapSmtpCaldavAccount(accountOwnerId: UUID!, handle: String!, connectionParameters: EmailAccountConnectionParameters!, id: UUID): ImapSmtpCaldavConnectionSuccess!
|
||||
updateLabPublicFeatureFlag(input: UpdateLabPublicFeatureFlagInput!): FeatureFlag!
|
||||
@@ -4515,6 +4531,16 @@ input EditSsoInput {
|
||||
status: SSOIdentityProviderStatus!
|
||||
}
|
||||
|
||||
input SendEmailInput {
|
||||
connectedAccountId: String!
|
||||
to: String!
|
||||
cc: String
|
||||
bcc: String
|
||||
subject: String!
|
||||
body: String!
|
||||
inReplyTo: String
|
||||
}
|
||||
|
||||
input EmailAccountConnectionParameters {
|
||||
IMAP: ConnectionParameters
|
||||
SMTP: ConnectionParameters
|
||||
|
||||
@@ -676,7 +676,7 @@ export interface PageLayoutWidget {
|
||||
__typename: 'PageLayoutWidget'
|
||||
}
|
||||
|
||||
export type WidgetType = 'VIEW' | 'IFRAME' | 'FIELD' | 'FIELDS' | 'GRAPH' | 'STANDALONE_RICH_TEXT' | 'TIMELINE' | 'TASKS' | 'NOTES' | 'FILES' | 'EMAILS' | 'CALENDAR' | 'FIELD_RICH_TEXT' | 'WORKFLOW' | 'WORKFLOW_VERSION' | 'WORKFLOW_RUN' | 'FRONT_COMPONENT' | 'RECORD_TABLE'
|
||||
export type WidgetType = 'VIEW' | 'IFRAME' | 'FIELD' | 'FIELDS' | 'GRAPH' | 'STANDALONE_RICH_TEXT' | 'TIMELINE' | 'TASKS' | 'NOTES' | 'FILES' | 'EMAILS' | 'CALENDAR' | 'FIELD_RICH_TEXT' | 'WORKFLOW' | 'WORKFLOW_VERSION' | 'WORKFLOW_RUN' | 'FRONT_COMPONENT' | 'RECORD_TABLE' | 'EMAIL_THREAD'
|
||||
|
||||
export type PageLayoutWidgetPosition = (PageLayoutWidgetGridPosition | PageLayoutWidgetVerticalListPosition | PageLayoutWidgetCanvasPosition) & { __isUnion?: true }
|
||||
|
||||
@@ -702,7 +702,7 @@ export interface PageLayoutWidgetCanvasPosition {
|
||||
__typename: 'PageLayoutWidgetCanvasPosition'
|
||||
}
|
||||
|
||||
export type WidgetConfiguration = (AggregateChartConfiguration | StandaloneRichTextConfiguration | PieChartConfiguration | LineChartConfiguration | IframeConfiguration | GaugeChartConfiguration | BarChartConfiguration | CalendarConfiguration | FrontComponentConfiguration | EmailsConfiguration | FieldConfiguration | FieldRichTextConfiguration | FieldsConfiguration | FilesConfiguration | NotesConfiguration | TasksConfiguration | TimelineConfiguration | ViewConfiguration | RecordTableConfiguration | WorkflowConfiguration | WorkflowRunConfiguration | WorkflowVersionConfiguration) & { __isUnion?: true }
|
||||
export type WidgetConfiguration = (AggregateChartConfiguration | StandaloneRichTextConfiguration | PieChartConfiguration | LineChartConfiguration | IframeConfiguration | GaugeChartConfiguration | BarChartConfiguration | CalendarConfiguration | FrontComponentConfiguration | EmailsConfiguration | EmailThreadConfiguration | FieldConfiguration | FieldRichTextConfiguration | FieldsConfiguration | FilesConfiguration | NotesConfiguration | TasksConfiguration | TimelineConfiguration | ViewConfiguration | RecordTableConfiguration | WorkflowConfiguration | WorkflowRunConfiguration | WorkflowVersionConfiguration) & { __isUnion?: true }
|
||||
|
||||
export interface AggregateChartConfiguration {
|
||||
configurationType: WidgetConfigurationType
|
||||
@@ -721,7 +721,7 @@ export interface AggregateChartConfiguration {
|
||||
__typename: 'AggregateChartConfiguration'
|
||||
}
|
||||
|
||||
export type WidgetConfigurationType = 'AGGREGATE_CHART' | 'GAUGE_CHART' | 'PIE_CHART' | 'BAR_CHART' | 'LINE_CHART' | 'IFRAME' | 'STANDALONE_RICH_TEXT' | 'VIEW' | 'FIELD' | 'FIELDS' | 'TIMELINE' | 'TASKS' | 'NOTES' | 'FILES' | 'EMAILS' | 'CALENDAR' | 'FIELD_RICH_TEXT' | 'WORKFLOW' | 'WORKFLOW_VERSION' | 'WORKFLOW_RUN' | 'FRONT_COMPONENT' | 'RECORD_TABLE'
|
||||
export type WidgetConfigurationType = 'AGGREGATE_CHART' | 'GAUGE_CHART' | 'PIE_CHART' | 'BAR_CHART' | 'LINE_CHART' | 'IFRAME' | 'STANDALONE_RICH_TEXT' | 'VIEW' | 'FIELD' | 'FIELDS' | 'TIMELINE' | 'TASKS' | 'NOTES' | 'FILES' | 'EMAILS' | 'CALENDAR' | 'FIELD_RICH_TEXT' | 'WORKFLOW' | 'WORKFLOW_VERSION' | 'WORKFLOW_RUN' | 'FRONT_COMPONENT' | 'RECORD_TABLE' | 'EMAIL_THREAD'
|
||||
|
||||
export interface StandaloneRichTextConfiguration {
|
||||
configurationType: WidgetConfigurationType
|
||||
@@ -869,6 +869,11 @@ export interface EmailsConfiguration {
|
||||
__typename: 'EmailsConfiguration'
|
||||
}
|
||||
|
||||
export interface EmailThreadConfiguration {
|
||||
configurationType: WidgetConfigurationType
|
||||
__typename: 'EmailThreadConfiguration'
|
||||
}
|
||||
|
||||
export interface FieldConfiguration {
|
||||
configurationType: WidgetConfigurationType
|
||||
fieldMetadataId: Scalars['String']
|
||||
@@ -1424,7 +1429,7 @@ export interface PublicFeatureFlag {
|
||||
__typename: 'PublicFeatureFlag'
|
||||
}
|
||||
|
||||
export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_AI_ENABLED' | 'IS_COMMAND_MENU_ITEM_ENABLED' | 'IS_MARKETPLACE_ENABLED' | 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' | 'IS_PUBLIC_DOMAIN_ENABLED' | 'IS_EMAILING_DOMAIN_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_DRAFT_EMAIL_ENABLED' | 'IS_USAGE_ANALYTICS_ENABLED' | 'IS_RICH_TEXT_V1_MIGRATED' | 'IS_DIRECT_GRAPHQL_EXECUTION_ENABLED' | 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' | 'IS_CONNECTED_ACCOUNT_MIGRATED' | 'IS_RECORD_TABLE_WIDGET_ENABLED' | 'IS_DATASOURCE_MIGRATED'
|
||||
export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_AI_ENABLED' | 'IS_COMMAND_MENU_ITEM_ENABLED' | 'IS_MARKETPLACE_ENABLED' | 'IS_MARKETPLACE_SETTING_TAB_VISIBLE' | 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' | 'IS_PUBLIC_DOMAIN_ENABLED' | 'IS_EMAILING_DOMAIN_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_DRAFT_EMAIL_ENABLED' | 'IS_CONNECTED_ACCOUNT_MIGRATED' | 'IS_USAGE_ANALYTICS_ENABLED' | 'IS_RICH_TEXT_V1_MIGRATED' | 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' | 'IS_RECORD_TABLE_WIDGET_ENABLED' | 'IS_DATASOURCE_MIGRATED'
|
||||
|
||||
export interface ClientConfigMaintenanceMode {
|
||||
startAt: Scalars['DateTime']
|
||||
@@ -2250,7 +2255,7 @@ export interface ConnectedImapSmtpCaldavAccount {
|
||||
id: Scalars['UUID']
|
||||
handle: Scalars['String']
|
||||
provider: Scalars['String']
|
||||
accountOwnerId: Scalars['UUID']
|
||||
userWorkspaceId: Scalars['UUID']
|
||||
connectionParameters?: ImapSmtpCaldavConnectionParameters
|
||||
__typename: 'ConnectedImapSmtpCaldavAccount'
|
||||
}
|
||||
@@ -2290,7 +2295,7 @@ export interface CommandMenuItem {
|
||||
__typename: 'CommandMenuItem'
|
||||
}
|
||||
|
||||
export type EngineComponentKey = 'NAVIGATE_TO_NEXT_RECORD' | 'NAVIGATE_TO_PREVIOUS_RECORD' | 'CREATE_NEW_RECORD' | 'DELETE_RECORDS' | 'RESTORE_RECORDS' | 'DESTROY_RECORDS' | 'ADD_TO_FAVORITES' | 'REMOVE_FROM_FAVORITES' | 'EXPORT_NOTE_TO_PDF' | 'EXPORT_RECORDS' | 'UPDATE_MULTIPLE_RECORDS' | 'MERGE_MULTIPLE_RECORDS' | 'IMPORT_RECORDS' | 'EXPORT_VIEW' | 'SEE_DELETED_RECORDS' | 'CREATE_NEW_VIEW' | 'HIDE_DELETED_RECORDS' | 'GO_TO_PEOPLE' | 'GO_TO_COMPANIES' | 'GO_TO_DASHBOARDS' | 'GO_TO_OPPORTUNITIES' | 'GO_TO_SETTINGS' | 'GO_TO_TASKS' | 'GO_TO_NOTES' | 'EDIT_RECORD_PAGE_LAYOUT' | 'EDIT_DASHBOARD_LAYOUT' | 'SAVE_DASHBOARD_LAYOUT' | 'CANCEL_DASHBOARD_LAYOUT' | 'DUPLICATE_DASHBOARD' | 'GO_TO_WORKFLOWS' | 'ACTIVATE_WORKFLOW' | 'DEACTIVATE_WORKFLOW' | 'DISCARD_DRAFT_WORKFLOW' | 'TEST_WORKFLOW' | 'SEE_ACTIVE_VERSION_WORKFLOW' | 'SEE_RUNS_WORKFLOW' | 'SEE_VERSIONS_WORKFLOW' | 'ADD_NODE_WORKFLOW' | 'TIDY_UP_WORKFLOW' | 'DUPLICATE_WORKFLOW' | 'GO_TO_RUNS' | 'SEE_VERSION_WORKFLOW_RUN' | 'SEE_WORKFLOW_WORKFLOW_RUN' | 'STOP_WORKFLOW_RUN' | 'SEE_RUNS_WORKFLOW_VERSION' | 'SEE_WORKFLOW_WORKFLOW_VERSION' | 'USE_AS_DRAFT_WORKFLOW_VERSION' | 'SEE_VERSIONS_WORKFLOW_VERSION' | 'SEARCH_RECORDS' | 'SEARCH_RECORDS_FALLBACK' | 'ASK_AI' | 'VIEW_PREVIOUS_AI_CHATS' | 'TRIGGER_WORKFLOW_VERSION' | 'FRONT_COMPONENT_RENDERER' | 'DELETE_SINGLE_RECORD' | 'DELETE_MULTIPLE_RECORDS' | 'RESTORE_SINGLE_RECORD' | 'RESTORE_MULTIPLE_RECORDS' | 'DESTROY_SINGLE_RECORD' | 'DESTROY_MULTIPLE_RECORDS' | 'EXPORT_FROM_RECORD_INDEX' | 'EXPORT_FROM_RECORD_SHOW' | 'EXPORT_MULTIPLE_RECORDS'
|
||||
export type EngineComponentKey = 'NAVIGATE_TO_NEXT_RECORD' | 'NAVIGATE_TO_PREVIOUS_RECORD' | 'CREATE_NEW_RECORD' | 'DELETE_RECORDS' | 'RESTORE_RECORDS' | 'DESTROY_RECORDS' | 'ADD_TO_FAVORITES' | 'REMOVE_FROM_FAVORITES' | 'EXPORT_NOTE_TO_PDF' | 'EXPORT_RECORDS' | 'UPDATE_MULTIPLE_RECORDS' | 'MERGE_MULTIPLE_RECORDS' | 'IMPORT_RECORDS' | 'EXPORT_VIEW' | 'SEE_DELETED_RECORDS' | 'CREATE_NEW_VIEW' | 'HIDE_DELETED_RECORDS' | 'GO_TO_PEOPLE' | 'GO_TO_COMPANIES' | 'GO_TO_DASHBOARDS' | 'GO_TO_OPPORTUNITIES' | 'GO_TO_SETTINGS' | 'GO_TO_TASKS' | 'GO_TO_NOTES' | 'EDIT_RECORD_PAGE_LAYOUT' | 'EDIT_DASHBOARD_LAYOUT' | 'SAVE_DASHBOARD_LAYOUT' | 'CANCEL_DASHBOARD_LAYOUT' | 'DUPLICATE_DASHBOARD' | 'GO_TO_WORKFLOWS' | 'ACTIVATE_WORKFLOW' | 'DEACTIVATE_WORKFLOW' | 'DISCARD_DRAFT_WORKFLOW' | 'TEST_WORKFLOW' | 'SEE_ACTIVE_VERSION_WORKFLOW' | 'SEE_RUNS_WORKFLOW' | 'SEE_VERSIONS_WORKFLOW' | 'ADD_NODE_WORKFLOW' | 'TIDY_UP_WORKFLOW' | 'DUPLICATE_WORKFLOW' | 'GO_TO_RUNS' | 'SEE_VERSION_WORKFLOW_RUN' | 'SEE_WORKFLOW_WORKFLOW_RUN' | 'STOP_WORKFLOW_RUN' | 'SEE_RUNS_WORKFLOW_VERSION' | 'SEE_WORKFLOW_WORKFLOW_VERSION' | 'USE_AS_DRAFT_WORKFLOW_VERSION' | 'SEE_VERSIONS_WORKFLOW_VERSION' | 'SEARCH_RECORDS' | 'SEARCH_RECORDS_FALLBACK' | 'ASK_AI' | 'VIEW_PREVIOUS_AI_CHATS' | 'TRIGGER_WORKFLOW_VERSION' | 'FRONT_COMPONENT_RENDERER' | 'REPLY_TO_EMAIL_THREAD' | 'COMPOSE_EMAIL' | 'DELETE_SINGLE_RECORD' | 'DELETE_MULTIPLE_RECORDS' | 'RESTORE_SINGLE_RECORD' | 'RESTORE_MULTIPLE_RECORDS' | 'DESTROY_SINGLE_RECORD' | 'DESTROY_MULTIPLE_RECORDS' | 'EXPORT_FROM_RECORD_INDEX' | 'EXPORT_FROM_RECORD_SHOW' | 'EXPORT_MULTIPLE_RECORDS'
|
||||
|
||||
export type CommandMenuItemAvailabilityType = 'GLOBAL' | 'RECORD_SELECTION' | 'FALLBACK'
|
||||
|
||||
@@ -2411,6 +2416,28 @@ export interface DuplicatedDashboard {
|
||||
__typename: 'DuplicatedDashboard'
|
||||
}
|
||||
|
||||
export interface ConnectedAccountDTO {
|
||||
id: Scalars['UUID']
|
||||
handle: Scalars['String']
|
||||
provider: Scalars['String']
|
||||
lastCredentialsRefreshedAt?: Scalars['DateTime']
|
||||
authFailedAt?: Scalars['DateTime']
|
||||
handleAliases?: Scalars['String'][]
|
||||
scopes?: Scalars['String'][]
|
||||
connectionParameters?: ImapSmtpCaldavConnectionParameters
|
||||
lastSignedInAt?: Scalars['DateTime']
|
||||
userWorkspaceId: Scalars['UUID']
|
||||
createdAt: Scalars['DateTime']
|
||||
updatedAt: Scalars['DateTime']
|
||||
__typename: 'ConnectedAccountDTO'
|
||||
}
|
||||
|
||||
export interface SendEmailOutput {
|
||||
success: Scalars['Boolean']
|
||||
error?: Scalars['String']
|
||||
__typename: 'SendEmailOutput'
|
||||
}
|
||||
|
||||
export interface EventLogRecord {
|
||||
event: Scalars['String']
|
||||
timestamp: Scalars['DateTime']
|
||||
@@ -2570,21 +2597,6 @@ export type CalendarChannelVisibility = 'METADATA' | 'SHARE_EVERYTHING'
|
||||
|
||||
export type CalendarChannelContactAutoCreationPolicy = 'AS_PARTICIPANT_AND_ORGANIZER' | 'AS_PARTICIPANT' | 'AS_ORGANIZER' | 'NONE'
|
||||
|
||||
export interface ConnectedAccountDTO {
|
||||
id: Scalars['UUID']
|
||||
handle: Scalars['String']
|
||||
provider: Scalars['String']
|
||||
lastCredentialsRefreshedAt?: Scalars['DateTime']
|
||||
authFailedAt?: Scalars['DateTime']
|
||||
handleAliases?: Scalars['String'][]
|
||||
scopes?: Scalars['String'][]
|
||||
lastSignedInAt?: Scalars['DateTime']
|
||||
userWorkspaceId: Scalars['UUID']
|
||||
createdAt: Scalars['DateTime']
|
||||
updatedAt: Scalars['DateTime']
|
||||
__typename: 'ConnectedAccountDTO'
|
||||
}
|
||||
|
||||
export interface MessageChannel {
|
||||
id: Scalars['UUID']
|
||||
visibility: MessageChannelVisibility
|
||||
@@ -2628,7 +2640,7 @@ export interface MessageFolder {
|
||||
name?: Scalars['String']
|
||||
isSentFolder: Scalars['Boolean']
|
||||
isSynced: Scalars['Boolean']
|
||||
parentFolderId?: Scalars['UUID']
|
||||
parentFolderId?: Scalars['String']
|
||||
externalId?: Scalars['String']
|
||||
pendingSyncAction: MessageFolderPendingSyncAction
|
||||
messageChannelId: Scalars['UUID']
|
||||
@@ -2774,7 +2786,6 @@ export interface Query {
|
||||
findApplicationRegistrationStats: ApplicationRegistrationStats
|
||||
findApplicationRegistrationVariables: ApplicationRegistrationVariable[]
|
||||
applicationRegistrationTarballUrl?: Scalars['String']
|
||||
getApplicationShareLink: Scalars['String']
|
||||
currentUser: User
|
||||
currentWorkspace: Workspace
|
||||
getPublicWorkspaceDataByDomain: PublicWorkspaceData
|
||||
@@ -2819,7 +2830,7 @@ export type SortNulls = 'NULLS_FIRST' | 'NULLS_LAST'
|
||||
|
||||
export type EventLogTable = 'WORKSPACE_EVENT' | 'PAGEVIEW' | 'OBJECT_EVENT' | 'USAGE_EVENT'
|
||||
|
||||
export type UsageOperationType = 'AI_CHAT_TOKEN' | 'AI_WORKFLOW_TOKEN' | 'WORKFLOW_EXECUTION' | 'CODE_EXECUTION'
|
||||
export type UsageOperationType = 'AI_CHAT_TOKEN' | 'AI_WORKFLOW_TOKEN' | 'WORKFLOW_EXECUTION' | 'CODE_EXECUTION' | 'WEB_SEARCH'
|
||||
|
||||
export interface Mutation {
|
||||
addQueryToEventStream: Scalars['Boolean']
|
||||
@@ -2894,6 +2905,7 @@ export interface Mutation {
|
||||
updatePageLayout: PageLayout
|
||||
destroyPageLayout: Scalars['Boolean']
|
||||
updatePageLayoutWithTabsAndWidgets: PageLayout
|
||||
resetPageLayoutWidgetToDefault: PageLayoutWidget
|
||||
createPageLayoutWidget: PageLayoutWidget
|
||||
updatePageLayoutWidget: PageLayoutWidget
|
||||
destroyPageLayoutWidget: Scalars['Boolean']
|
||||
@@ -2994,6 +3006,7 @@ export interface Mutation {
|
||||
deleteSSOIdentityProvider: DeleteSso
|
||||
editSSOIdentityProvider: EditSso
|
||||
impersonate: Impersonate
|
||||
sendEmail: SendEmailOutput
|
||||
startChannelSync: ChannelSyncSuccess
|
||||
saveImapSmtpCaldavAccount: ImapSmtpCaldavConnectionSuccess
|
||||
updateLabPublicFeatureFlag: FeatureFlag
|
||||
@@ -3790,6 +3803,7 @@ export interface WidgetConfigurationGenqlSelection{
|
||||
on_CalendarConfiguration?:CalendarConfigurationGenqlSelection,
|
||||
on_FrontComponentConfiguration?:FrontComponentConfigurationGenqlSelection,
|
||||
on_EmailsConfiguration?:EmailsConfigurationGenqlSelection,
|
||||
on_EmailThreadConfiguration?:EmailThreadConfigurationGenqlSelection,
|
||||
on_FieldConfiguration?:FieldConfigurationGenqlSelection,
|
||||
on_FieldRichTextConfiguration?:FieldRichTextConfigurationGenqlSelection,
|
||||
on_FieldsConfiguration?:FieldsConfigurationGenqlSelection,
|
||||
@@ -3958,6 +3972,12 @@ export interface EmailsConfigurationGenqlSelection{
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface EmailThreadConfigurationGenqlSelection{
|
||||
configurationType?: boolean | number
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface FieldConfigurationGenqlSelection{
|
||||
configurationType?: boolean | number
|
||||
fieldMetadataId?: boolean | number
|
||||
@@ -5431,7 +5451,7 @@ export interface ConnectedImapSmtpCaldavAccountGenqlSelection{
|
||||
id?: boolean | number
|
||||
handle?: boolean | number
|
||||
provider?: boolean | number
|
||||
accountOwnerId?: boolean | number
|
||||
userWorkspaceId?: boolean | number
|
||||
connectionParameters?: ImapSmtpCaldavConnectionParametersGenqlSelection
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
@@ -5603,6 +5623,30 @@ export interface DuplicatedDashboardGenqlSelection{
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface ConnectedAccountDTOGenqlSelection{
|
||||
id?: boolean | number
|
||||
handle?: boolean | number
|
||||
provider?: boolean | number
|
||||
lastCredentialsRefreshedAt?: boolean | number
|
||||
authFailedAt?: boolean | number
|
||||
handleAliases?: boolean | number
|
||||
scopes?: boolean | number
|
||||
connectionParameters?: ImapSmtpCaldavConnectionParametersGenqlSelection
|
||||
lastSignedInAt?: boolean | number
|
||||
userWorkspaceId?: boolean | number
|
||||
createdAt?: boolean | number
|
||||
updatedAt?: boolean | number
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface SendEmailOutputGenqlSelection{
|
||||
success?: boolean | number
|
||||
error?: boolean | number
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface EventLogRecordGenqlSelection{
|
||||
event?: boolean | number
|
||||
timestamp?: boolean | number
|
||||
@@ -5770,22 +5814,6 @@ export interface CalendarChannelGenqlSelection{
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface ConnectedAccountDTOGenqlSelection{
|
||||
id?: boolean | number
|
||||
handle?: boolean | number
|
||||
provider?: boolean | number
|
||||
lastCredentialsRefreshedAt?: boolean | number
|
||||
authFailedAt?: boolean | number
|
||||
handleAliases?: boolean | number
|
||||
scopes?: boolean | number
|
||||
lastSignedInAt?: boolean | number
|
||||
userWorkspaceId?: boolean | number
|
||||
createdAt?: boolean | number
|
||||
updatedAt?: boolean | number
|
||||
__typename?: boolean | number
|
||||
__scalar?: boolean | number
|
||||
}
|
||||
|
||||
export interface MessageChannelGenqlSelection{
|
||||
id?: boolean | number
|
||||
visibility?: boolean | number
|
||||
@@ -5988,7 +6016,6 @@ export interface QueryGenqlSelection{
|
||||
findApplicationRegistrationStats?: (ApplicationRegistrationStatsGenqlSelection & { __args: {id: Scalars['String']} })
|
||||
findApplicationRegistrationVariables?: (ApplicationRegistrationVariableGenqlSelection & { __args: {applicationRegistrationId: Scalars['String']} })
|
||||
applicationRegistrationTarballUrl?: { __args: {id: Scalars['String']} }
|
||||
getApplicationShareLink?: { __args: {id: Scalars['String']} }
|
||||
currentUser?: UserGenqlSelection
|
||||
currentWorkspace?: WorkspaceGenqlSelection
|
||||
getPublicWorkspaceDataByDomain?: (PublicWorkspaceDataGenqlSelection & { __args?: {origin?: (Scalars['String'] | null)} })
|
||||
@@ -6127,6 +6154,7 @@ export interface MutationGenqlSelection{
|
||||
updatePageLayout?: (PageLayoutGenqlSelection & { __args: {id: Scalars['String'], input: UpdatePageLayoutInput} })
|
||||
destroyPageLayout?: { __args: {id: Scalars['String']} }
|
||||
updatePageLayoutWithTabsAndWidgets?: (PageLayoutGenqlSelection & { __args: {id: Scalars['String'], input: UpdatePageLayoutWithTabsInput} })
|
||||
resetPageLayoutWidgetToDefault?: (PageLayoutWidgetGenqlSelection & { __args: {id: Scalars['String']} })
|
||||
createPageLayoutWidget?: (PageLayoutWidgetGenqlSelection & { __args: {input: CreatePageLayoutWidgetInput} })
|
||||
updatePageLayoutWidget?: (PageLayoutWidgetGenqlSelection & { __args: {id: Scalars['String'], input: UpdatePageLayoutWidgetInput} })
|
||||
destroyPageLayoutWidget?: { __args: {id: Scalars['String']} }
|
||||
@@ -6227,6 +6255,7 @@ export interface MutationGenqlSelection{
|
||||
deleteSSOIdentityProvider?: (DeleteSsoGenqlSelection & { __args: {input: DeleteSsoInput} })
|
||||
editSSOIdentityProvider?: (EditSsoGenqlSelection & { __args: {input: EditSsoInput} })
|
||||
impersonate?: (ImpersonateGenqlSelection & { __args: {userId: Scalars['UUID'], workspaceId: Scalars['UUID']} })
|
||||
sendEmail?: (SendEmailOutputGenqlSelection & { __args: {input: SendEmailInput} })
|
||||
startChannelSync?: (ChannelSyncSuccessGenqlSelection & { __args: {connectedAccountId: Scalars['UUID']} })
|
||||
saveImapSmtpCaldavAccount?: (ImapSmtpCaldavConnectionSuccessGenqlSelection & { __args: {accountOwnerId: Scalars['UUID'], handle: Scalars['String'], connectionParameters: EmailAccountConnectionParameters, id?: (Scalars['UUID'] | null)} })
|
||||
updateLabPublicFeatureFlag?: (FeatureFlagGenqlSelection & { __args: {input: UpdateLabPublicFeatureFlagInput} })
|
||||
@@ -6577,6 +6606,8 @@ export interface DeleteSsoInput {identityProviderId: Scalars['UUID']}
|
||||
|
||||
export interface EditSsoInput {id: Scalars['UUID'],status: SSOIdentityProviderStatus}
|
||||
|
||||
export interface SendEmailInput {connectedAccountId: Scalars['String'],to: Scalars['String'],cc?: (Scalars['String'] | null),bcc?: (Scalars['String'] | null),subject: Scalars['String'],body: Scalars['String'],inReplyTo?: (Scalars['String'] | null)}
|
||||
|
||||
export interface EmailAccountConnectionParameters {IMAP?: (ConnectionParameters | null),SMTP?: (ConnectionParameters | null),CALDAV?: (ConnectionParameters | null)}
|
||||
|
||||
export interface ConnectionParameters {host: Scalars['String'],port: Scalars['Float'],username?: (Scalars['String'] | null),password: Scalars['String'],secure?: (Scalars['Boolean'] | null)}
|
||||
@@ -6956,7 +6987,7 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
|
||||
|
||||
|
||||
|
||||
const WidgetConfiguration_possibleTypes: string[] = ['AggregateChartConfiguration','StandaloneRichTextConfiguration','PieChartConfiguration','LineChartConfiguration','IframeConfiguration','GaugeChartConfiguration','BarChartConfiguration','CalendarConfiguration','FrontComponentConfiguration','EmailsConfiguration','FieldConfiguration','FieldRichTextConfiguration','FieldsConfiguration','FilesConfiguration','NotesConfiguration','TasksConfiguration','TimelineConfiguration','ViewConfiguration','RecordTableConfiguration','WorkflowConfiguration','WorkflowRunConfiguration','WorkflowVersionConfiguration']
|
||||
const WidgetConfiguration_possibleTypes: string[] = ['AggregateChartConfiguration','StandaloneRichTextConfiguration','PieChartConfiguration','LineChartConfiguration','IframeConfiguration','GaugeChartConfiguration','BarChartConfiguration','CalendarConfiguration','FrontComponentConfiguration','EmailsConfiguration','EmailThreadConfiguration','FieldConfiguration','FieldRichTextConfiguration','FieldsConfiguration','FilesConfiguration','NotesConfiguration','TasksConfiguration','TimelineConfiguration','ViewConfiguration','RecordTableConfiguration','WorkflowConfiguration','WorkflowRunConfiguration','WorkflowVersionConfiguration']
|
||||
export const isWidgetConfiguration = (obj?: { __typename?: any } | null): obj is WidgetConfiguration => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isWidgetConfiguration"')
|
||||
return WidgetConfiguration_possibleTypes.includes(obj.__typename)
|
||||
@@ -7044,6 +7075,14 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
|
||||
|
||||
|
||||
|
||||
const EmailThreadConfiguration_possibleTypes: string[] = ['EmailThreadConfiguration']
|
||||
export const isEmailThreadConfiguration = (obj?: { __typename?: any } | null): obj is EmailThreadConfiguration => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isEmailThreadConfiguration"')
|
||||
return EmailThreadConfiguration_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const FieldConfiguration_possibleTypes: string[] = ['FieldConfiguration']
|
||||
export const isFieldConfiguration = (obj?: { __typename?: any } | null): obj is FieldConfiguration => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isFieldConfiguration"')
|
||||
@@ -8476,6 +8515,22 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
|
||||
|
||||
|
||||
|
||||
const ConnectedAccountDTO_possibleTypes: string[] = ['ConnectedAccountDTO']
|
||||
export const isConnectedAccountDTO = (obj?: { __typename?: any } | null): obj is ConnectedAccountDTO => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isConnectedAccountDTO"')
|
||||
return ConnectedAccountDTO_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const SendEmailOutput_possibleTypes: string[] = ['SendEmailOutput']
|
||||
export const isSendEmailOutput = (obj?: { __typename?: any } | null): obj is SendEmailOutput => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isSendEmailOutput"')
|
||||
return SendEmailOutput_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const EventLogRecord_possibleTypes: string[] = ['EventLogRecord']
|
||||
export const isEventLogRecord = (obj?: { __typename?: any } | null): obj is EventLogRecord => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isEventLogRecord"')
|
||||
@@ -8604,14 +8659,6 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
|
||||
|
||||
|
||||
|
||||
const ConnectedAccountDTO_possibleTypes: string[] = ['ConnectedAccountDTO']
|
||||
export const isConnectedAccountDTO = (obj?: { __typename?: any } | null): obj is ConnectedAccountDTO => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isConnectedAccountDTO"')
|
||||
return ConnectedAccountDTO_possibleTypes.includes(obj.__typename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const MessageChannel_possibleTypes: string[] = ['MessageChannel']
|
||||
export const isMessageChannel = (obj?: { __typename?: any } | null): obj is MessageChannel => {
|
||||
if (!obj?.__typename) throw new Error('__typename is missing in "isMessageChannel"')
|
||||
@@ -8912,7 +8959,8 @@ export const enumWidgetType = {
|
||||
WORKFLOW_VERSION: 'WORKFLOW_VERSION' as const,
|
||||
WORKFLOW_RUN: 'WORKFLOW_RUN' as const,
|
||||
FRONT_COMPONENT: 'FRONT_COMPONENT' as const,
|
||||
RECORD_TABLE: 'RECORD_TABLE' as const
|
||||
RECORD_TABLE: 'RECORD_TABLE' as const,
|
||||
EMAIL_THREAD: 'EMAIL_THREAD' as const
|
||||
}
|
||||
|
||||
export const enumPageLayoutTabLayoutMode = {
|
||||
@@ -8943,7 +8991,8 @@ export const enumWidgetConfigurationType = {
|
||||
WORKFLOW_VERSION: 'WORKFLOW_VERSION' as const,
|
||||
WORKFLOW_RUN: 'WORKFLOW_RUN' as const,
|
||||
FRONT_COMPONENT: 'FRONT_COMPONENT' as const,
|
||||
RECORD_TABLE: 'RECORD_TABLE' as const
|
||||
RECORD_TABLE: 'RECORD_TABLE' as const,
|
||||
EMAIL_THREAD: 'EMAIL_THREAD' as const
|
||||
}
|
||||
|
||||
export const enumObjectRecordGroupByDateGranularity = {
|
||||
@@ -9092,16 +9141,16 @@ export const enumFeatureFlagKey = {
|
||||
IS_AI_ENABLED: 'IS_AI_ENABLED' as const,
|
||||
IS_COMMAND_MENU_ITEM_ENABLED: 'IS_COMMAND_MENU_ITEM_ENABLED' as const,
|
||||
IS_MARKETPLACE_ENABLED: 'IS_MARKETPLACE_ENABLED' as const,
|
||||
IS_MARKETPLACE_SETTING_TAB_VISIBLE: 'IS_MARKETPLACE_SETTING_TAB_VISIBLE' as const,
|
||||
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED: 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' as const,
|
||||
IS_PUBLIC_DOMAIN_ENABLED: 'IS_PUBLIC_DOMAIN_ENABLED' as const,
|
||||
IS_EMAILING_DOMAIN_ENABLED: 'IS_EMAILING_DOMAIN_ENABLED' as const,
|
||||
IS_JUNCTION_RELATIONS_ENABLED: 'IS_JUNCTION_RELATIONS_ENABLED' as const,
|
||||
IS_DRAFT_EMAIL_ENABLED: 'IS_DRAFT_EMAIL_ENABLED' as const,
|
||||
IS_CONNECTED_ACCOUNT_MIGRATED: 'IS_CONNECTED_ACCOUNT_MIGRATED' as const,
|
||||
IS_USAGE_ANALYTICS_ENABLED: 'IS_USAGE_ANALYTICS_ENABLED' as const,
|
||||
IS_RICH_TEXT_V1_MIGRATED: 'IS_RICH_TEXT_V1_MIGRATED' as const,
|
||||
IS_DIRECT_GRAPHQL_EXECUTION_ENABLED: 'IS_DIRECT_GRAPHQL_EXECUTION_ENABLED' as const,
|
||||
IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED: 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' as const,
|
||||
IS_CONNECTED_ACCOUNT_MIGRATED: 'IS_CONNECTED_ACCOUNT_MIGRATED' as const,
|
||||
IS_RECORD_TABLE_WIDGET_ENABLED: 'IS_RECORD_TABLE_WIDGET_ENABLED' as const,
|
||||
IS_DATASOURCE_MIGRATED: 'IS_DATASOURCE_MIGRATED' as const
|
||||
}
|
||||
@@ -9252,6 +9301,8 @@ export const enumEngineComponentKey = {
|
||||
VIEW_PREVIOUS_AI_CHATS: 'VIEW_PREVIOUS_AI_CHATS' as const,
|
||||
TRIGGER_WORKFLOW_VERSION: 'TRIGGER_WORKFLOW_VERSION' as const,
|
||||
FRONT_COMPONENT_RENDERER: 'FRONT_COMPONENT_RENDERER' as const,
|
||||
REPLY_TO_EMAIL_THREAD: 'REPLY_TO_EMAIL_THREAD' as const,
|
||||
COMPOSE_EMAIL: 'COMPOSE_EMAIL' as const,
|
||||
DELETE_SINGLE_RECORD: 'DELETE_SINGLE_RECORD' as const,
|
||||
DELETE_MULTIPLE_RECORDS: 'DELETE_MULTIPLE_RECORDS' as const,
|
||||
RESTORE_SINGLE_RECORD: 'RESTORE_SINGLE_RECORD' as const,
|
||||
@@ -9408,7 +9459,8 @@ export const enumUsageOperationType = {
|
||||
AI_CHAT_TOKEN: 'AI_CHAT_TOKEN' as const,
|
||||
AI_WORKFLOW_TOKEN: 'AI_WORKFLOW_TOKEN' as const,
|
||||
WORKFLOW_EXECUTION: 'WORKFLOW_EXECUTION' as const,
|
||||
CODE_EXECUTION: 'CODE_EXECUTION' as const
|
||||
CODE_EXECUTION: 'CODE_EXECUTION' as const,
|
||||
WEB_SEARCH: 'WEB_SEARCH' as const
|
||||
}
|
||||
|
||||
export const enumAnalyticsType = {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,7 +52,11 @@ yarn twenty deploy
|
||||
|
||||
### Sharing a deployed app
|
||||
|
||||
Tarball apps are not listed in the public marketplace, so other workspaces on the same server won't discover them by browsing. To share a deployed app:
|
||||
<Warning>
|
||||
Sharing private (tarball) apps across workspaces is an **Enterprise** feature. The **Distribution** tab will show an upgrade prompt instead of the share controls until your workspace has a valid Enterprise key. See [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to activate it.
|
||||
</Warning>
|
||||
|
||||
Tarball apps are not listed in the public marketplace, so other workspaces on the same server won't discover them by browsing. Once your workspace is on the Enterprise plan, you can share a deployed app like this:
|
||||
|
||||
1. Go to **Settings > Applications > Registrations** and open your app
|
||||
2. In the **Distribution** tab, click **Copy share link**
|
||||
@@ -60,10 +64,6 @@ Tarball apps are not listed in the public marketplace, so other workspaces on th
|
||||
|
||||
The share link uses the server's base URL (without any workspace subdomain) so it works for any workspace on the server.
|
||||
|
||||
<Warning>
|
||||
Sharing private apps is an Enterprise feature. Go to [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to enable it.
|
||||
</Warning>
|
||||
|
||||
### Version management
|
||||
|
||||
To release an update:
|
||||
|
||||
@@ -81,7 +81,7 @@ import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
universalIdentifier: '39783023-bcac-41e3-b0d2-ff1944d8465d',
|
||||
displayName: 'My Twenty App',
|
||||
description: 'My first Twenty app',
|
||||
icon: 'IconWorld',
|
||||
@@ -716,6 +716,13 @@ yarn twenty exec --postInstall
|
||||
|
||||
المكوّنات الأمامية هي مكوّنات React تُعرَض مباشرة داخل واجهة مستخدم Twenty. تعمل ضمن **Web Worker** معزول باستخدام Remote DOM — تكون شيفرتك في صندوق عزل لكنها تُعرَض أصيلًا داخل الصفحة، وليس ضمن iframe.
|
||||
|
||||
#### أين يمكن استخدام مكوّنات الواجهة الأمامية
|
||||
|
||||
يمكن عرض مكوّنات الواجهة الأمامية في موقعين داخل Twenty:
|
||||
|
||||
* **اللوحة الجانبية** — المكوّنات غير عديمة الرأس تفتح في اللوحة الجانبية اليمنى. هذا هو السلوك الافتراضي عندما يتم تشغيل مكوّن واجهة أمامية من قائمة الأوامر.
|
||||
* **الويدجت (لوحات المعلومات وصفحات السجلات)** — يمكن تضمين مكوّنات الواجهة الأمامية كويدجت داخل تخطيطات الصفحات. عند تكوين لوحة معلومات أو تخطيط صفحة سجل، يمكن للمستخدمين إضافة ويدجت لمكوّن واجهة أمامية.
|
||||
|
||||
#### مثال أساسي
|
||||
|
||||
أسرع طريقة لرؤية مكوّن أمامي قيد العمل هي تسجيله كأمر. إضافة حقل `command` مع `isPinned: true` يجعلُه يظهر كزر إجراء سريع في الزاوية العلوية اليمنى من الصفحة — دون الحاجة إلى تخطيط صفحة:
|
||||
@@ -773,9 +780,13 @@ export default defineFrontComponent({
|
||||
|
||||
إضافةً إلى الأوامر، يمكنك تضمين مكوّن أمامي مباشرةً في صفحة سجل عبر إضافته كودجت في **تخطيط صفحة**. راجع قسم [definePageLayout](#definepagelayout) للتفاصيل.
|
||||
|
||||
#### مكوّنات عديمة الواجهة (`isHeadless: true`)
|
||||
#### عديم الرأس مقابل غير عديم الرأس
|
||||
|
||||
المكوّنات عديمة الواجهة لا تُظهر واجهة مرئية لكنها ما تزال تُشغِّل منطق React. يكون هذا مفيدًا لـ **مكوّنات التأثير** — وهي مكوّنات تُجري تأثيرات جانبية عند التثبيت، مثل مزامنة البيانات، بدء مؤقّت، الاستماع إلى الأحداث، أو إطلاق إشعار.
|
||||
تأتي مكوّنات الواجهة الأمامية بوضعَي عرض يتحكّم بهما الخيار `isHeadless`:
|
||||
|
||||
**غير عديم الرأس (افتراضي)** — يعرض المكوّن واجهة مستخدم مرئية. عند تشغيله من قائمة الأوامر يفتح في اللوحة الجانبية. هذا هو السلوك الافتراضي عندما تكون `isHeadless` تساوي `false` أو يتم تجاهلها.
|
||||
|
||||
**عديم الرأس (`isHeadless: true`)** — يتم تركيب المكوّن بشكل غير مرئي في الخلفية. لا يفتح اللوحة الجانبية. تم تصميم المكوّنات عديمة الرأس لإجراءات تنفّذ منطقًا ثم تُزيل تركيبها ذاتيًا — على سبيل المثال، تشغيل مهمة غير متزامنة، أو الانتقال إلى صفحة، أو إظهار نافذة تأكيد منبثقة. تتوافق بشكل طبيعي مع مكوّنات Command في SDK الموصوفة أدناه.
|
||||
|
||||
```tsx src/front-components/sync-tracker.tsx
|
||||
import { defineFrontComponent, useRecordId, enqueueSnackbar } from 'twenty-sdk';
|
||||
@@ -802,6 +813,89 @@ export default defineFrontComponent({
|
||||
|
||||
نظرًا لأن المكوّن يُرجع `null`، فإن Twenty يتخطّى عرض حاوية له — ولن تظهر مساحة فارغة في التخطيط. لا يزال لدى المكوّن إمكانية الوصول إلى جميع الخطافات وواجهة برمجة الاتصال مع المضيف.
|
||||
|
||||
#### مكوّنات Command في SDK
|
||||
|
||||
توفر حزمة `twenty-sdk` أربعة مكوّنات مساعدة من نوع Command مصممة للمكوّنات عديمة الرأس في الواجهة الأمامية. كل مكوّن ينفّذ إجراءً عند التركيب، ويتعامل مع الأخطاء بعرض إشعار Snackbar، ويزيل تركيب مكوّن الواجهة الأمامية تلقائيًا عند الانتهاء.
|
||||
|
||||
استوردها من `twenty-sdk/command`:
|
||||
|
||||
* **`Command`** — يشغّل رد نداء غير متزامن عبر الخاصية `execute`.
|
||||
* **`CommandLink`** — ينتقل إلى مسار في التطبيق. الخصائص: `to`، `params`، `queryParams`، `options`.
|
||||
* **`CommandModal`** — يفتح نافذة تأكيد منبثقة. إذا أكّد المستخدم، ينفّذ رد النداء `execute`. الخصائص: `title`، `subtitle`، `execute`، `confirmButtonText`، `confirmButtonAccent`.
|
||||
* **`CommandOpenSidePanelPage`** — يفتح صفحة محدّدة في اللوحة الجانبية. الخصائص: `page`، `pageTitle`، `pageIcon`.
|
||||
|
||||
فيما يلي مثال كامل لمكوّن واجهة أمامية عديم الرأس يستخدم `Command` لتشغيل إجراء من قائمة الأوامر:
|
||||
|
||||
```tsx src/front-components/run-action.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { Command } from 'twenty-sdk/command';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const RunAction = () => {
|
||||
const execute = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
createTask: {
|
||||
__args: { data: { title: 'Created by my app' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return <Command execute={execute} />;
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'e5f6a7b8-c9d0-1234-efab-345678901234',
|
||||
name: 'run-action',
|
||||
description: 'Creates a task from the command menu',
|
||||
component: RunAction,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'f6a7b8c9-d0e1-2345-fabc-456789012345',
|
||||
label: 'Run my action',
|
||||
icon: 'IconPlayerPlay',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
ومثال يستخدم `CommandModal` لطلب التأكيد قبل التنفيذ:
|
||||
|
||||
```tsx src/front-components/delete-draft.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { CommandModal } from 'twenty-sdk/command';
|
||||
|
||||
const DeleteDraft = () => {
|
||||
const execute = async () => {
|
||||
// perform the deletion
|
||||
};
|
||||
|
||||
return (
|
||||
<CommandModal
|
||||
title="Delete draft?"
|
||||
subtitle="This action cannot be undone."
|
||||
execute={execute}
|
||||
confirmButtonText="Delete"
|
||||
confirmButtonAccent="danger"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'a7b8c9d0-e1f2-3456-abcd-567890123456',
|
||||
name: 'delete-draft',
|
||||
description: 'Deletes a draft with confirmation',
|
||||
component: DeleteDraft,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'b8c9d0e1-f2a3-4567-bcde-678901234567',
|
||||
label: 'Delete draft',
|
||||
icon: 'IconTrash',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### الوصول إلى سياق وقت التشغيل
|
||||
|
||||
داخل مكوّنك، استخدم خطافات SDK للوصول إلى المستخدم الحالي، والسجل، ومثيل المكوّن:
|
||||
@@ -858,6 +952,50 @@ export default defineFrontComponent({
|
||||
| `unmountFrontComponent()` | إلغاء تركيب المكوّن |
|
||||
| `updateProgress(progress)` | تحديث مؤشّر التقدّم |
|
||||
|
||||
فيما يلي مثال يستخدم واجهة برمجة تطبيقات المضيف لعرض Snackbar وإغلاق اللوحة الجانبية بعد اكتمال الإجراء:
|
||||
|
||||
```tsx src/front-components/archive-record.tsx
|
||||
import { defineFrontComponent, useRecordId } from 'twenty-sdk';
|
||||
import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const ArchiveRecord = () => {
|
||||
const recordId = useRecordId();
|
||||
|
||||
const handleArchive = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
updateTask: {
|
||||
__args: { id: recordId, data: { status: 'ARCHIVED' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
await enqueueSnackbar({
|
||||
message: 'Record archived',
|
||||
variant: 'success',
|
||||
});
|
||||
|
||||
await closeSidePanel();
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px' }}>
|
||||
<p>Archive this record?</p>
|
||||
<button onClick={handleArchive}>Archive</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'c9d0e1f2-a3b4-5678-cdef-789012345678',
|
||||
name: 'archive-record',
|
||||
description: 'Archives the current record',
|
||||
component: ArchiveRecord,
|
||||
});
|
||||
```
|
||||
|
||||
#### خيارات الأوامر
|
||||
|
||||
إضافة حقل `command` إلى `defineFrontComponent` تُسجِّل المكوّن في قائمة الأوامر (Cmd+K). إذا كانت قيمة `isPinned` هي `true`، فسيظهر أيضًا كزر إجراء سريع في الزاوية العلوية اليمنى من الصفحة.
|
||||
@@ -1712,3 +1850,86 @@ yarn twenty uninstall
|
||||
# Skip the confirmation prompt
|
||||
yarn twenty uninstall --yes
|
||||
```
|
||||
|
||||
## إدارة الريموتات
|
||||
|
||||
**الريموت** هو خادم Twenty يتصل به تطبيقك. أثناء الإعداد، تُنشئ أداة إنشاء الهيكل واحدًا لك تلقائيًا. يمكنك إضافة ريموتات أخرى أو التبديل بينها في أي وقت.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
تُخزَّن بيانات اعتمادك في `~/.twenty/config.json`.
|
||||
|
||||
## التكامل المستمر (CI) باستخدام GitHub Actions
|
||||
|
||||
تولّد أداة إنشاء الهيكل سير عمل GitHub Actions جاهزًا للاستخدام في `.github/workflows/ci.yml`. يشغّل اختبارات التكامل لديك تلقائيًا عند كل دفع إلى `main` وعلى طلبات السحب.
|
||||
|
||||
سير العمل:
|
||||
|
||||
1. يجلب الشيفرة الخاصة بك
|
||||
2. يشغّل خادم Twenty مؤقتًا باستخدام الإجراء `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. يثبّت التبعيات باستخدام `yarn install --immutable`
|
||||
4. يشغّل `yarn test` مع حقن `TWENTY_API_URL` و`TWENTY_API_KEY` من مخرجات الإجراء
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
لا تحتاج إلى تهيئة أي أسرار — إذ يبدأ إجراء `spawn-twenty-docker-image` خادم Twenty عابرًا مباشرة في المشغّل ويُخرِج تفاصيل الاتصال. يتم توفير السر `GITHUB_TOKEN` تلقائيًا من قِبل GitHub.
|
||||
|
||||
لتثبيت إصدار محدّد من Twenty بدلًا من `latest`، غيّر متغير البيئة `TWENTY_VERSION` في أعلى سير العمل.
|
||||
|
||||
@@ -7,7 +7,9 @@ description: أنشئ أول تطبيق Twenty خلال دقائق.
|
||||
التطبيقات حاليًا في مرحلة الألفا. الميزة تعمل لكنها لا تزال قيد التطور.
|
||||
</Warning>
|
||||
|
||||
تتيح لك التطبيقات توسيع Twenty باستخدام كائنات وحقول ووظائف منطقية ومهارات ذكاء اصطناعي ومكونات واجهة مستخدم مخصصة — جميعها تُدار ككود.
|
||||
## ما هي التطبيقات؟
|
||||
|
||||
تتيح لك التطبيقات توسيع Twenty باستخدام كائنات وحقول مخصّصة ووظائف منطقية ومكوّنات الواجهة الأمامية ومهارات الذكاء الاصطناعي وغير ذلك — جميعها تُدار ككود. بدلًا من تكوين كل شيء عبر واجهة المستخدم، تعرّف نموذج بياناتك ومنطقك في TypeScript وتقوم بنشره إلى مساحة عمل واحدة أو أكثر.
|
||||
|
||||
## المتطلبات الأساسية
|
||||
|
||||
@@ -17,7 +19,9 @@ description: أنشئ أول تطبيق Twenty خلال دقائق.
|
||||
* **Yarn 4** — يأتي مع Node.js عبر Corepack. قم بتمكينه عبر تشغيل `corepack enable`
|
||||
* **Docker** — [نزّل من هنا](https://www.docker.com/products/docker-desktop/). مطلوب لتشغيل مثيل محلي من Twenty. غير مطلوب إذا كان لديك خادم Twenty قيد التشغيل بالفعل.
|
||||
|
||||
## الخطوة 1: إنشاء هيكل تطبيقك
|
||||
## قم بإنشاء تطبيقك الأول
|
||||
|
||||
### أنشئ هيكل تطبيقك
|
||||
|
||||
افتح الطرفية وشغّل:
|
||||
|
||||
@@ -29,18 +33,7 @@ npx create-twenty-app@latest my-twenty-app
|
||||
|
||||
سيؤدي ذلك إلى إنشاء مجلد جديد باسم `my-twenty-app` يحتوي على كل ما تحتاجه.
|
||||
|
||||
<Note>
|
||||
أداة إنشاء الهيكل تدعم الأعلام التالية:
|
||||
|
||||
* `--minimal` — إنشاء الهيكل للملفات الأساسية فقط، بدون أمثلة (افتراضي)
|
||||
* `--exhaustive` — إنشاء الهيكل لجميع كيانات الأمثلة
|
||||
* `--name <name>` — تعيين اسم التطبيق (يتخطى المطالبة)
|
||||
* `--display-name <displayName>` — تعيين اسم العرض (يتخطى المطالبة)
|
||||
* `--description <description>` — تعيين الوصف (يتخطى المطالبة)
|
||||
* `--skip-local-instance` — تخطي مطالبة إعداد الخادم المحلي
|
||||
</Note>
|
||||
|
||||
## الخطوة 2: إعداد مثيل محلي من Twenty
|
||||
### إعداد مثيل محلي من Twenty
|
||||
|
||||
ستسأل أداة إنشاء الهيكل:
|
||||
|
||||
@@ -53,7 +46,7 @@ npx create-twenty-app@latest my-twenty-app
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="هل يجب بدء المثيل المحلي؟" />
|
||||
</div>
|
||||
|
||||
## الخطوة 3: سجّل الدخول إلى مساحة العمل الخاصة بك
|
||||
### سجّل الدخول إلى مساحة العمل الخاصة بك
|
||||
|
||||
بعد ذلك، ستُفتح نافذة متصفح تعرض صفحة تسجيل الدخول الخاصة بـ Twenty. سجّل الدخول باستخدام حساب العرض التوضيحي المُجهَّز مسبقًا:
|
||||
|
||||
@@ -64,7 +57,7 @@ npx create-twenty-app@latest my-twenty-app
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="شاشة تسجيل الدخول إلى Twenty" />
|
||||
</div>
|
||||
|
||||
## الخطوة 4: تفويض التطبيق
|
||||
### قم بتفويض التطبيق
|
||||
|
||||
بعد تسجيل الدخول، ستظهر لك شاشة تفويض. يتيح هذا لتطبيقك التفاعل مع مساحة العمل الخاصة بك.
|
||||
|
||||
@@ -80,7 +73,7 @@ npx create-twenty-app@latest my-twenty-app
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="تم إنشاء هيكل التطبيق بنجاح" />
|
||||
</div>
|
||||
|
||||
## الخطوة 5: ابدأ التطوير
|
||||
### ابدأ التطوير
|
||||
|
||||
انتقل إلى مجلد تطبيقك الجديد وابدأ خادم التطوير:
|
||||
|
||||
@@ -105,7 +98,7 @@ yarn twenty dev --verbose
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="مخرجات الطرفية في وضع التطوير" />
|
||||
</div>
|
||||
|
||||
## الخطوة 6: اعرض تطبيقك في Twenty
|
||||
### اعرض تطبيقك في Twenty
|
||||
|
||||
افتح [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) في متصفحك. انتقل إلى **Settings > Apps** واختر علامة التبويب **Developer**. يُفترض أن ترى تطبيقك مُدرجًا تحت **Your Apps**:
|
||||
|
||||
@@ -133,13 +126,28 @@ yarn twenty dev --verbose
|
||||
|
||||
أنت جاهز تمامًا! حرّر أي ملف في `src/` وسيتم التقاط التغييرات تلقائيًا.
|
||||
|
||||
انتقل إلى [بناء التطبيقات](/l/ar/developers/extend/apps/building) للحصول على دليل مفصّل حول إنشاء الكائنات، ودوال المنطق، ومكونات الواجهة الأمامية، والمهارات، والمزيد.
|
||||
---
|
||||
|
||||
## ما الذي يمكنك بناؤه
|
||||
|
||||
تتكون التطبيقات من **كيانات** — يُعرَّف كل منها كملف TypeScript يحتوي على `export default` واحد:
|
||||
|
||||
| كيان | ماذا يفعل |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------- |
|
||||
| **الكائنات والحقول** | عرّف نماذج بيانات مخصّصة (مثل Post Card، Invoice) مع حقول محددة النوع |
|
||||
| **الوظائف المنطقية** | دوال TypeScript على جانب الخادم يتم تشغيلها عبر مسارات HTTP، وجداول cron، أو أحداث قاعدة البيانات |
|
||||
| **المكوّنات الأمامية** | مكوّنات React تُعرَض داخل واجهة مستخدم Twenty (اللوحة الجانبية، الودجات، قائمة الأوامر) |
|
||||
| **المهارات والوكلاء** | قدرات الذكاء الاصطناعي — تعليمات قابلة لإعادة الاستخدام ومساعدون مستقلون ذاتيًا |
|
||||
| **طرق العرض والتنقّل** | طرق عرض القوائم مُعدّة مسبقًا وعناصر قائمة الشريط الجانبي لكائناتك |
|
||||
| **تخطيطات الصفحات** | صفحات تفاصيل سجلات مخصصة تتضمن علامات تبويب وعناصر واجهة |
|
||||
|
||||
انتقل إلى [بناء التطبيقات](/l/ar/developers/extend/apps/building) للاطلاع على دليل مفصّل لكل نوع من الكيانات.
|
||||
|
||||
---
|
||||
|
||||
## هيكل المشروع
|
||||
|
||||
تولّد أداة إنشاء الهيكل بنية الملفات التالية (مُبيّنة بوضع `--exhaustive` الذي يتضمن أمثلة لكل نوع من الكيانات):
|
||||
تولّد أداة إنشاء الهيكل بنية الملفات التالية:
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -148,160 +156,50 @@ my-twenty-app/
|
||||
.gitignore
|
||||
.nvmrc
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── 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
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── default-role.ts # Default role for logic functions
|
||||
├── constants/
|
||||
│ └── universal-identifiers.ts # Auto-generated UUIDs and app metadata
|
||||
└── __tests__/
|
||||
├── setup-test.ts # Test setup (server health check, config)
|
||||
└── app-install.integration-test.ts # Integration test
|
||||
```
|
||||
|
||||
افتراضيًا (`--minimal`)، تُنشأ الملفات الأساسية فقط: `application-config.ts`، `roles/default-role.ts`، `logic-functions/pre-install.ts`، و`logic-functions/post-install.ts`. استخدم `--exhaustive` لتضمين جميع ملفات الأمثلة الموضّحة أعلاه.
|
||||
### البدء من مثال
|
||||
|
||||
للبدء من مثال أكثر اكتمالًا يضم كائنات وحقولًا مخصّصة، ودوال المنطق، ومكوّنات الواجهة الأمامية، وغير ذلك، استخدم الخيار `--example`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
npx create-twenty-app@latest my-twenty-app --example postcard
|
||||
```
|
||||
|
||||
تُستمد الأمثلة من الدليل [twenty-apps/examples](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples) على GitHub. يمكنك أيضًا إنشاء هيكل لكيانات فردية داخل مشروع قائم باستخدام `yarn twenty add` (انظر [بناء التطبيقات](/l/ar/developers/extend/apps/building#scaffolding-entities-with-yarn-twenty-add)).
|
||||
|
||||
### الملفات الرئيسية
|
||||
|
||||
| ملف / مجلد | الغرض |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | يصرّح باسم تطبيقك وإصداره واعتماداته. يتضمن نصًا برمجيًا باسم `twenty` بحيث يمكنك تشغيل `yarn twenty help` للاطلاع على جميع الأوامر. |
|
||||
| `src/application-config.ts` | **مطلوب.** ملف الإعداد الرئيسي لتطبيقك. |
|
||||
| `src/roles/` | يعرِّف الأدوار التي تتحكم بما يمكن لدوال المنطق الوصول إليه. |
|
||||
| `src/logic-functions/` | دوال على جانب الخادم يتم تشغيلها عبر المسارات، وجداول cron، أو أحداث قاعدة البيانات. |
|
||||
| `src/front-components/` | مكونات React تُعرَض داخل واجهة مستخدم Twenty. |
|
||||
| `src/objects/` | تعريفات كائنات مخصّصة لتوسيع نموذج البيانات لديك. |
|
||||
| `src/fields/` | حقول مخصّصة تُضاف إلى الكائنات الموجودة. |
|
||||
| `src/views/` | تكوينات العروض المحفوظة. |
|
||||
| `src/navigation-menu-items/` | روابط مخصّصة في شريط التنقل الجانبي. |
|
||||
| `src/skills/` | مهارات توسّع قدرات وكلاء الذكاء الاصطناعي في Twenty. |
|
||||
| `src/agents/` | وكلاء ذكاء اصطناعي مع موجهات مخصّصة. |
|
||||
| `src/page-layouts/` | تخطيطات صفحات مخصّصة لعرض السجلات. |
|
||||
| `src/__tests__/` | اختبارات تكامل (إعداد + اختبار مثال). |
|
||||
| `public/` | أصول ثابتة (صور، خطوط) تُقدَّم مع تطبيقك. |
|
||||
| ملف / مجلد | الغرض |
|
||||
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | يصرّح باسم تطبيقك وإصداره واعتماداته. يتضمن نصًا برمجيًا باسم `twenty` بحيث يمكنك تشغيل `yarn twenty help` للاطلاع على جميع الأوامر. |
|
||||
| `src/application-config.ts` | **مطلوب.** ملف الإعداد الرئيسي لتطبيقك. |
|
||||
| `src/default-role.ts` | الدور الافتراضي الذي يتحكم بما يمكن لدوال المنطق الوصول إليه. |
|
||||
| `src/constants/universal-identifiers.ts` | معرّفات UUID وبيانات التعريف للتطبيق، والمولَّدة تلقائيًا (اسم العرض، الوصف). |
|
||||
| `src/__tests__/` | اختبارات تكامل (إعداد + اختبار مثال). |
|
||||
| `public/` | أصول ثابتة (صور، خطوط) تُقدَّم مع تطبيقك. |
|
||||
|
||||
## إدارة الريموتات
|
||||
## خادم التطوير المحلي
|
||||
|
||||
**الريموت** هو خادم Twenty يتصل به تطبيقك. أثناء الإعداد، تُنشئ أداة إنشاء الهيكل واحدًا لك تلقائيًا. يمكنك إضافة ريموتات أخرى أو التبديل بينها في أي وقت.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
تُخزَّن بيانات اعتمادك في `~/.twenty/config.json`.
|
||||
|
||||
## خادم التطوير المحلي (`yarn twenty server`)
|
||||
|
||||
يمكن لأداة سطر الأوامر (CLI) إدارة خادم Twenty محلي يعمل داخل Docker. هذا هو الخادم نفسه الذي يبدأ تلقائيًا عند إنشاء هيكل تطبيق باستخدام `create-twenty-app`، لكن يمكنك أيضًا إدارته يدويًا.
|
||||
|
||||
### بدء الخادم
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
سيؤدي ذلك إلى سحب صورة Docker `twentycrm/twenty-app-dev:latest` (إن لم تكن موجودة بالفعل)، وإنشاء حاوية باسم `twenty-app-dev`، وبدء تشغيلها على المنفذ **2020**. تنتظر أداة CLI حتى يجتاز الخادم فحص السلامة قبل الإنهاء.
|
||||
|
||||
يتم إنشاء حجمين في Docker للاحتفاظ بالبيانات بين عمليات إعادة التشغيل:
|
||||
|
||||
* `twenty-app-dev-data` — قاعدة بيانات PostgreSQL
|
||||
* `twenty-app-dev-storage` — تخزين ملفات
|
||||
|
||||
إذا كان المنفذ 2020 مستخدمًا بالفعل، يمكنك البدء على منفذ مختلف:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
تقوم أداة CLI تلقائيًا بتهيئة قيم `NODE_PORT` و`SERVER_URL` الداخلية في الحاوية لتطابق المنفذ المختار، بحيث تعمل دوال المنطق وOAuth وكل الشبكات الداخلية الأخرى بشكل صحيح.
|
||||
|
||||
بمجرد البدء، يُسجَّل الخادم تلقائيًا كـ `local` remote في إعدادات CLI لديك.
|
||||
|
||||
### التحقق من حالة الخادم
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
يعرض ما إذا كان الخادم قيد التشغيل، وعنوان URL الخاص به، وبيانات اعتماد تسجيل الدخول الافتراضية (`[email protected]` / `[email protected]`).
|
||||
|
||||
### عرض سجلات الخادم
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
يبث سجلات الحاوية. استخدم `--lines` للتحكّم بعدد الأسطر الحديثة المراد عرضها:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### إيقاف الخادم
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
يوقف الحاوية. تُحفَظ بياناتك في أحجام Docker — وستُستأنف الحالة مع عملية `start` التالية من حيث توقفت.
|
||||
|
||||
### إعادة تعيين الخادم
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
يزيل الحاوية **و** يحذف كلا حجمي Docker، ممّا يمحو جميع البيانات. ستنشئ عملية `start` التالية مثيلًا جديدًا من البداية.
|
||||
|
||||
<Note>
|
||||
يتطلّب الخادم أن يكون **Docker** قيد التشغيل. إذا ظهرت لك رسالة خطأ "Docker not running"، فتأكّد من تشغيل Docker Desktop (أو خادوم Docker).
|
||||
</Note>
|
||||
|
||||
### مرجع الأوامر
|
||||
لقد قامت أداة إنشاء الهيكل بالفعل بتشغيل خادم Twenty محليًا لك. لإدارته لاحقًا، استخدم `yarn twenty server`:
|
||||
|
||||
| أمر | الوصف |
|
||||
| -------------------------------------- | --------------------------------------------- |
|
||||
@@ -313,65 +211,11 @@ yarn twenty server reset
|
||||
| `yarn twenty server logs --lines 100` | عرض آخر 100 سطر من السجلات |
|
||||
| `yarn twenty server reset` | حذف جميع البيانات والبدء من جديد |
|
||||
|
||||
## التكامل المستمر (CI) باستخدام GitHub Actions
|
||||
يتم الاحتفاظ بالبيانات عبر عمليات إعادة التشغيل في وحدتي تخزين Docker (`twenty-app-dev-data` لـ PostgreSQL، و`twenty-app-dev-storage` للملفات). استخدم `reset` لمسح كل شيء والبدء من جديد.
|
||||
|
||||
تولّد أداة إنشاء الهيكل سير عمل GitHub Actions جاهزًا للاستخدام في `.github/workflows/ci.yml`. يشغّل اختبارات التكامل لديك تلقائيًا عند كل دفع إلى `main` وعلى طلبات السحب.
|
||||
|
||||
سير العمل:
|
||||
|
||||
1. يجلب الشيفرة الخاصة بك
|
||||
2. يشغّل خادم Twenty مؤقتًا باستخدام الإجراء `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. يثبّت الاعتمادات باستخدام `yarn install --immutable`
|
||||
4. يشغّل `yarn test` مع حقن `TWENTY_API_URL` و`TWENTY_API_KEY` من مخرجات الإجراء
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
لا تحتاج إلى تهيئة أي أسرار — إذ يبدأ إجراء `spawn-twenty-docker-image` خادم Twenty عابرًا مباشرة في المشغّل ويُخرِج تفاصيل الاتصال. يتم توفير السر `GITHUB_TOKEN` تلقائيًا من قِبل GitHub.
|
||||
|
||||
لتثبيت إصدار محدّد من Twenty بدلًا من `latest`، غيّر متغير البيئة `TWENTY_VERSION` في أعلى سير العمل.
|
||||
<Note>
|
||||
يتطلّب الخادم أن يكون **Docker** قيد التشغيل. إذا ظهرت لك رسالة خطأ "Docker not running"، فتأكّد من تشغيل Docker Desktop (أو خادوم Docker).
|
||||
</Note>
|
||||
|
||||
## إعداد يدوي (بدون المهيئ)
|
||||
|
||||
|
||||
@@ -52,7 +52,11 @@ yarn twenty deploy
|
||||
|
||||
### مشاركة تطبيق منشور
|
||||
|
||||
تطبيقات tarball لا تُدرَج في السوق العامة، لذا لن تكتشفها مساحات العمل الأخرى على الخادم نفسه عبر الاستعراض. لمشاركة تطبيق منشور:
|
||||
<Warning>
|
||||
تُعد مشاركة التطبيقات الخاصة (tarball) عبر مساحات العمل ميزة ضمن **Enterprise**. ستعرض علامة التبويب **Distribution** مطالبة بالترقية بدلًا من عناصر التحكم في المشاركة حتى تحتوي مساحة العمل لديك على مفتاح Enterprise صالح. اطلع على [الإعدادات > لوحة الإدارة > Enterprise](/settings/admin-panel#enterprise) لتنشيطه.
|
||||
</Warning>
|
||||
|
||||
تطبيقات tarball لا تُدرَج في السوق العامة، لذا لن تكتشفها مساحات العمل الأخرى على الخادم نفسه عبر الاستعراض. Once your workspace is on the Enterprise plan, you can share a deployed app like this:
|
||||
|
||||
1. اذهب إلى **الإعدادات > التطبيقات > التسجيلات** وافتح تطبيقك
|
||||
2. في علامة التبويب **التوزيع**، انقر **نسخ رابط المشاركة**
|
||||
@@ -60,10 +64,6 @@ yarn twenty deploy
|
||||
|
||||
يستخدم رابط المشاركة عنوان URL الأساسي للخادم (من دون أي نطاق فرعي لمساحة عمل)، لذا يعمل مع أي مساحة عمل على الخادم.
|
||||
|
||||
<Warning>
|
||||
مشاركة التطبيقات الخاصة هي ميزة ضمن باقة Enterprise. اذهب إلى [الإعدادات > لوحة الإدارة > Enterprise](/settings/admin-panel#enterprise) لتمكينها.
|
||||
</Warning>
|
||||
|
||||
### إدارة الإصدارات
|
||||
|
||||
لطرح تحديث:
|
||||
|
||||
@@ -81,7 +81,7 @@ import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
universalIdentifier: '39783023-bcac-41e3-b0d2-ff1944d8465d',
|
||||
displayName: 'My Twenty App',
|
||||
description: 'My first Twenty app',
|
||||
icon: 'IconWorld',
|
||||
@@ -717,6 +717,13 @@ Hlavní body:
|
||||
|
||||
Frontendové komponenty jsou React komponenty, které se vykreslují přímo v uživatelském rozhraní Twenty. Běží v **izolovaném Web Workeru** s využitím Remote DOM — váš kód je sandboxovaný, ale vykresluje se nativně na stránce, nikoli v iframu.
|
||||
|
||||
#### Kde lze použít front komponenty
|
||||
|
||||
Front komponenty se mohou vykreslovat na dvou místech v rámci Twenty:
|
||||
|
||||
* **Postranní panel** — Ne-headless front komponenty se otevírají v pravém postranním panelu. Toto je výchozí chování, když je front komponenta vyvolána z menu příkazů.
|
||||
* **Widgety (nástěnky a stránky záznamů)** — Front komponenty lze vkládat jako widgety do rozložení stránek. Při konfiguraci nástěnky nebo rozložení stránky záznamu mohou uživatelé přidat widget front komponenty.
|
||||
|
||||
#### Základní příklad
|
||||
|
||||
Nejrychlejší způsob, jak vidět frontendovou komponentu v akci, je zaregistrovat ji jako **příkaz**. Přidáním pole `command` s `isPinned: true` se zobrazí jako tlačítko rychlé akce v pravém horním rohu stránky — není potřeba žádné rozvržení stránky:
|
||||
@@ -774,9 +781,13 @@ Kliknutím na něj vykreslíte komponentu přímo ve stránce.
|
||||
|
||||
Mimo příkazy můžete frontendovou komponentu vložit přímo na stránku záznamu přidáním jako widget v **rozvržení stránky**. Podrobnosti viz sekce [definePageLayout](#definepagelayout).
|
||||
|
||||
#### Headless komponenty (`isHeadless: true`)
|
||||
#### Headless vs. ne-headless
|
||||
|
||||
Headless komponenty nevykreslují viditelné UI, ale stále spouštějí logiku Reactu. To je užitečné pro **efektové komponenty** — komponenty, které po připojení provádějí vedlejší efekty, jako je synchronizace dat, spuštění časovače, naslouchání událostem nebo vyvolání oznámení.
|
||||
Front komponenty existují ve dvou režimech vykreslování řízených volbou `isHeadless`:
|
||||
|
||||
**Ne-headless (výchozí)** — Komponenta vykreslí viditelné uživatelské rozhraní. Po vyvolání z menu příkazů se otevře v postranním panelu. Toto je výchozí chování, když je `isHeadless` `false` nebo když tato volba není uvedena.
|
||||
|
||||
**Headless (`isHeadless: true`)** — Komponenta se neviditelně inicializuje na pozadí. Neotevírá postranní panel. Headless komponenty jsou určené pro akce, které provedou logiku a poté se odpojí — například spuštění asynchronního úkolu, navigaci na stránku nebo zobrazení potvrzovacího modálního okna. Přirozeně se hodí ke komponentám SDK Command popsaným níže.
|
||||
|
||||
```tsx src/front-components/sync-tracker.tsx
|
||||
import { defineFrontComponent, useRecordId, enqueueSnackbar } from 'twenty-sdk';
|
||||
@@ -803,6 +814,89 @@ export default defineFrontComponent({
|
||||
|
||||
Protože komponenta vrací `null`, Twenty přeskočí vykreslení kontejneru — v rozvržení se neobjeví žádné prázdné místo. Komponenta má však stále přístup ke všem hookům a API komunikace s hostitelem.
|
||||
|
||||
#### Komponenty SDK Command
|
||||
|
||||
Balíček `twenty-sdk` poskytuje čtyři pomocné komponenty Command navržené pro headless front komponenty. Každá komponenta při připojení provede akci, chyby zpracuje zobrazením oznámení ve snackbaru a po dokončení automaticky odpojí front komponentu.
|
||||
|
||||
Importujte je z `twenty-sdk/command`:
|
||||
|
||||
* **`Command`** — Spustí asynchronní callback přes prop `execute`.
|
||||
* **`CommandLink`** — Naviguje na cestu v aplikaci. Props: `to`, `params`, `queryParams`, `options`.
|
||||
* **`CommandModal`** — Otevře potvrzovací modální okno. Pokud uživatel potvrdí, provede callback `execute`. Props: `title`, `subtitle`, `execute`, `confirmButtonText`, `confirmButtonAccent`.
|
||||
* **`CommandOpenSidePanelPage`** — Otevře konkrétní stránku postranního panelu. Props: `page`, `pageTitle`, `pageIcon`.
|
||||
|
||||
Zde je kompletní příklad headless front komponenty, která pomocí `Command` spouští akci z menu příkazů:
|
||||
|
||||
```tsx src/front-components/run-action.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { Command } from 'twenty-sdk/command';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const RunAction = () => {
|
||||
const execute = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
createTask: {
|
||||
__args: { data: { title: 'Created by my app' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return <Command execute={execute} />;
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'e5f6a7b8-c9d0-1234-efab-345678901234',
|
||||
name: 'run-action',
|
||||
description: 'Creates a task from the command menu',
|
||||
component: RunAction,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'f6a7b8c9-d0e1-2345-fabc-456789012345',
|
||||
label: 'Run my action',
|
||||
icon: 'IconPlayerPlay',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
A příklad s použitím `CommandModal` k vyžádání potvrzení před provedením:
|
||||
|
||||
```tsx src/front-components/delete-draft.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { CommandModal } from 'twenty-sdk/command';
|
||||
|
||||
const DeleteDraft = () => {
|
||||
const execute = async () => {
|
||||
// perform the deletion
|
||||
};
|
||||
|
||||
return (
|
||||
<CommandModal
|
||||
title="Delete draft?"
|
||||
subtitle="This action cannot be undone."
|
||||
execute={execute}
|
||||
confirmButtonText="Delete"
|
||||
confirmButtonAccent="danger"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'a7b8c9d0-e1f2-3456-abcd-567890123456',
|
||||
name: 'delete-draft',
|
||||
description: 'Deletes a draft with confirmation',
|
||||
component: DeleteDraft,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'b8c9d0e1-f2a3-4567-bcde-678901234567',
|
||||
label: 'Delete draft',
|
||||
icon: 'IconTrash',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### Přístup k běhovému kontextu
|
||||
|
||||
Uvnitř komponenty použijte hooky SDK pro přístup k aktuálnímu uživateli, záznamu a instanci komponenty:
|
||||
@@ -859,6 +953,50 @@ Frontendové komponenty mohou pomocí funkcí z `twenty-sdk` vyvolávat navigaci
|
||||
| `unmountFrontComponent()` | Odmontovat komponentu |
|
||||
| `updateProgress(progress)` | Aktualizovat indikátor průběhu |
|
||||
|
||||
Zde je příklad, který používá hostitelské API k zobrazení snackbaru a zavření postranního panelu po dokončení akce:
|
||||
|
||||
```tsx src/front-components/archive-record.tsx
|
||||
import { defineFrontComponent, useRecordId } from 'twenty-sdk';
|
||||
import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const ArchiveRecord = () => {
|
||||
const recordId = useRecordId();
|
||||
|
||||
const handleArchive = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
updateTask: {
|
||||
__args: { id: recordId, data: { status: 'ARCHIVED' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
await enqueueSnackbar({
|
||||
message: 'Record archived',
|
||||
variant: 'success',
|
||||
});
|
||||
|
||||
await closeSidePanel();
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px' }}>
|
||||
<p>Archive this record?</p>
|
||||
<button onClick={handleArchive}>Archive</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'c9d0e1f2-a3b4-5678-cdef-789012345678',
|
||||
name: 'archive-record',
|
||||
description: 'Archives the current record',
|
||||
component: ArchiveRecord,
|
||||
});
|
||||
```
|
||||
|
||||
#### Možnosti příkazu
|
||||
|
||||
Přidání pole `command` do `defineFrontComponent` zaregistruje komponentu v příkazovém menu (Cmd+K). Pokud je `isPinned` nastaveno na `true`, zobrazí se také jako tlačítko rychlé akce v pravém horním rohu stránky.
|
||||
@@ -1713,3 +1851,86 @@ yarn twenty uninstall
|
||||
# Skip the confirmation prompt
|
||||
yarn twenty uninstall --yes
|
||||
```
|
||||
|
||||
## Správa vzdálených serverů
|
||||
|
||||
**Remote** je server Twenty, ke kterému se vaše aplikace připojuje. Během nastavení jej generátor kostry automaticky vytvoří. Můžete kdykoli přidat další vzdálené servery nebo mezi nimi přepínat.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Vaše přihlašovací údaje jsou uloženy v `~/.twenty/config.json`.
|
||||
|
||||
## CI s GitHub Actions
|
||||
|
||||
Generátor kostry vytvoří připravený k použití workflow GitHub Actions v `.github/workflows/ci.yml`. Automaticky spouští integrační testy při každém pushi do `main` a u pull requestů.
|
||||
|
||||
Workflow:
|
||||
|
||||
1. Načte váš kód (checkout).
|
||||
2. Spustí dočasný server Twenty pomocí akce `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. Nainstaluje závislosti pomocí `yarn install --immutable`
|
||||
4. Spustí `yarn test` s proměnnými `TWENTY_API_URL` a `TWENTY_API_KEY` vloženými z výstupů akce
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Není potřeba konfigurovat žádné secrets — akce `spawn-twenty-docker-image` spustí efemérní server Twenty přímo v runneru a vypíše podrobnosti připojení. Secret `GITHUB_TOKEN` je poskytován GitHubem automaticky.
|
||||
|
||||
Chcete-li připnout konkrétní verzi Twenty místo `latest`, změňte proměnnou prostředí `TWENTY_VERSION` na začátku workflow.
|
||||
|
||||
@@ -7,7 +7,9 @@ description: Vytvořte svou první aplikaci Twenty během několika minut.
|
||||
Aplikace jsou aktuálně v alfa fázi. Funkce funguje, ale stále se vyvíjí.
|
||||
</Warning>
|
||||
|
||||
Aplikace vám umožňují rozšířit Twenty o vlastní objekty, pole, logické funkce, AI schopnosti a komponenty uživatelského rozhraní — vše je spravováno jako kód.
|
||||
## Co jsou aplikace?
|
||||
|
||||
Aplikace vám umožňují rozšířit Twenty o vlastní objekty, pole, logické funkce, frontendové komponenty, AI schopnosti a další — vše je spravováno jako kód. Místo konfigurace všeho přes uživatelské rozhraní definujete v TypeScriptu svůj datový model a logiku a nasadíte je do jednoho nebo více pracovních prostorů.
|
||||
|
||||
## Předpoklady
|
||||
|
||||
@@ -17,7 +19,9 @@ Než začnete, ujistěte se, že máte ve svém počítači nainstalováno násl
|
||||
* **Yarn 4** — Dodává se s Node.js prostřednictvím Corepacku. Povolte jej spuštěním `corepack enable`
|
||||
* **Docker** — [Stáhnout zde](https://www.docker.com/products/docker-desktop/). Nutné pro spuštění lokální instance Twenty. Není potřeba, pokud už máte spuštěný server Twenty.
|
||||
|
||||
## Krok 1: Vytvořte kostru své aplikace
|
||||
## Vytvořte svou první aplikaci
|
||||
|
||||
### Vytvořte kostru své aplikace
|
||||
|
||||
Otevřete terminál a spusťte:
|
||||
|
||||
@@ -29,18 +33,7 @@ Budete vyzváni k zadání názvu a popisu své aplikace. Stisknutím **Enter**
|
||||
|
||||
Tím se vytvoří nová složka s názvem `my-twenty-app` se vším potřebným.
|
||||
|
||||
<Note>
|
||||
Generátor kostry podporuje tyto přepínače:
|
||||
|
||||
* `--minimal` — vygeneruje pouze nezbytné soubory, bez příkladů (výchozí)
|
||||
* `--exhaustive` — vygeneruje všechny ukázkové entity
|
||||
* `--name <name>` — nastaví název aplikace (přeskočí výzvu)
|
||||
* `--display-name <displayName>` — nastaví zobrazovaný název (přeskočí výzvu)
|
||||
* `--description <description>` — nastaví popis (přeskočí výzvu)
|
||||
* `--skip-local-instance` — přeskočí výzvu k nastavení lokálního serveru
|
||||
</Note>
|
||||
|
||||
## Krok 2: Nastavte lokální instanci Twenty
|
||||
### Nastavte lokální instanci Twenty
|
||||
|
||||
Generátor kostry se zeptá:
|
||||
|
||||
@@ -53,7 +46,7 @@ Generátor kostry se zeptá:
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Spustit lokální instanci?" />
|
||||
</div>
|
||||
|
||||
## Krok 3: Přihlaste se do svého pracovního prostoru
|
||||
### Přihlaste se do svého pracovního prostoru
|
||||
|
||||
Poté se otevře okno prohlížeče se stránkou přihlášení do Twenty. Přihlaste se předpřipraveným demo účtem:
|
||||
|
||||
@@ -64,7 +57,7 @@ Poté se otevře okno prohlížeče se stránkou přihlášení do Twenty. Přih
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Přihlašovací obrazovka Twenty" />
|
||||
</div>
|
||||
|
||||
## Krok 4: Autorizujte aplikaci
|
||||
### Autorizujte aplikaci
|
||||
|
||||
Po přihlášení uvidíte autorizační obrazovku. Tím umožníte vaší aplikaci pracovat s vaším pracovním prostorem.
|
||||
|
||||
@@ -80,7 +73,7 @@ Po autorizaci váš terminál potvrdí, že je vše nastaveno.
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="Aplikace byla úspěšně vygenerována" />
|
||||
</div>
|
||||
|
||||
## Krok 5: Začněte vyvíjet
|
||||
### Začněte vyvíjet
|
||||
|
||||
Přejděte do nové složky aplikace a spusťte vývojový server:
|
||||
|
||||
@@ -105,7 +98,7 @@ Vývojový režim je k dispozici pouze na instancích Twenty běžících v rež
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Výstup terminálu ve vývojovém režimu" />
|
||||
</div>
|
||||
|
||||
## Krok 6: Zobrazte svou aplikaci v Twenty
|
||||
### Zobrazte svou aplikaci v Twenty
|
||||
|
||||
Otevřete ve svém prohlížeči [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer). Přejděte do **Settings > Apps** a vyberte kartu **Developer**. Vaše aplikace by měla být uvedena v části **Your Apps**:
|
||||
|
||||
@@ -133,13 +126,28 @@ Přepněte na kartu **Content**, abyste viděli vše, co vaše aplikace poskytuj
|
||||
|
||||
Vše je připraveno! Upravte libovolný soubor v `src/` a změny se automaticky projeví.
|
||||
|
||||
Přejděte na [Tvorba aplikací](/l/cs/developers/extend/apps/building) pro podrobný průvodce vytvářením objektů, logických funkcí, frontendových komponent, dovedností a dalšího.
|
||||
---
|
||||
|
||||
## Co můžete vytvořit
|
||||
|
||||
Aplikace se skládají z **entit** — každá je definována jako soubor TypeScriptu s jediným `export default`:
|
||||
|
||||
| Entita | K čemu slouží |
|
||||
| -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Objekty a pole** | Definujte vlastní datové modely (např. Post Card, Invoice) s typovanými poli |
|
||||
| **Logické funkce** | Serverové funkce v TypeScriptu spouštěné HTTP trasami, plánovačem cron nebo událostmi databáze |
|
||||
| **Frontendové komponenty** | Komponenty Reactu, které se vykreslují v uživatelském rozhraní Twenty (postranní panel, widgety, příkazová nabídka) |
|
||||
| **Dovednosti a agenti** | Schopnosti AI — opakovaně použitelné pokyny a autonomní asistenti |
|
||||
| **Pohledy a navigace** | Předkonfigurované seznamové pohledy a položky postranní nabídky pro vaše objekty |
|
||||
| **Rozvržení stránek** | Vlastní stránky detailu záznamu s kartami a widgety |
|
||||
|
||||
Přejděte na [Tvorba aplikací](/l/cs/developers/extend/apps/building) pro podrobný průvodce každým typem entity.
|
||||
|
||||
---
|
||||
|
||||
## Struktura projektu
|
||||
|
||||
Generátor kostry vytvoří následující strukturu souborů (zobrazeno v režimu `--exhaustive`, který zahrnuje příklady pro každý typ entity):
|
||||
Nástroj pro vytvoření kostry vygeneruje následující strukturu souborů:
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -148,160 +156,50 @@ my-twenty-app/
|
||||
.gitignore
|
||||
.nvmrc
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── 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
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── default-role.ts # Default role for logic functions
|
||||
├── constants/
|
||||
│ └── universal-identifiers.ts # Auto-generated UUIDs and app metadata
|
||||
└── __tests__/
|
||||
├── setup-test.ts # Test setup (server health check, config)
|
||||
└── app-install.integration-test.ts # Integration test
|
||||
```
|
||||
|
||||
Ve výchozím nastavení (`--minimal`) se vytvoří pouze základní soubory: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` a `logic-functions/post-install.ts`. Pro zahrnutí všech ukázkových souborů výše použijte `--exhaustive`.
|
||||
### Začínáme s příkladem
|
||||
|
||||
Chcete-li začít s úplnějším příkladem s vlastními objekty, poli, logickými funkcemi, frontendovými komponentami a dalšími, použijte přepínač `--example`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
npx create-twenty-app@latest my-twenty-app --example postcard
|
||||
```
|
||||
|
||||
Příklady pocházejí z adresáře [twenty-apps/examples](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples) na GitHubu. Můžete také vytvořit kostru jednotlivých entit v existujícím projektu pomocí `yarn twenty add` (viz [Tvorba aplikací](/l/cs/developers/extend/apps/building#scaffolding-entities-with-yarn-twenty-add)).
|
||||
|
||||
### Klíčové soubory
|
||||
|
||||
| Soubor / Složka | Účel |
|
||||
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `package.json` | Definuje název, verzi a závislosti vaší aplikace. Obsahuje skript `twenty`, takže můžete spustit `yarn twenty help` a zobrazit všechny příkazy. |
|
||||
| `src/application-config.ts` | **Povinné.** Hlavní konfigurační soubor vaší aplikace. |
|
||||
| `src/roles/` | Definuje role, které určují, k čemu mají vaše logické funkce přístup. |
|
||||
| `src/logic-functions/` | Serverové funkce spouštěné trasami, plánovačem cron nebo událostmi databáze. |
|
||||
| `src/front-components/` | Komponenty Reactu, které se vykreslují uvnitř uživatelského rozhraní Twenty. |
|
||||
| `src/objects/` | Vlastní definice objektů pro rozšíření vašeho datového modelu. |
|
||||
| `src/fields/` | Vlastní pole přidaná k existujícím objektům. |
|
||||
| `src/views/` | Konfigurace uložených zobrazení. |
|
||||
| `src/navigation-menu-items/` | Vlastní odkazy v postranní navigaci. |
|
||||
| `src/skills/` | Dovednosti, které rozšiřují možnosti AI agentů Twenty. |
|
||||
| `src/agents/` | AI agenti s vlastními prompty. |
|
||||
| `src/page-layouts/` | Vlastní rozvržení stránek pro zobrazení záznamů. |
|
||||
| `src/__tests__/` | Integrační testy (nastavení + ukázkový test). |
|
||||
| `public/` | Statická aktiva (obrázky, písma) poskytovaná s vaší aplikací. |
|
||||
| Soubor / Složka | Účel |
|
||||
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `package.json` | Definuje název, verzi a závislosti vaší aplikace. Obsahuje skript `twenty`, takže můžete spustit `yarn twenty help` a zobrazit všechny příkazy. |
|
||||
| `src/application-config.ts` | **Povinné.** Hlavní konfigurační soubor vaší aplikace. |
|
||||
| `src/default-role.ts` | Výchozí role, která určuje, k čemu mají vaše logické funkce přístup. |
|
||||
| `src/constants/universal-identifiers.ts` | Automaticky generovaná UUID a metadata aplikace (zobrazovaný název, popis). |
|
||||
| `src/__tests__/` | Integrační testy (nastavení + ukázkový test). |
|
||||
| `public/` | Statická aktiva (obrázky, písma) poskytovaná s vaší aplikací. |
|
||||
|
||||
## Správa vzdálených serverů
|
||||
## Lokální vývojový server
|
||||
|
||||
**Remote** je server Twenty, ke kterému se vaše aplikace připojuje. Během nastavení jej generátor kostry automaticky vytvoří. Můžete kdykoli přidat další vzdálené servery nebo mezi nimi přepínat.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Vaše přihlašovací údaje jsou uloženy v `~/.twenty/config.json`.
|
||||
|
||||
## Lokální vývojový server (`yarn twenty server`)
|
||||
|
||||
CLI může spravovat lokální server Twenty běžící v Dockeru. Jde o stejný server, který se spustí automaticky při vytvoření kostry aplikace pomocí `create-twenty-app`, ale můžete jej spravovat i ručně.
|
||||
|
||||
### Spuštění serveru
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
Stáhne image Dockeru `twentycrm/twenty-app-dev:latest` (pokud již není k dispozici), vytvoří kontejner s názvem `twenty-app-dev` a spustí jej na portu **2020**. CLI čeká, dokud server neprojde kontrolou stavu, než vrátí řízení.
|
||||
|
||||
Vytvoří se dva svazky Dockeru pro zachování dat mezi restartováními:
|
||||
|
||||
* `twenty-app-dev-data` — databáze PostgreSQL
|
||||
* `twenty-app-dev-storage` — úložiště souborů
|
||||
|
||||
Pokud je port 2020 již používán, můžete spustit na jiném portu:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
CLI automaticky nakonfiguruje interní `NODE_PORT` a `SERVER_URL` kontejneru tak, aby odpovídaly zvolenému portu, takže logické funkce, OAuth a veškerá ostatní vnitřní síťová komunikace fungují správně.
|
||||
|
||||
Po spuštění je server automaticky zaregistrován jako `local` remote ve vaší konfiguraci CLI.
|
||||
|
||||
### Kontrola stavu serveru
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Zobrazí, zda server běží, jeho URL a výchozí přihlašovací údaje (`[email protected]` / `[email protected]`).
|
||||
|
||||
### Zobrazení protokolů serveru
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Streamuje protokoly kontejneru. Pomocí `--lines` ovládnete, kolik posledních řádků se má zobrazit:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Zastavení serveru
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Zastaví kontejner. Vaše data jsou zachována ve svazcích Dockeru — další `start` naváže tam, kde jste skončili.
|
||||
|
||||
### Resetování serveru
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Odstraní kontejner **a** smaže oba svazky Dockeru, čímž vymaže všechna data. Další `start` vytvoří čistou instanci.
|
||||
|
||||
<Note>
|
||||
Server vyžaduje, aby **Docker** běžel. Pokud vidíte chybu "Docker not running", ujistěte se, že je spuštěný Docker Desktop (nebo démon Dockeru).
|
||||
</Note>
|
||||
|
||||
### Přehled příkazů
|
||||
Nástroj pro vytvoření kostry vám již spustil lokální server Twenty. Pro jeho správu později použijte `yarn twenty server`:
|
||||
|
||||
| Příkaz | Popis |
|
||||
| -------------------------------------- | ------------------------------------------------------ |
|
||||
@@ -313,65 +211,11 @@ Odstraní kontejner **a** smaže oba svazky Dockeru, čímž vymaže všechna da
|
||||
| `yarn twenty server logs --lines 100` | Zobrazí posledních 100 řádků logu |
|
||||
| `yarn twenty server reset` | Smaže všechna data a začne znovu |
|
||||
|
||||
## CI s GitHub Actions
|
||||
Data přetrvávají při restartech ve dvou svazcích Dockeru (`twenty-app-dev-data` pro PostgreSQL, `twenty-app-dev-storage` pro soubory). Pomocí `reset` vymažte vše a začněte znovu.
|
||||
|
||||
Generátor kostry vytvoří připravený k použití workflow GitHub Actions v `.github/workflows/ci.yml`. Automaticky spouští integrační testy při každém pushi do `main` a u pull requestů.
|
||||
|
||||
Workflow:
|
||||
|
||||
1. Načte váš kód (checkout).
|
||||
2. Spustí dočasný server Twenty pomocí akce `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. Nainstaluje závislosti pomocí `yarn install --immutable`
|
||||
4. Spustí `yarn test` s proměnnými `TWENTY_API_URL` a `TWENTY_API_KEY` vloženými z výstupů akce
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Není potřeba konfigurovat žádné secrets — akce `spawn-twenty-docker-image` spustí efemérní server Twenty přímo v runneru a vypíše podrobnosti připojení. Secret `GITHUB_TOKEN` je poskytován GitHubem automaticky.
|
||||
|
||||
Chcete-li připnout konkrétní verzi Twenty místo `latest`, změňte proměnnou prostředí `TWENTY_VERSION` na začátku workflow.
|
||||
<Note>
|
||||
Server vyžaduje, aby **Docker** běžel. Pokud vidíte chybu "Docker not running", ujistěte se, že je spuštěný Docker Desktop (nebo démon Dockeru).
|
||||
</Note>
|
||||
|
||||
## Ruční nastavení (bez scaffolderu)
|
||||
|
||||
|
||||
@@ -52,7 +52,11 @@ yarn twenty deploy
|
||||
|
||||
### Sdílení nasazené aplikace
|
||||
|
||||
Aplikace ve formě tarball nejsou uvedeny ve veřejném tržišti, takže je ostatní pracovní prostory na tomtéž serveru procházením neobjeví. Chcete-li sdílet nasazenou aplikaci:
|
||||
<Warning>
|
||||
Sdílení soukromých (tarball) aplikací napříč pracovními prostory je funkcí plánu **Enterprise**. Karta **Distribution** bude místo ovládacích prvků sdílení zobrazovat výzvu k upgradu, dokud váš pracovní prostor nebude mít platný klíč Enterprise. Přejděte do [Nastavení > Admin Panel > Enterprise](/settings/admin-panel#enterprise) a aktivujte ji.
|
||||
</Warning>
|
||||
|
||||
Aplikace ve formě tarball nejsou uvedeny ve veřejném tržišti, takže je ostatní pracovní prostory na tomtéž serveru procházením neobjeví. Once your workspace is on the Enterprise plan, you can share a deployed app like this:
|
||||
|
||||
1. Přejděte do **Nastavení > Aplikace > Registrace** a otevřete svou aplikaci
|
||||
2. Na kartě **Distribuce** klikněte na **Zkopírovat odkaz ke sdílení**
|
||||
@@ -60,10 +64,6 @@ Aplikace ve formě tarball nejsou uvedeny ve veřejném tržišti, takže je ost
|
||||
|
||||
Odkaz ke sdílení používá základní adresu URL serveru (bez jakékoli subdomény pracovního prostoru), takže funguje pro libovolný pracovní prostor na serveru.
|
||||
|
||||
<Warning>
|
||||
Sdílení soukromých aplikací je funkce Enterprise. Přejděte do [Nastavení > Admin Panel > Enterprise](/settings/admin-panel#enterprise) a povolte ji.
|
||||
</Warning>
|
||||
|
||||
### Správa verzí
|
||||
|
||||
Chcete-li vydat aktualizaci:
|
||||
|
||||
@@ -81,7 +81,7 @@ import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
universalIdentifier: '39783023-bcac-41e3-b0d2-ff1944d8465d',
|
||||
displayName: 'My Twenty App',
|
||||
description: 'My first Twenty app',
|
||||
icon: 'IconWorld',
|
||||
@@ -716,6 +716,13 @@ Hauptpunkte:
|
||||
|
||||
Frontend-Komponenten sind React-Komponenten, die direkt innerhalb der Twenty-UI gerendert werden. Sie laufen in einem **isolierten Web Worker** unter Verwendung von Remote DOM — Ihr Code wird in einer Sandbox ausgeführt, rendert jedoch nativ auf der Seite, nicht in einem iframe.
|
||||
|
||||
#### Wo Front-Komponenten verwendet werden können
|
||||
|
||||
Front-Komponenten können an zwei Stellen innerhalb von Twenty gerendert werden:
|
||||
|
||||
* **Seitenpanel** — Nicht-Headless-Front-Komponenten werden im rechten Seitenpanel geöffnet. Dies ist das Standardverhalten, wenn eine Front-Komponente über das Befehlsmenü ausgelöst wird.
|
||||
* **Widgets (Dashboards und Datensatzseiten)** — Front-Komponenten können als Widgets in Seitenlayouts eingebettet werden. Beim Konfigurieren eines Dashboards oder eines Datensatzseiten-Layouts können Benutzer ein Front-Komponenten-Widget hinzufügen.
|
||||
|
||||
#### Einfaches Beispiel
|
||||
|
||||
Der schnellste Weg, eine Frontend-Komponente in Aktion zu sehen, ist, sie als Befehl zu registrieren. Das Hinzufügen eines `command`-Felds mit `isPinned: true` lässt sie als Schnellaktionsschaltfläche oben rechts auf der Seite erscheinen — kein Seitenlayout erforderlich:
|
||||
@@ -773,9 +780,13 @@ Klicken Sie darauf, um die Komponente inline zu rendern.
|
||||
|
||||
Über Befehle hinaus können Sie eine Frontend-Komponente direkt in eine Datensatzseite einbetten, indem Sie sie als Widget in einem **Seitenlayout** hinzufügen. Details finden Sie im Abschnitt [definePageLayout](#definepagelayout).
|
||||
|
||||
#### Headless-Komponenten (`isHeadless: true`)
|
||||
#### Headless vs. Nicht-Headless
|
||||
|
||||
Headless-Komponenten rendern keine sichtbare UI, führen aber dennoch React-Logik aus. Dies ist nützlich für **Effekt-Komponenten** — Komponenten, die beim Mounten Seiteneffekte ausführen, wie z. B. das Synchronisieren von Daten, Starten eines Timers, Lauschen auf Ereignisse oder Auslösen einer Benachrichtigung.
|
||||
Front-Komponenten gibt es in zwei Rendering-Modi, die durch die Option `isHeadless` gesteuert werden:
|
||||
|
||||
**Nicht-Headless (Standard)** — Die Komponente rendert eine sichtbare UI. Wird sie über das Befehlsmenü ausgelöst, öffnet sie sich im Seitenpanel. Dies ist das Standardverhalten, wenn `isHeadless` `false` ist oder weggelassen wird.
|
||||
|
||||
**Headless (`isHeadless: true`)** — Die Komponente wird unsichtbar im Hintergrund gemountet. Sie öffnet das Seitenpanel nicht. Headless-Komponenten sind für Aktionen konzipiert, die Logik ausführen und sich anschließend selbst unmounten — zum Beispiel das Ausführen einer asynchronen Aufgabe, das Navigieren zu einer Seite oder das Anzeigen eines Bestätigungsdialogs. Sie lassen sich gut mit den unten beschriebenen SDK-Command-Komponenten kombinieren.
|
||||
|
||||
```tsx src/front-components/sync-tracker.tsx
|
||||
import { defineFrontComponent, useRecordId, enqueueSnackbar } from 'twenty-sdk';
|
||||
@@ -802,6 +813,89 @@ export default defineFrontComponent({
|
||||
|
||||
Da die Komponente `null` zurückgibt, überspringt Twenty das Rendern eines Containers dafür — im Layout entsteht kein Leerraum. Die Komponente hat dennoch Zugriff auf alle Hooks und die Host-Kommunikations-API.
|
||||
|
||||
#### SDK-Command-Komponenten
|
||||
|
||||
Das Paket `twenty-sdk` stellt vier Command-Hilfskomponenten bereit, die für Headless-Front-Komponenten ausgelegt sind. Jede Komponente führt beim Mounten eine Aktion aus, behandelt Fehler durch Anzeige einer Snackbar-Benachrichtigung und unmountet die Front-Komponente nach Abschluss automatisch.
|
||||
|
||||
Importieren Sie sie aus `twenty-sdk/command`:
|
||||
|
||||
* **`Command`** — Führt einen asynchronen Callback über das Prop `execute` aus.
|
||||
* **`CommandLink`** — Navigiert zu einem App-Pfad. Props: `to`, `params`, `queryParams`, `options`.
|
||||
* **`CommandModal`** — Öffnet einen Bestätigungsdialog. Bestätigt der Benutzer, wird der Callback `execute` ausgeführt. Props: `title`, `subtitle`, `execute`, `confirmButtonText`, `confirmButtonAccent`.
|
||||
* **`CommandOpenSidePanelPage`** — Öffnet eine bestimmte Seite im Seitenpanel. Props: `page`, `pageTitle`, `pageIcon`.
|
||||
|
||||
Hier ist ein vollständiges Beispiel einer Headless-Front-Komponente, die `Command` verwendet, um eine Aktion aus dem Befehlsmenü auszuführen:
|
||||
|
||||
```tsx src/front-components/run-action.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { Command } from 'twenty-sdk/command';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const RunAction = () => {
|
||||
const execute = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
createTask: {
|
||||
__args: { data: { title: 'Created by my app' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return <Command execute={execute} />;
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'e5f6a7b8-c9d0-1234-efab-345678901234',
|
||||
name: 'run-action',
|
||||
description: 'Creates a task from the command menu',
|
||||
component: RunAction,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'f6a7b8c9-d0e1-2345-fabc-456789012345',
|
||||
label: 'Run my action',
|
||||
icon: 'IconPlayerPlay',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Und ein Beispiel, das `CommandModal` verwendet, um vor der Ausführung um Bestätigung zu bitten:
|
||||
|
||||
```tsx src/front-components/delete-draft.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { CommandModal } from 'twenty-sdk/command';
|
||||
|
||||
const DeleteDraft = () => {
|
||||
const execute = async () => {
|
||||
// perform the deletion
|
||||
};
|
||||
|
||||
return (
|
||||
<CommandModal
|
||||
title="Delete draft?"
|
||||
subtitle="This action cannot be undone."
|
||||
execute={execute}
|
||||
confirmButtonText="Delete"
|
||||
confirmButtonAccent="danger"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'a7b8c9d0-e1f2-3456-abcd-567890123456',
|
||||
name: 'delete-draft',
|
||||
description: 'Deletes a draft with confirmation',
|
||||
component: DeleteDraft,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'b8c9d0e1-f2a3-4567-bcde-678901234567',
|
||||
label: 'Delete draft',
|
||||
icon: 'IconTrash',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### Zugriff auf den Laufzeitkontext
|
||||
|
||||
Verwenden Sie innerhalb Ihrer Komponente SDK-Hooks, um auf den aktuellen Benutzer, den Datensatz und die Komponenteninstanz zuzugreifen:
|
||||
@@ -858,6 +952,50 @@ Frontend-Komponenten können Navigation, Modals und Benachrichtigungen mittels F
|
||||
| `unmountFrontComponent()` | Die Komponente entfernen |
|
||||
| `updateProgress(progress)` | Einen Fortschrittsindikator aktualisieren |
|
||||
|
||||
Hier ist ein Beispiel, das die Host-API verwendet, um nach Abschluss einer Aktion eine Snackbar anzuzeigen und das Seitenpanel zu schließen:
|
||||
|
||||
```tsx src/front-components/archive-record.tsx
|
||||
import { defineFrontComponent, useRecordId } from 'twenty-sdk';
|
||||
import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const ArchiveRecord = () => {
|
||||
const recordId = useRecordId();
|
||||
|
||||
const handleArchive = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
updateTask: {
|
||||
__args: { id: recordId, data: { status: 'ARCHIVED' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
await enqueueSnackbar({
|
||||
message: 'Record archived',
|
||||
variant: 'success',
|
||||
});
|
||||
|
||||
await closeSidePanel();
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px' }}>
|
||||
<p>Archive this record?</p>
|
||||
<button onClick={handleArchive}>Archive</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'c9d0e1f2-a3b4-5678-cdef-789012345678',
|
||||
name: 'archive-record',
|
||||
description: 'Archives the current record',
|
||||
component: ArchiveRecord,
|
||||
});
|
||||
```
|
||||
|
||||
#### Befehlsoptionen
|
||||
|
||||
Das Hinzufügen eines `command`-Felds zu `defineFrontComponent` registriert die Komponente im Befehlsmenü (Cmd+K). Wenn `isPinned` `true` ist, erscheint sie außerdem als Schnellaktionsschaltfläche oben rechts auf der Seite.
|
||||
@@ -1712,3 +1850,86 @@ yarn twenty uninstall
|
||||
# Skip the confirmation prompt
|
||||
yarn twenty uninstall --yes
|
||||
```
|
||||
|
||||
## Remotes verwalten
|
||||
|
||||
Ein **Remote** ist ein Twenty-Server, mit dem sich Ihre App verbindet. Während der Einrichtung erstellt das Scaffolding-Tool automatisch eines für Sie. Sie können jederzeit weitere Remotes hinzufügen oder zwischen ihnen wechseln.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Ihre Anmeldedaten werden in `~/.twenty/config.json` gespeichert.
|
||||
|
||||
## CI mit GitHub Actions
|
||||
|
||||
Das Scaffolding-Tool erzeugt einen einsatzbereiten GitHub-Actions-Workflow in `.github/workflows/ci.yml`. Er führt Ihre Integrationstests automatisch bei jedem Push auf `main` und bei Pull Requests aus.
|
||||
|
||||
Der Workflow:
|
||||
|
||||
1. Checkt Ihren Code aus
|
||||
2. Startet einen temporären Twenty-Server mit der Aktion `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. Installiert Abhängigkeiten mit `yarn install --immutable`
|
||||
4. Führt `yarn test` aus, wobei `TWENTY_API_URL` und `TWENTY_API_KEY` aus den Aktionsausgaben injiziert werden.
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Sie müssen keine Secrets konfigurieren — die Aktion `spawn-twenty-docker-image` startet einen flüchtigen Twenty-Server direkt im Runner und gibt die Verbindungsdetails aus. Das Secret `GITHUB_TOKEN` wird automatisch von GitHub bereitgestellt.
|
||||
|
||||
Um eine bestimmte Twenty-Version statt `latest` festzulegen, ändern Sie die Umgebungsvariable `TWENTY_VERSION` oben im Workflow.
|
||||
|
||||
@@ -7,7 +7,9 @@ description: Erstellen Sie in wenigen Minuten Ihre erste Twenty-App.
|
||||
Apps befinden sich derzeit in der Alpha-Phase. Die Funktion ist funktionsfähig, entwickelt sich jedoch noch weiter.
|
||||
</Warning>
|
||||
|
||||
Apps ermöglichen es Ihnen, Twenty mit benutzerdefinierten Objekten, Feldern, Logikfunktionen, KI-Fähigkeiten und UI-Komponenten zu erweitern — alles als Code verwaltet.
|
||||
## Was sind Apps?
|
||||
|
||||
Apps ermöglichen es Ihnen, Twenty mit benutzerdefinierten Objekten, Feldern, Logikfunktionen, Frontend-Komponenten, KI-Fähigkeiten und mehr zu erweitern — alles als Code verwaltet. Anstatt alles über die UI zu konfigurieren, definieren Sie Ihr Datenmodell und Ihre Logik in TypeScript und stellen es in einem oder mehreren Workspaces bereit.
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
@@ -17,7 +19,9 @@ Bevor Sie beginnen, stellen Sie sicher, dass Folgendes auf Ihrem Rechner install
|
||||
* **Yarn 4** — Wird mit Node.js über Corepack mitgeliefert. Aktivieren Sie es, indem Sie `corepack enable` ausführen
|
||||
* **Docker** — [Hier herunterladen](https://www.docker.com/products/docker-desktop/). Erforderlich, um eine lokale Twenty-Instanz auszuführen. Nicht erforderlich, wenn bereits ein Twenty-Server läuft.
|
||||
|
||||
## Schritt 1: App-Gerüst erstellen
|
||||
## Erstellen Sie Ihre erste App
|
||||
|
||||
### App-Gerüst erstellen
|
||||
|
||||
Öffnen Sie ein Terminal und führen Sie Folgendes aus:
|
||||
|
||||
@@ -29,18 +33,7 @@ Sie werden aufgefordert, einen Namen und eine Beschreibung für Ihre App einzuge
|
||||
|
||||
Dadurch wird ein neuer Ordner namens `my-twenty-app` mit allem erstellt, was Sie benötigen.
|
||||
|
||||
<Note>
|
||||
Das Scaffolding-Tool unterstützt diese Flags:
|
||||
|
||||
* `--minimal` — erstellt nur die wesentlichen Dateien, keine Beispiele (Standard)
|
||||
* `--exhaustive` — erstellt alle Beispiel-Entitäten
|
||||
* `--name <name>` — legt den App-Namen fest (überspringt die Abfrage)
|
||||
* `--display-name <displayName>` — legt den Anzeigenamen fest (überspringt die Abfrage)
|
||||
* `--description <description>` — legt die Beschreibung fest (überspringt die Abfrage)
|
||||
* `--skip-local-instance` — überspringt die Eingabeaufforderung zur Einrichtung des lokalen Servers
|
||||
</Note>
|
||||
|
||||
## Schritt 2: Lokale Twenty-Instanz einrichten
|
||||
### Lokale Twenty-Instanz einrichten
|
||||
|
||||
Das Scaffolding-Tool fragt:
|
||||
|
||||
@@ -53,7 +46,7 @@ Das Scaffolding-Tool fragt:
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Soll die lokale Instanz gestartet werden?" />
|
||||
</div>
|
||||
|
||||
## Schritt 3: Bei Ihrem Arbeitsbereich anmelden
|
||||
### Melden Sie sich bei Ihrem Arbeitsbereich an
|
||||
|
||||
Anschließend öffnet sich ein Browserfenster mit der Twenty-Anmeldeseite. Melden Sie sich mit dem vorab eingerichteten Demo-Konto an:
|
||||
|
||||
@@ -64,7 +57,7 @@ Anschließend öffnet sich ein Browserfenster mit der Twenty-Anmeldeseite. Melde
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty-Anmeldebildschirm" />
|
||||
</div>
|
||||
|
||||
## Schritt 4: Die App autorisieren
|
||||
### Autorisieren Sie die App
|
||||
|
||||
Nach der Anmeldung sehen Sie einen Autorisierungsbildschirm. Dadurch kann Ihre App mit Ihrem Arbeitsbereich interagieren.
|
||||
|
||||
@@ -80,7 +73,7 @@ Nach der Autorisierung bestätigt Ihr Terminal, dass alles eingerichtet ist.
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App-Gerüst erfolgreich erstellt" />
|
||||
</div>
|
||||
|
||||
## Schritt 5: Mit der Entwicklung beginnen
|
||||
### Beginnen Sie mit der Entwicklung
|
||||
|
||||
Wechseln Sie in Ihren neuen App-Ordner und starten Sie den Entwicklungsserver:
|
||||
|
||||
@@ -105,7 +98,7 @@ Der Dev-Modus ist nur auf Twenty-Instanzen verfügbar, die im Entwicklungsmodus
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Terminalausgabe im Dev-Modus" />
|
||||
</div>
|
||||
|
||||
## Schritt 6: Ihre App in Twenty ansehen
|
||||
### Sehen Sie sich Ihre App in Twenty an
|
||||
|
||||
Öffnen Sie [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) in Ihrem Browser. Navigieren Sie zu **Settings > Apps** und wählen Sie die Registerkarte **Developer**. Unter **Your Apps** sollte Ihre App aufgeführt sein:
|
||||
|
||||
@@ -133,13 +126,28 @@ Wechseln Sie zur Registerkarte **Content**, um alles zu sehen, was Ihre App bere
|
||||
|
||||
Alles erledigt! Bearbeiten Sie eine beliebige Datei in `src/`, und die Änderungen werden automatisch übernommen.
|
||||
|
||||
Wechseln Sie zu [Apps erstellen](/l/de/developers/extend/apps/building) für eine ausführliche Anleitung zum Erstellen von Objekten, Logikfunktionen, Frontend-Komponenten, Skills und mehr.
|
||||
---
|
||||
|
||||
## Was Sie erstellen können
|
||||
|
||||
Apps bestehen aus **Entitäten** — jede ist als TypeScript-Datei mit einem einzigen `export default` definiert:
|
||||
|
||||
| Entität | Was sie macht |
|
||||
| -------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Objekte & Felder** | Definieren Sie benutzerdefinierte Datenmodelle (wie Post Card, Invoice) mit typisierten Feldern |
|
||||
| **Logikfunktionen** | Serverseitige TypeScript-Funktionen, die durch HTTP-Routen, Cron-Zeitpläne oder Datenbankereignisse ausgelöst werden |
|
||||
| **Frontend-Komponenten** | React-Komponenten, die in der UI von Twenty gerendert werden (Seitenleiste, Widgets, Befehlsmenü) |
|
||||
| **Fähigkeiten & Agenten** | KI-Funktionen — wiederverwendbare Anweisungen und autonome Assistenten |
|
||||
| **Ansichten & Navigation** | Vorkonfigurierte Listenansichten und Seitenleisteneinträge für Ihre Objekte |
|
||||
| **Seitenlayouts** | Benutzerdefinierte Datensatz-Detailseiten mit Tabs und Widgets |
|
||||
|
||||
Wechseln Sie zu [Apps erstellen](/l/de/developers/extend/apps/building) für eine ausführliche Anleitung zu jedem Entitätstyp.
|
||||
|
||||
---
|
||||
|
||||
## Projektstruktur
|
||||
|
||||
Das Scaffolding-Tool erzeugt die folgende Verzeichnisstruktur (gezeigt im Modus `--exhaustive`, der Beispiele für jeden Entitätstyp enthält):
|
||||
Der Scaffolder erzeugt die folgende Verzeichnisstruktur:
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -148,160 +156,50 @@ my-twenty-app/
|
||||
.gitignore
|
||||
.nvmrc
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── 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
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── default-role.ts # Default role for logic functions
|
||||
├── constants/
|
||||
│ └── universal-identifiers.ts # Auto-generated UUIDs and app metadata
|
||||
└── __tests__/
|
||||
├── setup-test.ts # Test setup (server health check, config)
|
||||
└── app-install.integration-test.ts # Integration test
|
||||
```
|
||||
|
||||
Standardmäßig (`--minimal`) werden nur die Kerndateien erstellt: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` und `logic-functions/post-install.ts`. Verwenden Sie `--exhaustive`, um alle oben gezeigten Beispieldateien einzuschließen.
|
||||
### Mit einem Beispiel beginnen
|
||||
|
||||
Um mit einem umfassenderen Beispiel mit benutzerdefinierten Objekten, Feldern, Logikfunktionen, Frontend-Komponenten und mehr zu starten, verwenden Sie die Option `--example`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
npx create-twenty-app@latest my-twenty-app --example postcard
|
||||
```
|
||||
|
||||
Die Beispiele stammen aus dem Verzeichnis [twenty-apps/examples](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples) auf GitHub. Sie können auch einzelne Entitäten in einem bestehenden Projekt mit `yarn twenty add` erzeugen (siehe [Apps erstellen](/l/de/developers/extend/apps/building#scaffolding-entities-with-yarn-twenty-add)).
|
||||
|
||||
### Wichtige Dateien
|
||||
|
||||
| Datei / Ordner | Zweck |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | Deklariert den App-Namen, die Version und Abhängigkeiten. Enthält ein `twenty`-Skript, sodass Sie `yarn twenty help` ausführen können, um alle Befehle anzuzeigen. |
|
||||
| `src/application-config.ts` | **Erforderlich.** Die Hauptkonfigurationsdatei für Ihre App. |
|
||||
| `src/roles/` | Definiert Rollen, die steuern, worauf Ihre Logikfunktionen zugreifen können. |
|
||||
| `src/logic-functions/` | Serverseitige Funktionen, die durch Routen, Cron-Zeitpläne oder Datenbankereignisse ausgelöst werden. |
|
||||
| `src/front-components/` | React-Komponenten, die innerhalb der Twenty-UI gerendert werden. |
|
||||
| `src/objects/` | Benutzerdefinierte Objektdefinitionen zur Erweiterung Ihres Datenmodells. |
|
||||
| `src/fields/` | Benutzerdefinierte Felder, die vorhandenen Objekten hinzugefügt werden. |
|
||||
| `src/views/` | Konfigurationen gespeicherter Ansichten. |
|
||||
| `src/navigation-menu-items/` | Benutzerdefinierte Links in der Seitenleisten-Navigation. |
|
||||
| `src/skills/` | Skills, die die KI-Agenten von Twenty erweitern. |
|
||||
| `src/agents/` | KI-Agenten mit benutzerdefinierten Prompts. |
|
||||
| `src/page-layouts/` | Benutzerdefinierte Seitenlayouts für Datensatzansichten. |
|
||||
| `src/__tests__/` | Integrationstests (Setup + Beispieltest). |
|
||||
| `public/` | Statische Assets (Bilder, Schriftarten), die mit Ihrer App ausgeliefert werden. |
|
||||
| Datei / Ordner | Zweck |
|
||||
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `package.json` | Deklariert den App-Namen, die Version und Abhängigkeiten. Enthält ein `twenty`-Skript, sodass Sie `yarn twenty help` ausführen können, um alle Befehle anzuzeigen. |
|
||||
| `src/application-config.ts` | **Erforderlich.** Die Hauptkonfigurationsdatei für Ihre App. |
|
||||
| `src/default-role.ts` | Standardrolle, die steuert, worauf Ihre Logikfunktionen zugreifen können. |
|
||||
| `src/constants/universal-identifiers.ts` | Automatisch erzeugte UUIDs und App-Metadaten (Anzeigename, Beschreibung). |
|
||||
| `src/__tests__/` | Integrationstests (Setup + Beispieltest). |
|
||||
| `public/` | Statische Assets (Bilder, Schriftarten), die mit Ihrer App ausgeliefert werden. |
|
||||
|
||||
## Remotes verwalten
|
||||
## Lokaler Entwicklungsserver
|
||||
|
||||
Ein **Remote** ist ein Twenty-Server, mit dem sich Ihre App verbindet. Während der Einrichtung erstellt das Scaffolding-Tool automatisch eines für Sie. Sie können jederzeit weitere Remotes hinzufügen oder zwischen ihnen wechseln.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Ihre Anmeldedaten werden in `~/.twenty/config.json` gespeichert.
|
||||
|
||||
## Lokaler Entwicklungsserver (`yarn twenty server`)
|
||||
|
||||
Die CLI kann einen lokalen, in Docker laufenden Twenty-Server verwalten. Dies ist derselbe Server, der automatisch gestartet wird, wenn Sie mit `create-twenty-app` eine App aufsetzen, aber Sie können ihn auch manuell verwalten.
|
||||
|
||||
### Server starten
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
Dadurch wird das Docker-Image `twentycrm/twenty-app-dev:latest` heruntergeladen (falls nicht bereits vorhanden), ein Container namens `twenty-app-dev` erstellt und auf Port **2020** gestartet. Die CLI wartet, bis der Server seinen Health-Check bestanden hat, bevor sie zurückkehrt.
|
||||
|
||||
Es werden zwei Docker-Volumes erstellt, um Daten zwischen Neustarts beizubehalten:
|
||||
|
||||
* `twenty-app-dev-data` — PostgreSQL-Datenbank
|
||||
* `twenty-app-dev-storage` — Dateispeicher
|
||||
|
||||
Wenn Port 2020 bereits verwendet wird, können Sie auf einem anderen Port starten:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
Die CLI konfiguriert automatisch die internen Werte `NODE_PORT` und `SERVER_URL` des Containers passend zum gewählten Port, sodass Logikfunktionen, OAuth und alle anderen internen Netzwerkfunktionen korrekt arbeiten.
|
||||
|
||||
Nach dem Start wird der Server automatisch als `local`-Remote in Ihrer CLI-Konfiguration registriert.
|
||||
|
||||
### Serverstatus prüfen
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Zeigt an, ob der Server läuft, seine URL und die Standard-Anmeldedaten (`[email protected]` / `[email protected]`).
|
||||
|
||||
### Serverprotokolle anzeigen
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Streamt die Containerprotokolle. Verwenden Sie `--lines`, um zu steuern, wie viele der letzten Zeilen angezeigt werden:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Server stoppen
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Stoppt den Container. Ihre Daten bleiben in den Docker-Volumes erhalten — der nächste `start` macht dort weiter, wo Sie aufgehört haben.
|
||||
|
||||
### Server zurücksetzen
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Entfernt den Container **und** löscht beide Docker-Volumes, wobei alle Daten gelöscht werden. Der nächste `start` erstellt eine frische Instanz.
|
||||
|
||||
<Note>
|
||||
Der Server erfordert, dass **Docker** läuft. Wenn der Fehler "Docker not running" angezeigt wird, stellen Sie sicher, dass Docker Desktop (oder der Docker-Daemon) gestartet ist.
|
||||
</Note>
|
||||
|
||||
### Befehlsreferenz
|
||||
Der Scaffolder hat bereits einen lokalen Twenty-Server für Sie gestartet. Um ihn später zu verwalten, verwenden Sie `yarn twenty server`:
|
||||
|
||||
| Befehl | Beschreibung |
|
||||
| -------------------------------------- | ----------------------------------------------------------- |
|
||||
@@ -313,65 +211,11 @@ Entfernt den Container **und** löscht beide Docker-Volumes, wobei alle Daten ge
|
||||
| `yarn twenty server logs --lines 100` | Die letzten 100 Protokollzeilen anzeigen |
|
||||
| `yarn twenty server reset` | Alle Daten löschen und neu starten |
|
||||
|
||||
## CI mit GitHub Actions
|
||||
Daten bleiben über Neustarts hinweg in zwei Docker-Volumes bestehen (`twenty-app-dev-data` für PostgreSQL, `twenty-app-dev-storage` für Dateien). Verwenden Sie `reset`, um alles zu löschen und neu zu beginnen.
|
||||
|
||||
Das Scaffolding-Tool erzeugt einen einsatzbereiten GitHub-Actions-Workflow in `.github/workflows/ci.yml`. Er führt Ihre Integrationstests automatisch bei jedem Push auf `main` und bei Pull Requests aus.
|
||||
|
||||
Der Workflow:
|
||||
|
||||
1. Checkt Ihren Code aus
|
||||
2. Startet einen temporären Twenty-Server mit der Aktion `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. Installiert Abhängigkeiten mit `yarn install --immutable`
|
||||
4. Führt `yarn test` aus, wobei `TWENTY_API_URL` und `TWENTY_API_KEY` aus den Aktionsausgaben injiziert werden.
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Sie müssen keine Secrets konfigurieren — die Aktion `spawn-twenty-docker-image` startet einen flüchtigen Twenty-Server direkt im Runner und gibt die Verbindungsdetails aus. Das Secret `GITHUB_TOKEN` wird automatisch von GitHub bereitgestellt.
|
||||
|
||||
Um eine bestimmte Twenty-Version statt `latest` festzulegen, ändern Sie die Umgebungsvariable `TWENTY_VERSION` oben im Workflow.
|
||||
<Note>
|
||||
Der Server erfordert, dass **Docker** läuft. Wenn der Fehler "Docker not running" angezeigt wird, stellen Sie sicher, dass Docker Desktop (oder der Docker-Daemon) gestartet ist.
|
||||
</Note>
|
||||
|
||||
## Manuelle Einrichtung (ohne Scaffolder)
|
||||
|
||||
|
||||
@@ -52,7 +52,11 @@ yarn twenty deploy
|
||||
|
||||
### Eine bereitgestellte App freigeben
|
||||
|
||||
Tarball-Apps werden nicht im öffentlichen Marktplatz gelistet, daher entdecken andere Arbeitsbereiche auf demselben Server sie nicht durch Stöbern. So geben Sie eine bereitgestellte App frei:
|
||||
<Warning>
|
||||
Sharing private (tarball) apps across workspaces is an **Enterprise** feature. The **Distribution** tab will show an upgrade prompt instead of the share controls until your workspace has a valid Enterprise key. See [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to activate it.
|
||||
</Warning>
|
||||
|
||||
Tarball-Apps werden nicht im öffentlichen Marktplatz gelistet, daher entdecken andere Arbeitsbereiche auf demselben Server sie nicht durch Stöbern. Once your workspace is on the Enterprise plan, you can share a deployed app like this:
|
||||
|
||||
1. Gehen Sie zu **Einstellungen > Anwendungen > Registrierungen** und öffnen Sie Ihre App
|
||||
2. Klicken Sie im Tab **Distribution** auf **Freigabelink kopieren**
|
||||
@@ -60,10 +64,6 @@ Tarball-Apps werden nicht im öffentlichen Marktplatz gelistet, daher entdecken
|
||||
|
||||
Der Freigabelink verwendet die Basis-URL des Servers (ohne Workspace-Subdomain), sodass er für jeden Arbeitsbereich auf dem Server funktioniert.
|
||||
|
||||
<Warning>
|
||||
Das Teilen privater Apps ist eine Enterprise-Funktion. Gehen Sie zu [Einstellungen > Admin-Panel > Enterprise](/settings/admin-panel#enterprise), um es zu aktivieren.
|
||||
</Warning>
|
||||
|
||||
### Versionsverwaltung
|
||||
|
||||
So veröffentlichen Sie ein Update:
|
||||
|
||||
@@ -81,7 +81,7 @@ import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
universalIdentifier: '39783023-bcac-41e3-b0d2-ff1944d8465d',
|
||||
displayName: 'My Twenty App',
|
||||
description: 'My first Twenty app',
|
||||
icon: 'IconWorld',
|
||||
@@ -716,6 +716,13 @@ Punti chiave:
|
||||
|
||||
I componenti front-end sono componenti React che vengono renderizzati direttamente all'interno della UI di Twenty. Vengono eseguiti in un **Web Worker** isolato utilizzando Remote DOM — il tuo codice è in sandbox ma viene renderizzato in modo nativo nella pagina, non in un iframe.
|
||||
|
||||
#### Dove possono essere utilizzati i componenti front.
|
||||
|
||||
I componenti front possono essere renderizzati in due posizioni all'interno di Twenty:
|
||||
|
||||
* **Pannello laterale** — I componenti front non headless si aprono nel pannello laterale destro. Questo è il comportamento predefinito quando un componente front viene avviato dal menu comandi.
|
||||
* **Widget (dashboard e pagine dei record)** — I componenti front possono essere incorporati come widget all'interno dei layout di pagina. Quando si configura una dashboard o il layout di una pagina record, gli utenti possono aggiungere un widget del componente front.
|
||||
|
||||
#### Esempio di base
|
||||
|
||||
Il modo più rapido per vedere in azione un componente front-end è registrarlo come **comando**. Aggiungere un campo `command` con `isPinned: true` lo fa apparire come pulsante di azione rapida nell'angolo in alto a destra della pagina — nessun layout di pagina necessario:
|
||||
@@ -773,9 +780,13 @@ Fai clic per renderizzare il componente in linea.
|
||||
|
||||
Oltre ai comandi, puoi incorporare un componente front-end direttamente in una pagina di record aggiungendolo come widget in un **layout di pagina**. Vedi la sezione [definePageLayout](#definepagelayout) per i dettagli.
|
||||
|
||||
#### Componenti headless (`isHeadless: true`)
|
||||
#### Headless vs non headless
|
||||
|
||||
I componenti headless non renderizzano alcuna UI visibile ma eseguono comunque la logica React. Questo è utile per i componenti di effetto — componenti che eseguono effetti collaterali quando vengono montati, come sincronizzare dati, avviare un timer, ascoltare eventi o attivare una notifica.
|
||||
I componenti front prevedono due modalità di rendering controllate dall'opzione `isHeadless`:
|
||||
|
||||
**Non headless (predefinito)** — Il componente renderizza un'interfaccia utente visibile. Quando viene avviato dal menu comandi, si apre nel pannello laterale. Questo è il comportamento predefinito quando `isHeadless` è `false` o omesso.
|
||||
|
||||
**Headless (`isHeadless: true`)** — Il componente viene montato in modo invisibile in background. Non apre il pannello laterale. I componenti headless sono pensati per azioni che eseguono una logica e poi si smontano — ad esempio, eseguire un'attività asincrona, navigare a una pagina o mostrare una finestra modale di conferma. Si abbinano naturalmente ai componenti Command dell'SDK descritti di seguito.
|
||||
|
||||
```tsx src/front-components/sync-tracker.tsx
|
||||
import { defineFrontComponent, useRecordId, enqueueSnackbar } from 'twenty-sdk';
|
||||
@@ -802,6 +813,89 @@ export default defineFrontComponent({
|
||||
|
||||
Poiché il componente restituisce `null`, Twenty evita di renderizzare un contenitore per esso — non appare alcuno spazio vuoto nel layout. Il componente ha comunque accesso a tutti gli hook e all'API di comunicazione con l'host.
|
||||
|
||||
#### Componenti Command dell'SDK
|
||||
|
||||
Il pacchetto `twenty-sdk` fornisce quattro componenti di supporto Command progettati per i componenti front headless. Ogni componente esegue un'azione al montaggio, gestisce gli errori mostrando una notifica snackbar e smonta automaticamente il componente front al termine.
|
||||
|
||||
Importali da `twenty-sdk/command`:
|
||||
|
||||
* **`Command`** — Esegue una callback asincrona tramite la prop `execute`.
|
||||
* **`CommandLink`** — Naviga verso un percorso dell'app. Props: `to`, `params`, `queryParams`, `options`.
|
||||
* **`CommandModal`** — Apre una finestra modale di conferma. Se l'utente conferma, esegue la callback `execute`. Props: `title`, `subtitle`, `execute`, `confirmButtonText`, `confirmButtonAccent`.
|
||||
* **`CommandOpenSidePanelPage`** — Apre una specifica pagina del pannello laterale. Props: `page`, `pageTitle`, `pageIcon`.
|
||||
|
||||
Ecco un esempio completo di componente front headless che usa `Command` per eseguire un'azione dal menu comandi:
|
||||
|
||||
```tsx src/front-components/run-action.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { Command } from 'twenty-sdk/command';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const RunAction = () => {
|
||||
const execute = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
createTask: {
|
||||
__args: { data: { title: 'Created by my app' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return <Command execute={execute} />;
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'e5f6a7b8-c9d0-1234-efab-345678901234',
|
||||
name: 'run-action',
|
||||
description: 'Creates a task from the command menu',
|
||||
component: RunAction,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'f6a7b8c9-d0e1-2345-fabc-456789012345',
|
||||
label: 'Run my action',
|
||||
icon: 'IconPlayerPlay',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
E un esempio che usa `CommandModal` per chiedere conferma prima di eseguire:
|
||||
|
||||
```tsx src/front-components/delete-draft.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { CommandModal } from 'twenty-sdk/command';
|
||||
|
||||
const DeleteDraft = () => {
|
||||
const execute = async () => {
|
||||
// perform the deletion
|
||||
};
|
||||
|
||||
return (
|
||||
<CommandModal
|
||||
title="Delete draft?"
|
||||
subtitle="This action cannot be undone."
|
||||
execute={execute}
|
||||
confirmButtonText="Delete"
|
||||
confirmButtonAccent="danger"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'a7b8c9d0-e1f2-3456-abcd-567890123456',
|
||||
name: 'delete-draft',
|
||||
description: 'Deletes a draft with confirmation',
|
||||
component: DeleteDraft,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'b8c9d0e1-f2a3-4567-bcde-678901234567',
|
||||
label: 'Delete draft',
|
||||
icon: 'IconTrash',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### Accesso al contesto di runtime
|
||||
|
||||
All'interno del tuo componente, usa gli hook dell'SDK per accedere all'utente corrente, al record e all'istanza del componente:
|
||||
@@ -858,6 +952,50 @@ I componenti front-end possono attivare navigazione, modali e notifiche utilizza
|
||||
| `unmountFrontComponent()` | Smonta il componente |
|
||||
| `updateProgress(progress)` | Aggiorna un indicatore di avanzamento |
|
||||
|
||||
Ecco un esempio che usa l'API host per mostrare una snackbar e chiudere il pannello laterale dopo il completamento di un'azione:
|
||||
|
||||
```tsx src/front-components/archive-record.tsx
|
||||
import { defineFrontComponent, useRecordId } from 'twenty-sdk';
|
||||
import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const ArchiveRecord = () => {
|
||||
const recordId = useRecordId();
|
||||
|
||||
const handleArchive = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
updateTask: {
|
||||
__args: { id: recordId, data: { status: 'ARCHIVED' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
await enqueueSnackbar({
|
||||
message: 'Record archived',
|
||||
variant: 'success',
|
||||
});
|
||||
|
||||
await closeSidePanel();
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px' }}>
|
||||
<p>Archive this record?</p>
|
||||
<button onClick={handleArchive}>Archive</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'c9d0e1f2-a3b4-5678-cdef-789012345678',
|
||||
name: 'archive-record',
|
||||
description: 'Archives the current record',
|
||||
component: ArchiveRecord,
|
||||
});
|
||||
```
|
||||
|
||||
#### Opzioni del comando
|
||||
|
||||
Aggiungere un campo `command` a `defineFrontComponent` registra il componente nel menu comandi (Cmd+K). Se `isPinned` è `true`, compare anche come pulsante di azione rapida nell'angolo in alto a destra della pagina.
|
||||
@@ -1712,3 +1850,86 @@ yarn twenty uninstall
|
||||
# Skip the confirmation prompt
|
||||
yarn twenty uninstall --yes
|
||||
```
|
||||
|
||||
## Gestione dei remoti
|
||||
|
||||
Un **remoto** è un server Twenty a cui la tua app si connette. Durante la configurazione, lo strumento di scaffolding ne crea uno automaticamente per te. Puoi aggiungere altri remoti o passare da uno all'altro in qualsiasi momento.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Le tue credenziali sono archiviate in `~/.twenty/config.json`.
|
||||
|
||||
## CI con GitHub Actions
|
||||
|
||||
Lo strumento di scaffolding genera un workflow GitHub Actions pronto all'uso in `.github/workflows/ci.yml`. Esegue automaticamente i test di integrazione a ogni push su `main` e sulle pull request.
|
||||
|
||||
Il workflow:
|
||||
|
||||
1. Esegue il checkout del tuo codice
|
||||
2. Avvia un server Twenty temporaneo utilizzando l'azione `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. Installa le dipendenze con `yarn install --immutable`
|
||||
4. Esegue `yarn test` con `TWENTY_API_URL` e `TWENTY_API_KEY` iniettati dagli output dell'azione
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Non è necessario configurare alcun secret — l'azione `spawn-twenty-docker-image` avvia un server Twenty effimero direttamente nel runner e fornisce i dettagli di connessione. Il secret `GITHUB_TOKEN` è fornito automaticamente da GitHub.
|
||||
|
||||
Per fissare una versione specifica di Twenty invece di `latest`, modifica la variabile d'ambiente `TWENTY_VERSION` all'inizio del workflow.
|
||||
|
||||
@@ -7,7 +7,9 @@ description: Crea la tua prima app Twenty in pochi minuti.
|
||||
Le app sono attualmente in fase alfa. La funzionalità funziona ma è ancora in evoluzione.
|
||||
</Warning>
|
||||
|
||||
Le app ti permettono di estendere Twenty con oggetti, campi, funzioni logiche, competenze IA e componenti UI personalizzati — il tutto gestito come codice.
|
||||
## Cosa sono le app?
|
||||
|
||||
Le app ti consentono di estendere Twenty con oggetti, campi, funzioni logiche, componenti front-end, competenze IA e altro ancora — il tutto gestito come codice. Invece di configurare tutto tramite l'interfaccia utente, definisci in TypeScript il modello dati e la logica e li distribuisci in uno o più spazi di lavoro.
|
||||
|
||||
## Prerequisiti
|
||||
|
||||
@@ -17,7 +19,9 @@ Prima di iniziare, assicurati che quanto segue sia installato sul tuo computer:
|
||||
* **Yarn 4** — Incluso con Node.js tramite Corepack. Abilitalo eseguendo `corepack enable`
|
||||
* **Docker** — [Scarica qui](https://www.docker.com/products/docker-desktop/). Necessario per eseguire un'istanza locale di Twenty. Non necessario se hai già un server Twenty in esecuzione.
|
||||
|
||||
## Passaggio 1: Crea lo scheletro della tua app
|
||||
## Crea la tua prima app
|
||||
|
||||
### Crea lo scheletro della tua app
|
||||
|
||||
Apri un terminale ed esegui:
|
||||
|
||||
@@ -29,18 +33,7 @@ Ti verrà chiesto di inserire un nome e una descrizione per la tua app. Premi **
|
||||
|
||||
Questo crea una nuova cartella chiamata `my-twenty-app` con tutto il necessario.
|
||||
|
||||
<Note>
|
||||
Lo strumento di scaffolding supporta questi flag:
|
||||
|
||||
* `--minimal` — genera solo i file essenziali, senza esempi (predefinito)
|
||||
* `--exhaustive` — genera tutte le entità di esempio
|
||||
* `--name <name>` — imposta il nome dell'app (salta la richiesta)
|
||||
* `--display-name <displayName>` — imposta il nome visualizzato (salta la richiesta)
|
||||
* `--description <description>` — imposta la descrizione (salta la richiesta)
|
||||
* `--skip-local-instance` — salta la richiesta di configurazione del server locale
|
||||
</Note>
|
||||
|
||||
## Passaggio 2: Configura un'istanza locale di Twenty
|
||||
### Configura un'istanza locale di Twenty
|
||||
|
||||
Lo strumento di scaffolding chiederà:
|
||||
|
||||
@@ -53,7 +46,7 @@ Lo strumento di scaffolding chiederà:
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Avviare l'istanza locale?" />
|
||||
</div>
|
||||
|
||||
## Passaggio 3: Accedi al tuo spazio di lavoro
|
||||
### Accedi al tuo spazio di lavoro
|
||||
|
||||
Successivamente si aprirà una finestra del browser con la pagina di accesso di Twenty. Accedi con l'account demo preconfigurato:
|
||||
|
||||
@@ -64,7 +57,7 @@ Successivamente si aprirà una finestra del browser con la pagina di accesso di
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Schermata di accesso di Twenty" />
|
||||
</div>
|
||||
|
||||
## Passaggio 4: Autorizza l'app
|
||||
### Autorizza l'app
|
||||
|
||||
Dopo l'accesso, vedrai una schermata di autorizzazione. Questo consente alla tua app di interagire con il tuo spazio di lavoro.
|
||||
|
||||
@@ -80,7 +73,7 @@ Una volta autorizzato, il terminale confermerà che tutto è configurato.
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App creata con successo" />
|
||||
</div>
|
||||
|
||||
## Passaggio 5: Inizia a sviluppare
|
||||
### Inizia a sviluppare
|
||||
|
||||
Entra nella nuova cartella della tua app e avvia il server di sviluppo:
|
||||
|
||||
@@ -105,7 +98,7 @@ La modalità di sviluppo è disponibile solo sulle istanze di Twenty in esecuzio
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Output del terminale in modalità sviluppo" />
|
||||
</div>
|
||||
|
||||
## Passaggio 6: Visualizza la tua app in Twenty
|
||||
### Visualizza la tua app in Twenty
|
||||
|
||||
Apri [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) nel browser. Vai su **Settings > Apps** e seleziona la scheda **Developer**. Dovresti vedere la tua app elencata in **Your Apps**:
|
||||
|
||||
@@ -133,13 +126,28 @@ Passa alla scheda **Content** per vedere tutto ciò che la tua app fornisce —
|
||||
|
||||
È tutto pronto! Modifica qualsiasi file in `src/` e le modifiche verranno rilevate automaticamente.
|
||||
|
||||
Vai a [Creare app](/l/it/developers/extend/apps/building) per una guida dettagliata sulla creazione di oggetti, funzioni logiche, componenti front-end, skill e altro.
|
||||
---
|
||||
|
||||
## Cosa puoi creare
|
||||
|
||||
Le app sono composte da **entità** — ciascuna definita come un file TypeScript con un singolo `export default`:
|
||||
|
||||
| Entità | Cosa fa |
|
||||
| ------------------------ | ----------------------------------------------------------------------------------------------------------------- |
|
||||
| **Oggetti e campi** | Definisci modelli di dati personalizzati (come Post Card, Invoice) con campi tipizzati |
|
||||
| **Funzioni logiche** | Funzioni TypeScript lato server attivate da route HTTP, pianificazioni cron o eventi del database |
|
||||
| **Componenti front-end** | Componenti React che vengono renderizzati all'interno dell'UI di Twenty (pannello laterale, widget, menu comandi) |
|
||||
| **Skill e agenti** | Funzionalità di IA — istruzioni riutilizzabili e assistenti autonomi |
|
||||
| **Viste e navigazione** | Viste elenco preconfigurate e voci di menu della barra laterale per i tuoi oggetti |
|
||||
| **Layout di pagina** | Pagine di dettaglio dei record personalizzate con schede e widget |
|
||||
|
||||
Vai a [Creare app](/l/it/developers/extend/apps/building) per una guida dettagliata su ogni tipo di entità.
|
||||
|
||||
---
|
||||
|
||||
## Struttura del progetto
|
||||
|
||||
Lo strumento di scaffolding genera la seguente struttura di file (mostrata con la modalità `--exhaustive`, che include esempi per ogni tipo di entità):
|
||||
Lo scaffolder genera la seguente struttura dei file:
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -148,160 +156,50 @@ my-twenty-app/
|
||||
.gitignore
|
||||
.nvmrc
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── 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
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── default-role.ts # Default role for logic functions
|
||||
├── constants/
|
||||
│ └── universal-identifiers.ts # Auto-generated UUIDs and app metadata
|
||||
└── __tests__/
|
||||
├── setup-test.ts # Test setup (server health check, config)
|
||||
└── app-install.integration-test.ts # Integration test
|
||||
```
|
||||
|
||||
Per impostazione predefinita (`--minimal`), vengono creati solo i file principali: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` e `logic-functions/post-install.ts`. Usa `--exhaustive` per includere tutti i file di esempio mostrati sopra.
|
||||
### Partire da un esempio
|
||||
|
||||
Per iniziare da un esempio più completo con oggetti personalizzati, campi, funzioni logiche, componenti front-end e altro, usa il flag `--example`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
npx create-twenty-app@latest my-twenty-app --example postcard
|
||||
```
|
||||
|
||||
Gli esempi provengono dalla directory [twenty-apps/examples](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples) su GitHub. Puoi anche aggiungere singole entità a un progetto esistente con `yarn twenty add` (vedi [Creare app](/l/it/developers/extend/apps/building#scaffolding-entities-with-yarn-twenty-add)).
|
||||
|
||||
### File principali
|
||||
|
||||
| File / Cartella | Scopo |
|
||||
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `package.json` | Dichiara il nome, la versione e le dipendenze della tua app. Include uno script `twenty` così puoi eseguire `yarn twenty help` per vedere tutti i comandi. |
|
||||
| `src/application-config.ts` | **Obbligatorio.** Il file di configurazione principale della tua app. |
|
||||
| `src/roles/` | Definisce i ruoli che controllano a cosa possono accedere le tue funzioni logiche. |
|
||||
| `src/logic-functions/` | Funzioni lato server attivate da route, pianificazioni cron o eventi del database. |
|
||||
| `src/front-components/` | Componenti React che vengono renderizzati all'interno della UI di Twenty. |
|
||||
| `src/objects/` | Definizioni di oggetti personalizzati per estendere il tuo modello dati. |
|
||||
| `src/fields/` | Campi personalizzati aggiunti a oggetti esistenti. |
|
||||
| `src/views/` | Configurazioni di viste salvate. |
|
||||
| `src/navigation-menu-items/` | Link personalizzati nella navigazione laterale. |
|
||||
| `src/skills/` | Abilità che estendono gli agenti IA di Twenty. |
|
||||
| `src/agents/` | Agenti IA con prompt personalizzati. |
|
||||
| `src/page-layouts/` | Layout di pagina personalizzati per le viste dei record. |
|
||||
| `src/__tests__/` | Test di integrazione (setup + test di esempio). |
|
||||
| `public/` | Asset statici (immagini, font) serviti insieme alla tua app. |
|
||||
| File / Cartella | Scopo |
|
||||
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `package.json` | Dichiara il nome, la versione e le dipendenze della tua app. Include uno script `twenty` così puoi eseguire `yarn twenty help` per vedere tutti i comandi. |
|
||||
| `src/application-config.ts` | **Obbligatorio.** Il file di configurazione principale della tua app. |
|
||||
| `src/default-role.ts` | Ruolo predefinito che controlla a cosa possono accedere le tue funzioni logiche. |
|
||||
| `src/constants/universal-identifiers.ts` | UUID generati automaticamente e metadati dell'app (nome visualizzato, descrizione). |
|
||||
| `src/__tests__/` | Test di integrazione (setup + test di esempio). |
|
||||
| `public/` | Asset statici (immagini, font) serviti insieme alla tua app. |
|
||||
|
||||
## Gestione dei remoti
|
||||
## Server di sviluppo locale
|
||||
|
||||
Un **remoto** è un server Twenty a cui la tua app si connette. Durante la configurazione, lo strumento di scaffolding ne crea uno automaticamente per te. Puoi aggiungere altri remoti o passare da uno all'altro in qualsiasi momento.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Le tue credenziali sono archiviate in `~/.twenty/config.json`.
|
||||
|
||||
## Server di sviluppo locale (`yarn twenty server`)
|
||||
|
||||
La CLI può gestire un server Twenty locale in esecuzione in Docker. Questo è lo stesso server avviato automaticamente quando crei lo scheletro di un'app con `create-twenty-app`, ma puoi anche gestirlo manualmente.
|
||||
|
||||
### Avvio del server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
Questo scarica l'immagine Docker `twentycrm/twenty-app-dev:latest` (se non è già presente), crea un container chiamato `twenty-app-dev` e lo avvia sulla porta **2020**. La CLI attende che il server superi il controllo di integrità prima di restituire il controllo.
|
||||
|
||||
Vengono creati due volumi Docker per mantenere i dati tra i riavvii:
|
||||
|
||||
* `twenty-app-dev-data` — database PostgreSQL
|
||||
* `twenty-app-dev-storage` — archiviazione file
|
||||
|
||||
Se la porta 2020 è già in uso, puoi avviare su una porta diversa:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
La CLI configura automaticamente le variabili interne del container `NODE_PORT` e `SERVER_URL` per corrispondere alla porta scelta, in modo che funzioni logiche, OAuth e tutto il resto del networking interno funzionino correttamente.
|
||||
|
||||
Una volta avviato, il server viene registrato automaticamente come remoto `local` nella configurazione della CLI.
|
||||
|
||||
### Verifica dello stato del server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Mostra se il server è in esecuzione, il suo URL e le credenziali di accesso predefinite (`[email protected]` / `[email protected]`).
|
||||
|
||||
### Visualizzazione dei log del server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Trasmette in streaming i log del container. Usa `--lines` per controllare quante righe recenti mostrare:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Arresto del server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Arresta il container. I tuoi dati vengono conservati nei volumi Docker — il prossimo `start` riprenderà da dove avevi lasciato.
|
||||
|
||||
### Reimpostazione del server
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Rimuove il container **e** elimina entrambi i volumi Docker, cancellando tutti i dati. Il prossimo `start` crea un'istanza nuova.
|
||||
|
||||
<Note>
|
||||
Il server richiede che **Docker** sia in esecuzione. Se vedi l'errore "Docker not running", assicurati che Docker Desktop (o il demone Docker) sia avviato.
|
||||
</Note>
|
||||
|
||||
### Riferimento ai comandi
|
||||
Lo scaffolder ha già avviato per te un server Twenty locale. Per gestirlo in seguito, usa `yarn twenty server`:
|
||||
|
||||
| Comando | Descrizione |
|
||||
| -------------------------------------- | --------------------------------------------------------- |
|
||||
@@ -313,65 +211,11 @@ Rimuove il container **e** elimina entrambi i volumi Docker, cancellando tutti i
|
||||
| `yarn twenty server logs --lines 100` | Mostra le ultime 100 righe di log |
|
||||
| `yarn twenty server reset` | Elimina tutti i dati e riparti da zero |
|
||||
|
||||
## CI con GitHub Actions
|
||||
I dati vengono mantenuti tra i riavvii in due volumi Docker (`twenty-app-dev-data` per PostgreSQL, `twenty-app-dev-storage` per i file). Usa `reset` per cancellare tutto e ripartire da zero.
|
||||
|
||||
Lo strumento di scaffolding genera un workflow GitHub Actions pronto all'uso in `.github/workflows/ci.yml`. Esegue automaticamente i test di integrazione a ogni push su `main` e sulle pull request.
|
||||
|
||||
Il workflow:
|
||||
|
||||
1. Esegue il checkout del tuo codice
|
||||
2. Avvia un server Twenty temporaneo utilizzando l'azione `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. Installa le dipendenze con `yarn install --immutable`
|
||||
4. Esegue `yarn test` con `TWENTY_API_URL` e `TWENTY_API_KEY` iniettati dagli output dell'azione
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Non è necessario configurare alcun secret — l'azione `spawn-twenty-docker-image` avvia un server Twenty effimero direttamente nel runner e fornisce i dettagli di connessione. Il secret `GITHUB_TOKEN` è fornito automaticamente da GitHub.
|
||||
|
||||
Per fissare una versione specifica di Twenty invece di `latest`, modifica la variabile d'ambiente `TWENTY_VERSION` all'inizio del workflow.
|
||||
<Note>
|
||||
Il server richiede che **Docker** sia in esecuzione. Se vedi l'errore "Docker not running", assicurati che Docker Desktop (o il demone Docker) sia avviato.
|
||||
</Note>
|
||||
|
||||
## Configurazione manuale (senza lo scaffolder)
|
||||
|
||||
|
||||
@@ -52,7 +52,11 @@ yarn twenty deploy
|
||||
|
||||
### Condivisione di un'app distribuita
|
||||
|
||||
Le app in formato tarball non sono elencate nel marketplace pubblico, quindi altri spazi di lavoro sullo stesso server non le troveranno navigando. Per condividere un'app distribuita:
|
||||
<Warning>
|
||||
Sharing private (tarball) apps across workspaces is an **Enterprise** feature. The **Distribution** tab will show an upgrade prompt instead of the share controls until your workspace has a valid Enterprise key. See [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to activate it.
|
||||
</Warning>
|
||||
|
||||
Le app in formato tarball non sono elencate nel marketplace pubblico, quindi altri spazi di lavoro sullo stesso server non le troveranno navigando. Once your workspace is on the Enterprise plan, you can share a deployed app like this:
|
||||
|
||||
1. Vai su **Impostazioni > Applicazioni > Registrazioni** e apri la tua app
|
||||
2. Nella scheda **Distribuzione**, fai clic su **Copia link di condivisione**
|
||||
@@ -60,10 +64,6 @@ Le app in formato tarball non sono elencate nel marketplace pubblico, quindi alt
|
||||
|
||||
Il link di condivisione utilizza l'URL di base del server (senza alcun sottodominio dello spazio di lavoro) così funziona per qualsiasi spazio di lavoro sul server.
|
||||
|
||||
<Warning>
|
||||
La condivisione delle app private è una funzionalità Enterprise. Vai a [Impostazioni > Pannello di amministrazione > Enterprise](/settings/admin-panel#enterprise) per abilitarla.
|
||||
</Warning>
|
||||
|
||||
### Gestione delle versioni
|
||||
|
||||
Per rilasciare un aggiornamento:
|
||||
|
||||
@@ -81,7 +81,7 @@ import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
universalIdentifier: '39783023-bcac-41e3-b0d2-ff1944d8465d',
|
||||
displayName: 'My Twenty App',
|
||||
description: 'My first Twenty app',
|
||||
icon: 'IconWorld',
|
||||
@@ -716,6 +716,13 @@ Pontos-chave:
|
||||
|
||||
Componentes de front-end são componentes React que renderizam diretamente dentro da UI do Twenty. Eles são executados em um Web Worker isolado usando Remote DOM — seu código é sandboxed, mas renderiza nativamente na página, não em um iframe.
|
||||
|
||||
#### Onde os componentes de front-end podem ser usados
|
||||
|
||||
Os componentes de front-end podem ser renderizados em dois locais dentro do Twenty:
|
||||
|
||||
* **Painel lateral** — Componentes de front-end não headless abrem no painel lateral direito. Este é o comportamento padrão quando um componente de front-end é acionado pelo menu de comandos.
|
||||
* **Widgets (painéis e páginas de registro)** — Componentes de front-end podem ser incorporados como widgets nos layouts de página. Ao configurar um painel ou o layout de uma página de registro, os usuários podem adicionar um widget de componente de front-end.
|
||||
|
||||
#### Exemplo básico
|
||||
|
||||
A maneira mais rápida de ver um componente de front-end em ação é registrá-lo como um **comando**. Adicionar um campo `command` com `isPinned: true` faz com que ele apareça como um botão de ação rápida no canto superior direito da página — não é necessário layout de página:
|
||||
@@ -773,9 +780,13 @@ Clique nele para renderizar o componente inline.
|
||||
|
||||
Além de comandos, você pode incorporar um componente de front-end diretamente em uma página de registro adicionando-o como um widget em um **layout de página**. Veja a seção [definePageLayout](#definepagelayout) para obter detalhes.
|
||||
|
||||
#### Componentes sem interface (`isHeadless: true`)
|
||||
#### Headless vs não headless
|
||||
|
||||
Componentes sem interface não renderizam nenhuma UI visível, mas ainda executam a lógica do React. Isso é útil para **componentes de efeito** — componentes que executam efeitos colaterais quando montados, como sincronizar dados, iniciar um temporizador, ouvir eventos ou disparar uma notificação.
|
||||
Os componentes de front-end têm dois modos de renderização controlados pela opção `isHeadless`:
|
||||
|
||||
**Não headless (padrão)** — O componente renderiza uma interface visível. Quando acionado pelo menu de comandos, ele é aberto no painel lateral. Este é o comportamento padrão quando `isHeadless` é `false` ou omitido.
|
||||
|
||||
**Headless (`isHeadless: true`)** — The component mounts invisibly in the background. Ele não abre o painel lateral. Componentes headless são projetados para ações que executam lógica e, em seguida, se desmontam — por exemplo, executar uma tarefa assíncrona, navegar para uma página ou exibir um modal de confirmação. Eles se combinam naturalmente com os componentes Command do SDK descritos abaixo.
|
||||
|
||||
```tsx src/front-components/sync-tracker.tsx
|
||||
import { defineFrontComponent, useRecordId, enqueueSnackbar } from 'twenty-sdk';
|
||||
@@ -802,6 +813,89 @@ export default defineFrontComponent({
|
||||
|
||||
Como o componente retorna `null`, o Twenty ignora renderizar um contêiner para ele — nenhum espaço vazio aparece no layout. O componente ainda tem acesso a todos os hooks e à API de comunicação do host.
|
||||
|
||||
#### Componentes Command do SDK
|
||||
|
||||
O pacote `twenty-sdk` fornece quatro componentes auxiliares Command projetados para componentes de front-end headless. Cada componente executa uma ação ao montar, trata erros exibindo uma notificação de snackbar e desmonta automaticamente o componente de front-end ao concluir.
|
||||
|
||||
Importe-os de `twenty-sdk/command`:
|
||||
|
||||
* **`Command`** — Executa um callback assíncrono via a prop `execute`.
|
||||
* **`CommandLink`** — Navega para um caminho do app. Props: `to`, `params`, `queryParams`, `options`.
|
||||
* **`CommandModal`** — Abre um modal de confirmação. Se o usuário confirmar, executa o callback `execute`. Props: `title`, `subtitle`, `execute`, `confirmButtonText`, `confirmButtonAccent`.
|
||||
* **`CommandOpenSidePanelPage`** — Abre uma página específica do painel lateral. Props: `page`, `pageTitle`, `pageIcon`.
|
||||
|
||||
Aqui está um exemplo completo de um componente de front-end headless usando `Command` para executar uma ação a partir do menu de comandos:
|
||||
|
||||
```tsx src/front-components/run-action.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { Command } from 'twenty-sdk/command';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const RunAction = () => {
|
||||
const execute = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
createTask: {
|
||||
__args: { data: { title: 'Created by my app' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return <Command execute={execute} />;
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'e5f6a7b8-c9d0-1234-efab-345678901234',
|
||||
name: 'run-action',
|
||||
description: 'Creates a task from the command menu',
|
||||
component: RunAction,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'f6a7b8c9-d0e1-2345-fabc-456789012345',
|
||||
label: 'Run my action',
|
||||
icon: 'IconPlayerPlay',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
E um exemplo usando `CommandModal` para solicitar confirmação antes de executar:
|
||||
|
||||
```tsx src/front-components/delete-draft.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { CommandModal } from 'twenty-sdk/command';
|
||||
|
||||
const DeleteDraft = () => {
|
||||
const execute = async () => {
|
||||
// perform the deletion
|
||||
};
|
||||
|
||||
return (
|
||||
<CommandModal
|
||||
title="Delete draft?"
|
||||
subtitle="This action cannot be undone."
|
||||
execute={execute}
|
||||
confirmButtonText="Delete"
|
||||
confirmButtonAccent="danger"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'a7b8c9d0-e1f2-3456-abcd-567890123456',
|
||||
name: 'delete-draft',
|
||||
description: 'Deletes a draft with confirmation',
|
||||
component: DeleteDraft,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'b8c9d0e1-f2a3-4567-bcde-678901234567',
|
||||
label: 'Delete draft',
|
||||
icon: 'IconTrash',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### Acessando o contexto de execução
|
||||
|
||||
Dentro do seu componente, use hooks do SDK para acessar o usuário atual, o registro e a instância do componente:
|
||||
@@ -858,6 +952,50 @@ Componentes de front-end podem acionar navegação, modais e notificações usan
|
||||
| `unmountFrontComponent()` | Desmontar o componente |
|
||||
| `updateProgress(progress)` | Atualizar um indicador de progresso |
|
||||
|
||||
Aqui está um exemplo que usa a API do host para exibir um snackbar e fechar o painel lateral após a conclusão de uma ação:
|
||||
|
||||
```tsx src/front-components/archive-record.tsx
|
||||
import { defineFrontComponent, useRecordId } from 'twenty-sdk';
|
||||
import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const ArchiveRecord = () => {
|
||||
const recordId = useRecordId();
|
||||
|
||||
const handleArchive = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
updateTask: {
|
||||
__args: { id: recordId, data: { status: 'ARCHIVED' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
await enqueueSnackbar({
|
||||
message: 'Record archived',
|
||||
variant: 'success',
|
||||
});
|
||||
|
||||
await closeSidePanel();
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px' }}>
|
||||
<p>Archive this record?</p>
|
||||
<button onClick={handleArchive}>Archive</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'c9d0e1f2-a3b4-5678-cdef-789012345678',
|
||||
name: 'archive-record',
|
||||
description: 'Archives the current record',
|
||||
component: ArchiveRecord,
|
||||
});
|
||||
```
|
||||
|
||||
#### Opções de comando
|
||||
|
||||
Adicionar um campo `command` a `defineFrontComponent` registra o componente no menu de comandos (Cmd+K). Se `isPinned` for `true`, ele também aparece como um botão de ação rápida no canto superior direito da página.
|
||||
@@ -1712,3 +1850,86 @@ yarn twenty uninstall
|
||||
# Skip the confirmation prompt
|
||||
yarn twenty uninstall --yes
|
||||
```
|
||||
|
||||
## Gerenciando remotos
|
||||
|
||||
Um **remoto** é um servidor Twenty ao qual seu aplicativo se conecta. Durante a configuração, o gerador de scaffold cria um para você automaticamente. Você pode adicionar mais remotos ou alternar entre eles a qualquer momento.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Suas credenciais são armazenadas em `~/.twenty/config.json`.
|
||||
|
||||
## CI com GitHub Actions
|
||||
|
||||
O gerador de scaffold cria um workflow do GitHub Actions pronto para uso em `.github/workflows/ci.yml`. Ele executa seus testes de integração automaticamente a cada push para `main` e em pull requests.
|
||||
|
||||
O workflow:
|
||||
|
||||
1. Faz checkout do seu código
|
||||
2. Inicializa um servidor Twenty temporário usando a ação `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. Instala as dependências com `yarn install --immutable`
|
||||
4. Executa `yarn test` com `TWENTY_API_URL` e `TWENTY_API_KEY` injetados a partir das saídas da ação
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Você não precisa configurar nenhum segredo — a ação `spawn-twenty-docker-image` inicia um servidor Twenty efêmero diretamente no runner e fornece os detalhes de conexão. O segredo `GITHUB_TOKEN` é fornecido automaticamente pelo GitHub.
|
||||
|
||||
Para fixar uma versão específica do Twenty em vez de `latest`, altere a variável de ambiente `TWENTY_VERSION` no topo do workflow.
|
||||
|
||||
@@ -7,7 +7,9 @@ description: Crie seu primeiro app do Twenty em minutos.
|
||||
Os aplicativos estão atualmente em testes alfa. O recurso é funcional, mas ainda está evoluindo.
|
||||
</Warning>
|
||||
|
||||
Os apps permitem que você estenda o Twenty com objetos, campos, funções de lógica, habilidades de IA e componentes de UI personalizados — tudo gerenciado como código.
|
||||
## O que são aplicativos?
|
||||
|
||||
Os aplicativos permitem que você estenda o Twenty com objetos e campos personalizados, funções lógicas, componentes de front-end, habilidades de IA e mais — tudo gerenciado como código. Em vez de configurar tudo pela UI, você define seu modelo de dados e a lógica em TypeScript e implanta em um ou mais workspaces.
|
||||
|
||||
## Pré-requisitos
|
||||
|
||||
@@ -17,7 +19,9 @@ Antes de começar, verifique se o seguinte está instalado na sua máquina:
|
||||
* **Yarn 4** — Vem com o Node.js via Corepack. Ative-o executando `corepack enable`
|
||||
* **Docker** — [Baixe aqui](https://www.docker.com/products/docker-desktop/). Necessário para executar uma instância local do Twenty. Não é necessário se você já tiver um servidor Twenty em execução.
|
||||
|
||||
## Passo 1: Gere o scaffold do seu aplicativo
|
||||
## Crie seu primeiro aplicativo
|
||||
|
||||
### Gere o scaffold do seu aplicativo
|
||||
|
||||
Abra um terminal e execute:
|
||||
|
||||
@@ -29,18 +33,7 @@ Será solicitado que você informe um nome e uma descrição para o seu aplicati
|
||||
|
||||
Isso cria uma nova pasta chamada `my-twenty-app` com tudo de que você precisa.
|
||||
|
||||
<Note>
|
||||
O gerador de scaffold oferece suporte a estas flags:
|
||||
|
||||
* `--minimal` — gera apenas os arquivos essenciais, sem exemplos (padrão)
|
||||
* `--exhaustive` — gera todas as entidades de exemplo
|
||||
* `--name <name>` — define o nome do aplicativo (pula o prompt)
|
||||
* `--display-name <displayName>` — define o nome de exibição (pula o prompt)
|
||||
* `--description <description>` — define a descrição (pula o prompt)
|
||||
* `--skip-local-instance` — ignora o prompt de configuração do servidor local
|
||||
</Note>
|
||||
|
||||
## Passo 2: Configure uma instância local do Twenty
|
||||
### Configure uma instância local do Twenty
|
||||
|
||||
O gerador de scaffold perguntará:
|
||||
|
||||
@@ -53,7 +46,7 @@ O gerador de scaffold perguntará:
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Deve iniciar instância local?" />
|
||||
</div>
|
||||
|
||||
## Passo 3: Faça login no seu espaço de trabalho
|
||||
### Faça login no seu espaço de trabalho
|
||||
|
||||
Em seguida, uma janela do navegador será aberta com a página de login do Twenty. Faça login com a conta de demonstração pré-configurada:
|
||||
|
||||
@@ -64,7 +57,7 @@ Em seguida, uma janela do navegador será aberta com a página de login do Twent
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Tela de login do Twenty" />
|
||||
</div>
|
||||
|
||||
## Passo 4: Autorize o aplicativo
|
||||
### Autorize o aplicativo
|
||||
|
||||
Após fazer login, você verá uma tela de autorização. Isso permite que seu aplicativo interaja com seu espaço de trabalho.
|
||||
|
||||
@@ -80,7 +73,7 @@ Depois de autorizado, seu terminal confirmará que tudo está configurado.
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="Scaffold do aplicativo criado com sucesso" />
|
||||
</div>
|
||||
|
||||
## Passo 5: Comece a desenvolver
|
||||
### Comece a desenvolver
|
||||
|
||||
Entre na nova pasta do seu aplicativo e inicie o servidor de desenvolvimento:
|
||||
|
||||
@@ -105,7 +98,7 @@ O modo de desenvolvimento só está disponível em instâncias do Twenty em modo
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Saída do terminal no modo de desenvolvimento" />
|
||||
</div>
|
||||
|
||||
## Passo 6: Veja seu aplicativo no Twenty
|
||||
### Veja seu aplicativo no Twenty
|
||||
|
||||
Abra [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) no seu navegador. Navegue até **Settings > Apps** e selecione a aba **Developer**. Você deverá ver seu aplicativo listado em **Your Apps**:
|
||||
|
||||
@@ -133,13 +126,28 @@ Altere para a aba **Content** para ver tudo o que seu aplicativo oferece — obj
|
||||
|
||||
Tudo pronto! Edite qualquer arquivo em `src/` e as alterações serão detectadas automaticamente.
|
||||
|
||||
Acesse [Criando aplicativos](/l/pt/developers/extend/apps/building) para um guia detalhado sobre criação de objetos, funções de lógica, componentes de front-end, habilidades e mais.
|
||||
---
|
||||
|
||||
## O que você pode criar
|
||||
|
||||
Os aplicativos são compostos por **entidades** — cada uma definida como um arquivo TypeScript com um único `export default`:
|
||||
|
||||
| Entidade | O que faz |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
||||
| **Objetos e campos** | Defina modelos de dados personalizados (como cartão postal, fatura) com campos tipados |
|
||||
| **Funções lógicas** | Funções TypeScript do lado do servidor acionadas por rotas HTTP, agendamentos do cron ou eventos de banco de dados |
|
||||
| **Componentes de front-end** | Componentes React que são renderizados na UI do Twenty (painel lateral, widgets, menu de comandos) |
|
||||
| **Habilidades e agentes** | Recursos de IA — instruções reutilizáveis e assistentes autônomos |
|
||||
| **Exibições e navegação** | Exibições de lista pré-configuradas e itens de menu da barra lateral para seus objetos |
|
||||
| **Layouts de página** | Páginas de detalhes de registros personalizadas com abas e widgets |
|
||||
|
||||
Acesse [Criando aplicativos](/l/pt/developers/extend/apps/building) para um guia detalhado sobre cada tipo de entidade.
|
||||
|
||||
---
|
||||
|
||||
## Estrutura do projeto
|
||||
|
||||
O gerador de scaffold cria a seguinte estrutura de arquivos (mostrada com o modo `--exhaustive`, que inclui exemplos para cada tipo de entidade):
|
||||
A ferramenta de scaffolding gera a seguinte estrutura de arquivos:
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -148,160 +156,50 @@ my-twenty-app/
|
||||
.gitignore
|
||||
.nvmrc
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── 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
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── default-role.ts # Default role for logic functions
|
||||
├── constants/
|
||||
│ └── universal-identifiers.ts # Auto-generated UUIDs and app metadata
|
||||
└── __tests__/
|
||||
├── setup-test.ts # Test setup (server health check, config)
|
||||
└── app-install.integration-test.ts # Integration test
|
||||
```
|
||||
|
||||
Por padrão (`--minimal`), apenas os arquivos principais são criados: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` e `logic-functions/post-install.ts`. Use `--exhaustive` para incluir todos os arquivos de exemplo mostrados acima.
|
||||
### Começando a partir de um exemplo
|
||||
|
||||
Para começar a partir de um exemplo mais completo com objetos, campos, funções de lógica, componentes de front-end e mais, use a opção `--example`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
npx create-twenty-app@latest my-twenty-app --example postcard
|
||||
```
|
||||
|
||||
Os exemplos são obtidos do diretório [twenty-apps/examples](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples) no GitHub. Você também pode criar o scaffolding de entidades individuais em um projeto existente com `yarn twenty add` (veja [Criando aplicativos](/l/pt/developers/extend/apps/building#scaffolding-entities-with-yarn-twenty-add)).
|
||||
|
||||
### Arquivos principais
|
||||
|
||||
| Arquivo / Pasta | Finalidade |
|
||||
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `package.json` | Declara o nome, a versão e as dependências do seu aplicativo. Inclui um script `twenty` para que você possa executar `yarn twenty help` e ver todos os comandos. |
|
||||
| `src/application-config.ts` | **Obrigatório.** O principal arquivo de configuração do seu aplicativo. |
|
||||
| `src/roles/` | Define papéis que controlam o que suas funções de lógica podem acessar. |
|
||||
| `src/logic-functions/` | Funções do lado do servidor acionadas por rotas, agendamentos do cron ou eventos de banco de dados. |
|
||||
| `src/front-components/` | Componentes React que renderizam dentro da interface do Twenty. |
|
||||
| `src/objects/` | Definições de objetos personalizados para estender seu modelo de dados. |
|
||||
| `src/fields/` | Campos personalizados adicionados a objetos existentes. |
|
||||
| `src/views/` | Configurações de visualizações salvas. |
|
||||
| `src/navigation-menu-items/` | Links personalizados na navegação da barra lateral. |
|
||||
| `src/skills/` | Habilidades que estendem os agentes de IA do Twenty. |
|
||||
| `src/agents/` | Agentes de IA com prompts personalizados. |
|
||||
| `src/page-layouts/` | Layouts de página personalizados para visualizações de registros. |
|
||||
| `src/__tests__/` | Testes de integração (configuração + teste de exemplo). |
|
||||
| `public/` | Recursos estáticos (imagens, fontes) servidos com seu aplicativo. |
|
||||
| Arquivo / Pasta | Finalidade |
|
||||
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `package.json` | Declara o nome, a versão e as dependências do seu aplicativo. Inclui um script `twenty` para que você possa executar `yarn twenty help` e ver todos os comandos. |
|
||||
| `src/application-config.ts` | **Obrigatório.** O principal arquivo de configuração do seu aplicativo. |
|
||||
| `src/default-role.ts` | Papel padrão que controla o que suas funções de lógica podem acessar. |
|
||||
| `src/constants/universal-identifiers.ts` | UUIDs gerados automaticamente e metadados do aplicativo (nome de exibição, descrição). |
|
||||
| `src/__tests__/` | Testes de integração (configuração + teste de exemplo). |
|
||||
| `public/` | Recursos estáticos (imagens, fontes) servidos com seu aplicativo. |
|
||||
|
||||
## Gerenciando remotos
|
||||
## Servidor de desenvolvimento local
|
||||
|
||||
Um **remoto** é um servidor Twenty ao qual seu aplicativo se conecta. Durante a configuração, o gerador de scaffold cria um para você automaticamente. Você pode adicionar mais remotos ou alternar entre eles a qualquer momento.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Suas credenciais são armazenadas em `~/.twenty/config.json`.
|
||||
|
||||
## Servidor de desenvolvimento local (`yarn twenty server`)
|
||||
|
||||
A CLI pode gerenciar um servidor Twenty local em execução no Docker. Este é o mesmo servidor iniciado automaticamente quando você cria o scaffold de um aplicativo com `create-twenty-app`, mas você também pode gerenciá-lo manualmente.
|
||||
|
||||
### Iniciando o servidor
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
Isso baixa a imagem Docker `twentycrm/twenty-app-dev:latest` (se ainda não estiver presente), cria um contêiner chamado `twenty-app-dev` e o inicia na porta **2020**. A CLI aguarda até que o servidor passe na verificação de integridade antes de retornar.
|
||||
|
||||
Dois volumes do Docker são criados para persistir os dados entre reinicializações:
|
||||
|
||||
* `twenty-app-dev-data` — banco de dados PostgreSQL
|
||||
* `twenty-app-dev-storage` — armazenamento de arquivos
|
||||
|
||||
Se a porta 2020 já estiver em uso, você pode iniciar em uma porta diferente:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
A CLI configura automaticamente as variáveis internas do contêiner `NODE_PORT` e `SERVER_URL` para corresponderem à porta escolhida, para que as funções de lógica, o OAuth e toda a comunicação interna de rede funcionem corretamente.
|
||||
|
||||
Depois de iniciado, o servidor é registrado automaticamente como o remoto `local` na configuração da sua CLI.
|
||||
|
||||
### Verificando o status do servidor
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Exibe se o servidor está em execução, sua URL e as credenciais de login padrão (`[email protected]` / `[email protected]`).
|
||||
|
||||
### Visualizando os logs do servidor
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Transmite os logs do contêiner. Use `--lines` para controlar quantas linhas recentes mostrar:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Parando o servidor
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Interrompe o contêiner. Seus dados são preservados nos volumes do Docker — o próximo `start` continua de onde você parou.
|
||||
|
||||
### Redefinindo o servidor
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Remove o contêiner **e** exclui os dois volumes do Docker, apagando todos os dados. O próximo `start` cria uma instância nova.
|
||||
|
||||
<Note>
|
||||
O servidor requer que o **Docker** esteja em execução. Se você vir um erro "Docker not running", certifique-se de que o Docker Desktop (ou o daemon do Docker) esteja iniciado.
|
||||
</Note>
|
||||
|
||||
### Referência de comandos
|
||||
A ferramenta de scaffolding já iniciou um servidor local do Twenty para você. Para gerenciá-lo depois, use `yarn twenty server`:
|
||||
|
||||
| Comando | Descrição |
|
||||
| -------------------------------------- | ------------------------------------------------------ |
|
||||
@@ -313,65 +211,11 @@ Remove o contêiner **e** exclui os dois volumes do Docker, apagando todos os da
|
||||
| `yarn twenty server logs --lines 100` | Mostra as últimas 100 linhas de log |
|
||||
| `yarn twenty server reset` | Exclui todos os dados e inicia do zero |
|
||||
|
||||
## CI com GitHub Actions
|
||||
Os dados são persistidos entre reinicializações em dois volumes do Docker (`twenty-app-dev-data` para PostgreSQL, `twenty-app-dev-storage` para arquivos). Use `reset` para apagar tudo e começar do zero.
|
||||
|
||||
O gerador de scaffold cria um workflow do GitHub Actions pronto para uso em `.github/workflows/ci.yml`. Ele executa seus testes de integração automaticamente a cada push para `main` e em pull requests.
|
||||
|
||||
O workflow:
|
||||
|
||||
1. Faz checkout do seu código
|
||||
2. Inicializa um servidor Twenty temporário usando a ação `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. Instala as dependências com `yarn install --immutable`
|
||||
4. Executa `yarn test` com `TWENTY_API_URL` e `TWENTY_API_KEY` injetados a partir das saídas da ação
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Você não precisa configurar nenhum segredo — a ação `spawn-twenty-docker-image` inicia um servidor Twenty efêmero diretamente no runner e fornece os detalhes de conexão. O segredo `GITHUB_TOKEN` é fornecido automaticamente pelo GitHub.
|
||||
|
||||
Para fixar uma versão específica do Twenty em vez de `latest`, altere a variável de ambiente `TWENTY_VERSION` no topo do workflow.
|
||||
<Note>
|
||||
O servidor requer que o **Docker** esteja em execução. Se você vir um erro "Docker not running", certifique-se de que o Docker Desktop (ou o daemon do Docker) esteja iniciado.
|
||||
</Note>
|
||||
|
||||
## Configuração manual (sem o gerador)
|
||||
|
||||
|
||||
@@ -52,7 +52,11 @@ yarn twenty deploy
|
||||
|
||||
### Compartilhando um aplicativo implantado
|
||||
|
||||
Aplicativos em tarball não são listados no marketplace público, então outros espaços de trabalho no mesmo servidor não os descobrirão ao navegar. Para compartilhar um aplicativo implantado:
|
||||
<Warning>
|
||||
Sharing private (tarball) apps across workspaces is an **Enterprise** feature. The **Distribution** tab will show an upgrade prompt instead of the share controls until your workspace has a valid Enterprise key. See [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to activate it.
|
||||
</Warning>
|
||||
|
||||
Aplicativos em tarball não são listados no marketplace público, então outros espaços de trabalho no mesmo servidor não os descobrirão ao navegar. Once your workspace is on the Enterprise plan, you can share a deployed app like this:
|
||||
|
||||
1. Vá para **Configurações > Aplicações > Registros** e abra seu aplicativo
|
||||
2. Na guia **Distribuição**, clique em **Copiar link de compartilhamento**
|
||||
@@ -60,10 +64,6 @@ Aplicativos em tarball não são listados no marketplace público, então outros
|
||||
|
||||
O link de compartilhamento usa a URL base do servidor (sem qualquer subdomínio de espaço de trabalho), para funcionar em qualquer espaço de trabalho no servidor.
|
||||
|
||||
<Warning>
|
||||
Compartilhar apps privados é um recurso do plano Enterprise. Vá para [Configurações > Painel de Administração > Enterprise](/settings/admin-panel#enterprise) para ativá-lo.
|
||||
</Warning>
|
||||
|
||||
### Gerenciamento de versões
|
||||
|
||||
Para lançar uma atualização:
|
||||
|
||||
@@ -81,7 +81,7 @@ import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
universalIdentifier: '39783023-bcac-41e3-b0d2-ff1944d8465d',
|
||||
displayName: 'My Twenty App',
|
||||
description: 'My first Twenty app',
|
||||
icon: 'IconWorld',
|
||||
@@ -717,6 +717,13 @@ Puncte cheie:
|
||||
|
||||
Componentele front-end sunt componente React care se afișează direct în interfața Twenty. Rulează într-un **Web Worker** izolat folosind Remote DOM — codul este izolat (sandboxed), dar se redă nativ în pagină, nu într-un iframe.
|
||||
|
||||
#### Unde pot fi utilizate componentele frontale
|
||||
|
||||
Componentele frontale pot fi afișate în două locații în cadrul Twenty:
|
||||
|
||||
* **Panou lateral** — Componentele frontale care nu sunt headless se deschid în panoul lateral din dreapta. Acesta este comportamentul implicit atunci când o componentă frontală este declanșată din meniul de comenzi.
|
||||
* **Widgeturi (tablouri de bord și pagini de înregistrare)** — Componentele frontale pot fi încorporate ca widgeturi în machetele de pagină. La configurarea unui tablou de bord sau a machetei unei pagini de înregistrare, utilizatorii pot adăuga un widget de componentă frontală.
|
||||
|
||||
#### Exemplu de bază
|
||||
|
||||
Cel mai rapid mod de a vedea o componentă front-end în acțiune este să o înregistrați ca o **comandă**. Adăugarea unui câmp `command` cu `isPinned: true` o face să apară ca un buton de acțiune rapidă în colțul din dreapta sus al paginii — nu este nevoie de layout de pagină:
|
||||
@@ -774,9 +781,13 @@ Faceți clic pe el pentru a afișa componenta inline.
|
||||
|
||||
Dincolo de comenzi, puteți încorpora o componentă front-end direct într-o pagină de înregistrare adăugând-o ca widget într-un **layout de pagină**. Consultați secțiunea [definePageLayout](#definepagelayout) pentru detalii.
|
||||
|
||||
#### Componente headless (`isHeadless: true`)
|
||||
#### Headless vs non-headless
|
||||
|
||||
Componentele headless nu redau nicio interfață vizibilă, dar rulează în continuare logica React. Acest lucru este util pentru **componente de efect** — componente care execută efecte secundare la montare, cum ar fi sincronizarea datelor, pornirea unui cronometru, ascultarea evenimentelor sau declanșarea unei notificări.
|
||||
Componentele frontale au două moduri de randare controlate de opțiunea `isHeadless`:
|
||||
|
||||
**Non-headless (implicit)** — Componenta afișează o interfață vizibilă. Când este declanșat din meniul de comenzi, se deschide în panoul lateral. Acesta este comportamentul implicit când `isHeadless` este `false` sau omis.
|
||||
|
||||
**Headless (`isHeadless: true`)** — Componenta se montează invizibil în fundal. Nu deschide panoul lateral. Componentele headless sunt concepute pentru acțiuni care execută logică și apoi se demontează — de exemplu, rularea unei sarcini asincrone, navigarea la o pagină sau afișarea unui modal de confirmare. Se potrivesc în mod natural cu componentele Command din SDK descrise mai jos.
|
||||
|
||||
```tsx src/front-components/sync-tracker.tsx
|
||||
import { defineFrontComponent, useRecordId, enqueueSnackbar } from 'twenty-sdk';
|
||||
@@ -803,6 +814,89 @@ export default defineFrontComponent({
|
||||
|
||||
Deoarece componenta returnează `null`, Twenty omite redarea unui container pentru ea — nu apare spațiu gol în layout. Componenta are în continuare acces la toate hook-urile și la API-ul de comunicare cu gazda.
|
||||
|
||||
#### Componentele Command din SDK
|
||||
|
||||
Pachetul `twenty-sdk` oferă patru componente ajutătoare Command, concepute pentru componente front-end headless. Fiecare componentă execută o acțiune la montare, gestionează erorile afișând o notificare snackbar și demontează automat componenta de interfață la final.
|
||||
|
||||
Importă-le din `twenty-sdk/command`:
|
||||
|
||||
* **`Command`** — Rulează un callback asincron prin prop-ul `execute`.
|
||||
* **`CommandLink`** — Navighează către o rută a aplicației. Props: `to`, `params`, `queryParams`, `options`.
|
||||
* **`CommandModal`** — Deschide un modal de confirmare. Dacă utilizatorul confirmă, execută callback-ul `execute`. Props: `title`, `subtitle`, `execute`, `confirmButtonText`, `confirmButtonAccent`.
|
||||
* **`CommandOpenSidePanelPage`** — Deschide o anumită pagină din panoul lateral. Props: `page`, `pageTitle`, `pageIcon`.
|
||||
|
||||
Iată un exemplu complet de componentă front-end headless care folosește `Command` pentru a rula o acțiune din meniul de comenzi:
|
||||
|
||||
```tsx src/front-components/run-action.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { Command } from 'twenty-sdk/command';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const RunAction = () => {
|
||||
const execute = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
createTask: {
|
||||
__args: { data: { title: 'Created by my app' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return <Command execute={execute} />;
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'e5f6a7b8-c9d0-1234-efab-345678901234',
|
||||
name: 'run-action',
|
||||
description: 'Creates a task from the command menu',
|
||||
component: RunAction,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'f6a7b8c9-d0e1-2345-fabc-456789012345',
|
||||
label: 'Run my action',
|
||||
icon: 'IconPlayerPlay',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Și un exemplu care folosește `CommandModal` pentru a cere confirmarea înainte de execuție:
|
||||
|
||||
```tsx src/front-components/delete-draft.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { CommandModal } from 'twenty-sdk/command';
|
||||
|
||||
const DeleteDraft = () => {
|
||||
const execute = async () => {
|
||||
// perform the deletion
|
||||
};
|
||||
|
||||
return (
|
||||
<CommandModal
|
||||
title="Delete draft?"
|
||||
subtitle="This action cannot be undone."
|
||||
execute={execute}
|
||||
confirmButtonText="Delete"
|
||||
confirmButtonAccent="danger"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'a7b8c9d0-e1f2-3456-abcd-567890123456',
|
||||
name: 'delete-draft',
|
||||
description: 'Deletes a draft with confirmation',
|
||||
component: DeleteDraft,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'b8c9d0e1-f2a3-4567-bcde-678901234567',
|
||||
label: 'Delete draft',
|
||||
icon: 'IconTrash',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### Accesarea contextului de rulare
|
||||
|
||||
În interiorul componentei, folosiți hook-urile SDK pentru a accesa utilizatorul curent, înregistrarea curentă și instanța componentei:
|
||||
@@ -859,6 +953,50 @@ Componentele front-end pot declanșa navigare, ferestre modale și notificări f
|
||||
| `unmountFrontComponent()` | Demontați componenta |
|
||||
| `updateProgress(progress)` | Actualizați un indicator de progres |
|
||||
|
||||
Iată un exemplu care folosește API-ul gazdă pentru a afișa un snackbar și a închide panoul lateral după finalizarea unei acțiuni:
|
||||
|
||||
```tsx src/front-components/archive-record.tsx
|
||||
import { defineFrontComponent, useRecordId } from 'twenty-sdk';
|
||||
import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const ArchiveRecord = () => {
|
||||
const recordId = useRecordId();
|
||||
|
||||
const handleArchive = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
updateTask: {
|
||||
__args: { id: recordId, data: { status: 'ARCHIVED' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
await enqueueSnackbar({
|
||||
message: 'Record archived',
|
||||
variant: 'success',
|
||||
});
|
||||
|
||||
await closeSidePanel();
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px' }}>
|
||||
<p>Archive this record?</p>
|
||||
<button onClick={handleArchive}>Archive</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'c9d0e1f2-a3b4-5678-cdef-789012345678',
|
||||
name: 'archive-record',
|
||||
description: 'Archives the current record',
|
||||
component: ArchiveRecord,
|
||||
});
|
||||
```
|
||||
|
||||
#### Opțiuni pentru comandă
|
||||
|
||||
Adăugarea unui câmp `command` la `defineFrontComponent` înregistrează componenta în meniul de comenzi (Cmd+K). Dacă `isPinned` este `true`, apare și ca buton de acțiune rapidă în colțul din dreapta sus al paginii.
|
||||
@@ -1713,3 +1851,86 @@ yarn twenty uninstall
|
||||
# Skip the confirmation prompt
|
||||
yarn twenty uninstall --yes
|
||||
```
|
||||
|
||||
## Gestionarea remote-urilor
|
||||
|
||||
Un „remote” este un server Twenty la care se conectează aplicația. În timpul configurării, generatorul de schelet creează automat unul pentru dvs. Puteți adăuga mai multe remote-uri sau comuta între ele oricând.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Acreditările dvs. sunt stocate în `~/.twenty/config.json`.
|
||||
|
||||
## CI cu GitHub Actions
|
||||
|
||||
Scaffolderul generează un workflow GitHub Actions gata de utilizare în `.github/workflows/ci.yml`. Rulează automat testele de integrare la fiecare push pe `main` și la pull request-uri.
|
||||
|
||||
Workflow-ul:
|
||||
|
||||
1. Preia codul
|
||||
2. Pornește un server Twenty temporar folosind acțiunea `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. Instalează dependențele cu `yarn install --immutable`
|
||||
4. Rulează `yarn test` cu `TWENTY_API_URL` și `TWENTY_API_KEY` injectate din rezultatele acțiunii
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Nu trebuie să configurați niciun secret — acțiunea `spawn-twenty-docker-image` pornește un server Twenty efemer direct în runner și oferă detaliile de conectare. Secretul `GITHUB_TOKEN` este furnizat automat de GitHub.
|
||||
|
||||
Pentru a fixa o versiune Twenty specifică în loc de `latest`, modificați variabila de mediu `TWENTY_VERSION` din partea de sus a workflow-ului.
|
||||
|
||||
@@ -7,7 +7,9 @@ description: Creați prima dvs. aplicație Twenty în câteva minute.
|
||||
Aplicațiile sunt în prezent în testare alfa. Caracteristica funcționează, dar este încă în dezvoltare.
|
||||
</Warning>
|
||||
|
||||
Aplicațiile vă permit să extindeți Twenty cu obiecte personalizate, câmpuri, funcții logice, abilități IA și componente UI — toate gestionate ca cod.
|
||||
## Ce sunt aplicațiile?
|
||||
|
||||
Aplicațiile vă permit să extindeți Twenty cu obiecte personalizate, câmpuri, funcții logice, componente front-end, abilități IA și altele — toate gestionate ca cod. În loc să configurați totul prin interfața de utilizator (UI), vă definiți modelul de date și logica în TypeScript și le implementați în unul sau mai multe spații de lucru.
|
||||
|
||||
## Cerințe
|
||||
|
||||
@@ -17,7 +19,9 @@ Aplicațiile vă permit să extindeți Twenty cu obiecte personalizate, câmpuri
|
||||
* **Yarn 4** — Vine împreună cu Node.js prin Corepack. Activați-l rulând `corepack enable`
|
||||
* **Docker** — [Descărcați aici](https://www.docker.com/products/docker-desktop/). Necesar pentru a rula o instanță Twenty locală. Nu este necesar dacă aveți deja un server Twenty care rulează.
|
||||
|
||||
## Pasul 1: Creați scheletul aplicației
|
||||
## Creați prima dvs. aplicație
|
||||
|
||||
### Creați scheletul aplicației
|
||||
|
||||
Deschideți un terminal și rulați:
|
||||
|
||||
@@ -29,18 +33,7 @@ Vi se va cere să introduceți un nume și o descriere pentru aplicația dvs. Ap
|
||||
|
||||
Aceasta creează un folder nou numit `my-twenty-app` cu tot ce aveți nevoie.
|
||||
|
||||
<Note>
|
||||
Generatorul de schelet acceptă următoarele opțiuni:
|
||||
|
||||
* `--minimal` — generează doar fișierele esențiale, fără exemple (implicit)
|
||||
* `--exhaustive` — generează toate entitățile de exemplu
|
||||
* `--name <name>` — setează numele aplicației (omite solicitarea)
|
||||
* `--display-name <displayName>` — setează numele afișat (omite solicitarea)
|
||||
* `--description <description>` — setează descrierea (omite solicitarea)
|
||||
* `--skip-local-instance` — omite solicitarea de configurare a serverului local
|
||||
</Note>
|
||||
|
||||
## Pasul 2: Configurați o instanță Twenty locală
|
||||
### Configurați o instanță Twenty locală
|
||||
|
||||
Generatorul de schelet va întreba:
|
||||
|
||||
@@ -53,7 +46,7 @@ Generatorul de schelet va întreba:
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Porniți instanța locală?" />
|
||||
</div>
|
||||
|
||||
## Pasul 3: Autentificați-vă în spațiul dvs. de lucru
|
||||
### Autentificați-vă în spațiul dvs. de lucru
|
||||
|
||||
În continuare, se va deschide o fereastră de browser cu pagina de autentificare Twenty. Autentificați-vă cu contul demo preconfigurat:
|
||||
|
||||
@@ -64,7 +57,7 @@ Generatorul de schelet va întreba:
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Ecranul de autentificare Twenty" />
|
||||
</div>
|
||||
|
||||
## Pasul 4: Autorizați aplicația
|
||||
### Autorizați aplicația
|
||||
|
||||
După autentificare, veți vedea un ecran de autorizare. Acest lucru permite aplicației dvs. să interacționeze cu spațiul dvs. de lucru.
|
||||
|
||||
@@ -80,7 +73,7 @@ După autorizare, terminalul va confirma că totul este configurat.
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="Aplicația a fost creată cu succes" />
|
||||
</div>
|
||||
|
||||
## Pasul 5: Începeți dezvoltarea
|
||||
### Începeți dezvoltarea
|
||||
|
||||
Intrați în noul folder al aplicației și porniți serverul de dezvoltare:
|
||||
|
||||
@@ -105,7 +98,7 @@ Modul de dezvoltare este disponibil doar pe instanțele Twenty care rulează în
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Ieșirea terminalului în modul de dezvoltare" />
|
||||
</div>
|
||||
|
||||
## Pasul 6: Vedeți aplicația în Twenty
|
||||
### Vedeți aplicația în Twenty
|
||||
|
||||
Deschideți [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) în browser. Navigați la **Settings > Apps** și selectați fila **Developer**. Ar trebui să vedeți aplicația listată la **Your Apps**:
|
||||
|
||||
@@ -133,13 +126,28 @@ Comutați la fila **Content** pentru a vedea tot ceea ce oferă aplicația — o
|
||||
|
||||
Totul este gata! Editați orice fișier din `src/`, iar modificările vor fi preluate automat.
|
||||
|
||||
Accesați [Construirea aplicațiilor](/l/ro/developers/extend/apps/building) pentru un ghid detaliat despre crearea de obiecte, funcții logice, componente front-end, abilități și altele.
|
||||
---
|
||||
|
||||
## Ce puteți construi
|
||||
|
||||
Aplicațiile sunt compuse din **entități** — fiecare definită într-un fișier TypeScript cu un singur `export default`:
|
||||
|
||||
| Entitate | Ce face |
|
||||
| --------------------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| **Obiecte și câmpuri** | Definiți modele de date personalizate (cum ar fi Post Card, Invoice) cu câmpuri de tip definit |
|
||||
| **Funcții logice** | Funcții TypeScript pe server declanșate de rute HTTP, programări cron sau evenimente din baza de date |
|
||||
| **Componente front-end** | Componente React care se afișează în UI-ul Twenty (panou lateral, widgeturi, meniul de comenzi) |
|
||||
| **Abilități și agenți** | Capabilități AI — instrucțiuni reutilizabile și asistenți autonomi |
|
||||
| **Vizualizări și navigare** | Vizualizări de listă preconfigurate și elemente de meniu în bara laterală pentru obiectele dvs. |
|
||||
| **Layouturi de pagină** | Pagini personalizate de detalii ale înregistrărilor cu file și widgeturi |
|
||||
|
||||
Accesați [Construirea aplicațiilor](/l/ro/developers/extend/apps/building) pentru un ghid detaliat despre fiecare tip de entitate.
|
||||
|
||||
---
|
||||
|
||||
## Structura proiectului
|
||||
|
||||
Generatorul de schelet generează următoarea structură de fișiere (afișată cu modul `--exhaustive`, care include exemple pentru fiecare tip de entitate):
|
||||
Generatorul de schelete generează următoarea structură de fișiere:
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -148,160 +156,50 @@ my-twenty-app/
|
||||
.gitignore
|
||||
.nvmrc
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── 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
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── default-role.ts # Default role for logic functions
|
||||
├── constants/
|
||||
│ └── universal-identifiers.ts # Auto-generated UUIDs and app metadata
|
||||
└── __tests__/
|
||||
├── setup-test.ts # Test setup (server health check, config)
|
||||
└── app-install.integration-test.ts # Integration test
|
||||
```
|
||||
|
||||
În mod implicit (`--minimal`), sunt create doar fișierele de bază: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` și `logic-functions/post-install.ts`. Folosiți `--exhaustive` pentru a include toate fișierele de exemplu prezentate mai sus.
|
||||
### Pornind de la un exemplu
|
||||
|
||||
Pentru a porni de la un exemplu mai complet cu obiecte, câmpuri, funcții logice, componente front-end și altele, folosiți opțiunea `--example`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
npx create-twenty-app@latest my-twenty-app --example postcard
|
||||
```
|
||||
|
||||
Exemplele sunt preluate din directorul [twenty-apps/examples](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples) de pe GitHub. Puteți, de asemenea, să creați scheletul entităților individuale într-un proiect existent cu `yarn twenty add` (consultați [Construirea aplicațiilor](/l/ro/developers/extend/apps/building#scaffolding-entities-with-yarn-twenty-add)).
|
||||
|
||||
### Fișiere cheie
|
||||
|
||||
| Fișier / Folder | Scop |
|
||||
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `package.json` | Declară numele aplicației, versiunea și dependențele. Include un script `twenty` astfel încât să puteți rula `yarn twenty help` pentru a vedea toate comenzile. |
|
||||
| `src/application-config.ts` | **Necesar.** Fișierul principal de configurare pentru aplicație. |
|
||||
| `src/roles/` | Definește roluri care controlează la ce pot avea acces funcțiile logice. |
|
||||
| `src/logic-functions/` | Funcții pe server declanșate de rute, programări cron sau evenimente din baza de date. |
|
||||
| `src/front-components/` | Componente React care se afișează în interfața Twenty. |
|
||||
| `src/objects/` | Definiții de obiecte personalizate pentru a extinde modelul de date. |
|
||||
| `src/fields/` | Câmpuri personalizate adăugate obiectelor existente. |
|
||||
| `src/views/` | Configurații pentru vizualizări salvate. |
|
||||
| `src/navigation-menu-items/` | Linkuri personalizate în bara laterală de navigare. |
|
||||
| `src/skills/` | Abilități care extind capabilitățile agenților AI ai Twenty. |
|
||||
| `src/agents/` | Agenți AI cu prompturi personalizate. |
|
||||
| `src/page-layouts/` | Machete de pagină personalizate pentru vizualizările de înregistrare. |
|
||||
| `src/__tests__/` | Teste de integrare (configurare + test exemplu). |
|
||||
| `public/` | Resurse statice (imagini, fonturi) servite împreună cu aplicația. |
|
||||
| Fișier / Folder | Scop |
|
||||
| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `package.json` | Declară numele aplicației, versiunea și dependențele. Include un script `twenty` astfel încât să puteți rula `yarn twenty help` pentru a vedea toate comenzile. |
|
||||
| `src/application-config.ts` | **Necesar.** Fișierul principal de configurare pentru aplicație. |
|
||||
| `src/default-role.ts` | Rol implicit care controlează la ce pot avea acces funcțiile logice. |
|
||||
| `src/constants/universal-identifiers.ts` | UUID-uri generate automat și metadatele aplicației (nume afișat, descriere). |
|
||||
| `src/__tests__/` | Teste de integrare (configurare + test exemplu). |
|
||||
| `public/` | Resurse statice (imagini, fonturi) servite împreună cu aplicația. |
|
||||
|
||||
## Gestionarea remote-urilor
|
||||
## Server de dezvoltare local
|
||||
|
||||
Un „remote” este un server Twenty la care se conectează aplicația. În timpul configurării, generatorul de schelet creează automat unul pentru dvs. Puteți adăuga mai multe remote-uri sau comuta între ele oricând.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Acreditările dvs. sunt stocate în `~/.twenty/config.json`.
|
||||
|
||||
## Server local de dezvoltare (`yarn twenty server`)
|
||||
|
||||
CLI-ul poate gestiona un server Twenty local care rulează în Docker. Acesta este același server pornit automat când creați scheletul unei aplicații cu `create-twenty-app`, dar îl puteți gestiona și manual.
|
||||
|
||||
### Pornirea serverului
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
Aceasta descarcă imaginea Docker `twentycrm/twenty-app-dev:latest` (dacă nu este deja prezentă), creează un container numit `twenty-app-dev` și îl pornește pe portul **2020**. CLI-ul așteaptă până când serverul trece verificarea de integritate înainte de a reveni.
|
||||
|
||||
Sunt create două volume Docker pentru a păstra datele între reporniri:
|
||||
|
||||
* `twenty-app-dev-data` — bază de date PostgreSQL
|
||||
* `twenty-app-dev-storage` — stocare fișiere
|
||||
|
||||
Dacă portul 2020 este deja utilizat, puteți porni pe un alt port:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
CLI-ul configurează automat `NODE_PORT` și `SERVER_URL` interne ale containerului pentru a se potrivi cu portul ales, astfel încât funcțiile logice, OAuth și toată rețeaua internă să funcționeze corect.
|
||||
|
||||
După pornire, serverul este înregistrat automat ca remote `local` în configurația CLI.
|
||||
|
||||
### Verificarea stării serverului
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Afișează dacă serverul rulează, URL-ul său și acreditările implicite de autentificare (`[email protected]` / `[email protected]`).
|
||||
|
||||
### Vizualizarea jurnalelor serverului
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Transmite în flux jurnalele containerului. Folosiți `--lines` pentru a controla câte linii recente să fie afișate:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Oprirea serverului
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Oprește containerul. Datele dvs. sunt păstrate în volumele Docker — următoarea comandă `start` reia de unde ați rămas.
|
||||
|
||||
### Resetarea serverului
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Elimină containerul **și** șterge ambele volume Docker, ștergând toate datele. Următoarea comandă `start` creează o instanță nouă.
|
||||
|
||||
<Note>
|
||||
Serverul necesită ca **Docker** să ruleze. Dacă vedeți eroarea "Docker not running", asigurați-vă că Docker Desktop (sau demonul Docker) este pornit.
|
||||
</Note>
|
||||
|
||||
### Referință pentru comenzi
|
||||
Generatorul de schelete a pornit deja un server Twenty local pentru dvs. Pentru a-l gestiona ulterior, folosiți `yarn twenty server`:
|
||||
|
||||
| Comandă | Descriere |
|
||||
| -------------------------------------- | ------------------------------------------------------------- |
|
||||
@@ -313,65 +211,11 @@ Elimină containerul **și** șterge ambele volume Docker, ștergând toate date
|
||||
| `yarn twenty server logs --lines 100` | Afișează ultimele 100 de linii de jurnal |
|
||||
| `yarn twenty server reset` | Șterge toate datele și pornește de la zero |
|
||||
|
||||
## CI cu GitHub Actions
|
||||
Datele sunt păstrate între reporniri în două volume Docker (`twenty-app-dev-data` pentru PostgreSQL, `twenty-app-dev-storage` pentru fișiere). Folosiți `reset` pentru a șterge totul și a porni de la zero.
|
||||
|
||||
Scaffolderul generează un workflow GitHub Actions gata de utilizare în `.github/workflows/ci.yml`. Rulează automat testele de integrare la fiecare push pe `main` și la pull request-uri.
|
||||
|
||||
Workflow-ul:
|
||||
|
||||
1. Preia codul
|
||||
2. Pornește un server Twenty temporar folosind acțiunea `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. Instalează dependențele cu `yarn install --immutable`
|
||||
4. Rulează `yarn test` cu `TWENTY_API_URL` și `TWENTY_API_KEY` injectate din rezultatele acțiunii
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Nu trebuie să configurați niciun secret — acțiunea `spawn-twenty-docker-image` pornește un server Twenty efemer direct în runner și oferă detaliile de conectare. Secretul `GITHUB_TOKEN` este furnizat automat de GitHub.
|
||||
|
||||
Pentru a fixa o versiune Twenty specifică în loc de `latest`, modificați variabila de mediu `TWENTY_VERSION` din partea de sus a workflow-ului.
|
||||
<Note>
|
||||
Serverul necesită ca **Docker** să ruleze. Dacă vedeți eroarea "Docker not running", asigurați-vă că Docker Desktop (sau demonul Docker) este pornit.
|
||||
</Note>
|
||||
|
||||
## Configurare manuală (fără generator)
|
||||
|
||||
|
||||
@@ -52,7 +52,11 @@ yarn twenty deploy
|
||||
|
||||
### Partajarea unei aplicații implementate
|
||||
|
||||
Aplicațiile tarball nu sunt listate în marketplace-ul public, astfel încât alte spații de lucru de pe același server nu le vor descoperi prin navigare. Pentru a partaja o aplicație implementată:
|
||||
<Warning>
|
||||
Sharing private (tarball) apps across workspaces is an **Enterprise** feature. The **Distribution** tab will show an upgrade prompt instead of the share controls until your workspace has a valid Enterprise key. See [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to activate it.
|
||||
</Warning>
|
||||
|
||||
Aplicațiile tarball nu sunt listate în marketplace-ul public, astfel încât alte spații de lucru de pe același server nu le vor descoperi prin navigare. Once your workspace is on the Enterprise plan, you can share a deployed app like this:
|
||||
|
||||
1. Mergi la **Setări > Aplicații > Înregistrări** și deschide aplicația ta
|
||||
2. În fila **Distribuție**, fă clic pe **Copiază linkul de partajare**
|
||||
@@ -60,10 +64,6 @@ Aplicațiile tarball nu sunt listate în marketplace-ul public, astfel încât a
|
||||
|
||||
Linkul de partajare folosește URL-ul de bază al serverului (fără niciun subdomeniu de spațiu de lucru), astfel încât funcționează pentru orice spațiu de lucru de pe server.
|
||||
|
||||
<Warning>
|
||||
Partajarea aplicațiilor private este o funcționalitate Enterprise. Mergi la [Setări > Panou de administrare > Enterprise](/settings/admin-panel#enterprise) pentru a o activa.
|
||||
</Warning>
|
||||
|
||||
### Gestionarea versiunilor
|
||||
|
||||
Pentru a lansa o actualizare:
|
||||
|
||||
@@ -81,7 +81,7 @@ import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
universalIdentifier: '39783023-bcac-41e3-b0d2-ff1944d8465d',
|
||||
displayName: 'My Twenty App',
|
||||
description: 'My first Twenty app',
|
||||
icon: 'IconWorld',
|
||||
@@ -716,6 +716,13 @@ yarn twenty exec --postInstall
|
||||
|
||||
Фронтенд-компоненты — это компоненты React, которые отображаются непосредственно внутри интерфейса Twenty. Они выполняются в изолированном Web Worker с использованием Remote DOM — ваш код изолирован (sandboxed), но рендерится нативно на странице, а не в iframe.
|
||||
|
||||
#### Где можно использовать фронт-компоненты
|
||||
|
||||
Фронт-компоненты могут отображаться в двух местах внутри Twenty:
|
||||
|
||||
* **Боковая панель** — фронт-компоненты с интерфейсом открываются в правой боковой панели. Это поведение по умолчанию, когда фронт-компонент запускается из меню команд.
|
||||
* **Виджеты (дашборды и страницы записей)** — фронт-компоненты можно встраивать как виджеты в макеты страниц. При настройке дашборда или макета страницы записи пользователи могут добавить виджет фронт-компонента.
|
||||
|
||||
#### Простой пример
|
||||
|
||||
Самый быстрый способ увидеть фронтенд-компонент в действии — зарегистрировать его как **команду**. Добавление поля `command` с `isPinned: true` делает его кнопкой быстрого действия в правом верхнем углу страницы — макет страницы не требуется:
|
||||
@@ -773,9 +780,13 @@ export default defineFrontComponent({
|
||||
|
||||
Помимо команд, вы можете встроить фронт-компонент непосредственно на страницу записи, добавив его как виджет в **макет страницы**. См. раздел [definePageLayout](#definepagelayout) для подробностей.
|
||||
|
||||
#### Headless-компоненты (`isHeadless: true`)
|
||||
#### Headless и non-headless
|
||||
|
||||
Headless-компоненты не отображают видимый UI, но при этом выполняют логику React. Это полезно для **компонентов-эффектов** — компонентов, которые выполняют побочные эффекты при монтировании, например синхронизацию данных, запуск таймера, прослушивание событий или показ уведомления.
|
||||
Фронт-компоненты поддерживают два режима отображения, управляемых опцией `isHeadless`:
|
||||
|
||||
**Non-headless (по умолчанию)** — компонент отображает видимый интерфейс. При запуске из меню команд он открывается в боковой панели. Это поведение по умолчанию, когда `isHeadless` имеет значение `false` или опущен.
|
||||
|
||||
**Headless (`isHeadless: true`)** — компонент монтируется невидимо в фоновом режиме. Он не открывает боковую панель. Компоненты headless предназначены для действий, которые выполняют логику и затем размонтируются — например, запуск асинхронной задачи, переход на страницу или показ модального окна подтверждения. Они естественно сочетаются с компонентами SDK Command, описанными ниже.
|
||||
|
||||
```tsx src/front-components/sync-tracker.tsx
|
||||
import { defineFrontComponent, useRecordId, enqueueSnackbar } from 'twenty-sdk';
|
||||
@@ -802,6 +813,89 @@ export default defineFrontComponent({
|
||||
|
||||
Поскольку компонент возвращает `null`, Twenty пропускает рендеринг контейнера для него — в макете не появляется пустое место. Компонент по-прежнему имеет доступ ко всем хукам и API взаимодействия с хостом.
|
||||
|
||||
#### Компоненты SDK Command
|
||||
|
||||
Пакет `twenty-sdk` предоставляет четыре вспомогательных компонента Command, предназначенных для headless фронт-компонентов. Каждый компонент выполняет действие при монтировании, обрабатывает ошибки, показывая уведомление snackbar, и автоматически размонтирует фронт-компонент по завершении.
|
||||
|
||||
Импортируйте их из `twenty-sdk/command`:
|
||||
|
||||
* **`Command`** — запускает асинхронный колбэк через проп `execute`.
|
||||
* **`CommandLink`** — переходит по пути внутри приложения. Пропы: `to`, `params`, `queryParams`, `options`.
|
||||
* **`CommandModal`** — открывает модальное окно подтверждения. Если пользователь подтвердит, выполняет колбэк `execute`. Пропы: `title`, `subtitle`, `execute`, `confirmButtonText`, `confirmButtonAccent`.
|
||||
* **`CommandOpenSidePanelPage`** — открывает конкретную страницу боковой панели. Пропы: `page`, `pageTitle`, `pageIcon`.
|
||||
|
||||
Полный пример headless фронт-компонента, использующего `Command` для запуска действия из меню команд:
|
||||
|
||||
```tsx src/front-components/run-action.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { Command } from 'twenty-sdk/command';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const RunAction = () => {
|
||||
const execute = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
createTask: {
|
||||
__args: { data: { title: 'Created by my app' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return <Command execute={execute} />;
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'e5f6a7b8-c9d0-1234-efab-345678901234',
|
||||
name: 'run-action',
|
||||
description: 'Creates a task from the command menu',
|
||||
component: RunAction,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'f6a7b8c9-d0e1-2345-fabc-456789012345',
|
||||
label: 'Run my action',
|
||||
icon: 'IconPlayerPlay',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
А также пример с использованием `CommandModal` для запроса подтверждения перед выполнением:
|
||||
|
||||
```tsx src/front-components/delete-draft.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { CommandModal } from 'twenty-sdk/command';
|
||||
|
||||
const DeleteDraft = () => {
|
||||
const execute = async () => {
|
||||
// perform the deletion
|
||||
};
|
||||
|
||||
return (
|
||||
<CommandModal
|
||||
title="Delete draft?"
|
||||
subtitle="This action cannot be undone."
|
||||
execute={execute}
|
||||
confirmButtonText="Delete"
|
||||
confirmButtonAccent="danger"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'a7b8c9d0-e1f2-3456-abcd-567890123456',
|
||||
name: 'delete-draft',
|
||||
description: 'Deletes a draft with confirmation',
|
||||
component: DeleteDraft,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'b8c9d0e1-f2a3-4567-bcde-678901234567',
|
||||
label: 'Delete draft',
|
||||
icon: 'IconTrash',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### Доступ к контексту времени выполнения
|
||||
|
||||
Внутри вашего компонента используйте хуки SDK для доступа к текущему пользователю, записи и экземпляру компонента:
|
||||
@@ -858,6 +952,50 @@ export default defineFrontComponent({
|
||||
| `unmountFrontComponent()` | Размонтировать компонент |
|
||||
| `updateProgress(progress)` | Обновить индикатор прогресса |
|
||||
|
||||
Пример, который использует API хоста для показа snackbar и закрытия боковой панели после завершения действия:
|
||||
|
||||
```tsx src/front-components/archive-record.tsx
|
||||
import { defineFrontComponent, useRecordId } from 'twenty-sdk';
|
||||
import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const ArchiveRecord = () => {
|
||||
const recordId = useRecordId();
|
||||
|
||||
const handleArchive = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
updateTask: {
|
||||
__args: { id: recordId, data: { status: 'ARCHIVED' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
await enqueueSnackbar({
|
||||
message: 'Record archived',
|
||||
variant: 'success',
|
||||
});
|
||||
|
||||
await closeSidePanel();
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px' }}>
|
||||
<p>Archive this record?</p>
|
||||
<button onClick={handleArchive}>Archive</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'c9d0e1f2-a3b4-5678-cdef-789012345678',
|
||||
name: 'archive-record',
|
||||
description: 'Archives the current record',
|
||||
component: ArchiveRecord,
|
||||
});
|
||||
```
|
||||
|
||||
#### Параметры команды
|
||||
|
||||
Добавление поля `command` в `defineFrontComponent` регистрирует компонент в меню команд (Cmd+K). Если `isPinned` имеет значение `true`, команда также отображается как кнопка быстрого действия в правом верхнем углу страницы.
|
||||
@@ -1712,3 +1850,86 @@ yarn twenty uninstall
|
||||
# Skip the confirmation prompt
|
||||
yarn twenty uninstall --yes
|
||||
```
|
||||
|
||||
## Управление удалёнными серверами
|
||||
|
||||
**Remote** — это сервер Twenty, к которому подключается ваше приложение. Во время настройки скэффолдер автоматически создаст его для вас. Вы можете в любой момент добавлять новые удалённые серверы или переключаться между ними.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Ваши учётные данные хранятся в `~/.twenty/config.json`.
|
||||
|
||||
## CI с GitHub Actions
|
||||
|
||||
Скэффолдер генерирует готовый к использованию workflow GitHub Actions в `.github/workflows/ci.yml`. Он автоматически запускает ваши интеграционные тесты при каждом пуше в `main` и в pull request'ах.
|
||||
|
||||
Рабочий процесс:
|
||||
|
||||
1. Извлекает ваш код
|
||||
2. Поднимает временный сервер Twenty с помощью экшена `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. Устанавливает зависимости с помощью `yarn install --immutable`
|
||||
4. Запускает `yarn test` с `TWENTY_API_URL` и `TWENTY_API_KEY`, переданными из выходных данных экшена
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Вам не нужно настраивать секреты — экшен `spawn-twenty-docker-image` запускает эфемерный сервер Twenty прямо в раннере и выводит данные для подключения. Секрет `GITHUB_TOKEN` предоставляется GitHub автоматически.
|
||||
|
||||
Чтобы закрепить конкретную версию Twenty вместо `latest`, измените переменную окружения `TWENTY_VERSION` в начале workflow.
|
||||
|
||||
@@ -7,7 +7,9 @@ description: Создайте своё первое приложение Twenty
|
||||
Приложения сейчас проходят альфа-тестирование. Функция работает, но продолжает развиваться.
|
||||
</Warning>
|
||||
|
||||
Приложения позволяют расширять Twenty с помощью пользовательских объектов, полей, логических функций, навыков ИИ и UI-компонентов — всё это управляется как код.
|
||||
## Что такое приложения?
|
||||
|
||||
Приложения позволяют расширять Twenty с помощью пользовательских объектов, полей, логических функций, фронтенд-компонентов, навыков ИИ и многого другого — всё это управляется как код. Вместо настройки всего через интерфейс вы определяете модель данных и логику на TypeScript и развёртываете их в одном или нескольких рабочих пространствах.
|
||||
|
||||
## Требования
|
||||
|
||||
@@ -17,7 +19,9 @@ description: Создайте своё первое приложение Twenty
|
||||
* **Yarn 4** — Поставляется вместе с Node.js через Corepack. Включите его, выполнив `corepack enable`
|
||||
* **Docker** — [Скачать здесь](https://www.docker.com/products/docker-desktop/). Требуется для запуска локального экземпляра Twenty. Не требуется, если у вас уже запущен сервер Twenty.
|
||||
|
||||
## Шаг 1: Сгенерируйте каркас приложения
|
||||
## Создайте своё первое приложение
|
||||
|
||||
### Сгенерируйте каркас приложения
|
||||
|
||||
Откройте терминал и выполните:
|
||||
|
||||
@@ -29,18 +33,7 @@ npx create-twenty-app@latest my-twenty-app
|
||||
|
||||
Будет создана новая папка `my-twenty-app` со всем необходимым.
|
||||
|
||||
<Note>
|
||||
Генератор поддерживает следующие флаги:
|
||||
|
||||
* `--minimal` — сгенерировать только основные файлы, без примеров (по умолчанию)
|
||||
* `--exhaustive` — сгенерировать все примеры сущностей
|
||||
* `--name <name>` — задать имя приложения (пропускает запрос)
|
||||
* `--display-name <displayName>` — задать отображаемое имя (пропускает запрос)
|
||||
* `--description <description>` — задать описание (пропускает запрос)
|
||||
* `--skip-local-instance` — пропустить запрос на настройку локального сервера
|
||||
</Note>
|
||||
|
||||
## Шаг 2: Настройте локальный экземпляр Twenty
|
||||
### Настройте локальный экземпляр Twenty
|
||||
|
||||
Скэффолдер спросит:
|
||||
|
||||
@@ -53,7 +46,7 @@ npx create-twenty-app@latest my-twenty-app
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Запустить локальный экземпляр?" />
|
||||
</div>
|
||||
|
||||
## Шаг 3: Войдите в своё рабочее пространство
|
||||
### Войдите в своё рабочее пространство
|
||||
|
||||
Затем откроется окно браузера со страницей входа в Twenty. Войдите, используя предварительно созданную демонстрационную учётную запись:
|
||||
|
||||
@@ -64,7 +57,7 @@ npx create-twenty-app@latest my-twenty-app
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Экран входа в Twenty" />
|
||||
</div>
|
||||
|
||||
## Шаг 4: Авторизуйте приложение
|
||||
### Авторизуйте приложение
|
||||
|
||||
После входа вы увидите экран авторизации. Это позволит вашему приложению взаимодействовать с вашим рабочим пространством.
|
||||
|
||||
@@ -80,7 +73,7 @@ npx create-twenty-app@latest my-twenty-app
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="Каркас приложения успешно создан" />
|
||||
</div>
|
||||
|
||||
## Шаг 5: Начните разработку
|
||||
### Начните разработку
|
||||
|
||||
Перейдите в папку вашего нового приложения и запустите сервер разработки:
|
||||
|
||||
@@ -105,7 +98,7 @@ yarn twenty dev --verbose
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Вывод терминала в режиме разработки" />
|
||||
</div>
|
||||
|
||||
## Шаг 6: Посмотрите своё приложение в Twenty
|
||||
### Посмотрите своё приложение в Twenty
|
||||
|
||||
Откройте [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) в браузере. Перейдите в **Settings > Apps** и выберите вкладку **Developer**. Вы должны увидеть своё приложение в разделе **Your Apps**:
|
||||
|
||||
@@ -133,13 +126,28 @@ yarn twenty dev --verbose
|
||||
|
||||
Готово! Отредактируйте любой файл в `src/`, и изменения будут подхвачены автоматически.
|
||||
|
||||
Перейдите к разделу [Создание приложений](/l/ru/developers/extend/apps/building) за подробным руководством по созданию объектов, логических функций, фронтенд-компонентов, навыков и многого другого.
|
||||
---
|
||||
|
||||
## Что вы можете создать
|
||||
|
||||
Приложения состоят из **сущностей** — каждая определена как файл TypeScript с одним `export default`:
|
||||
|
||||
| Сущность | Что делает |
|
||||
| ----------------------------- | --------------------------------------------------------------------------------------------------------- |
|
||||
| **Объекты и поля** | Определяйте пользовательские модели данных (например, Post Card, Invoice) с типизированными полями |
|
||||
| **Логические функции** | Серверные функции на TypeScript, запускаемые HTTP-маршрутами, расписаниями cron или событиями базы данных |
|
||||
| **Фронтенд-компоненты** | React-компоненты, которые отображаются внутри интерфейса Twenty (боковая панель, виджеты, командное меню) |
|
||||
| **Навыки и агенты** | Возможности ИИ — многократно используемые инструкции и автономные помощники |
|
||||
| **Представления и навигация** | Предварительно настроенные представления списков и элементы бокового меню для ваших объектов |
|
||||
| **Макеты страниц** | Пользовательские страницы сведений о записи с вкладками и виджетами |
|
||||
|
||||
Перейдите к разделу [Создание приложений](/l/ru/developers/extend/apps/building), чтобы получить подробное руководство по каждому типу сущности.
|
||||
|
||||
---
|
||||
|
||||
## Структура проекта
|
||||
|
||||
Скэффолдер генерирует следующую структуру файлов (показано в режиме `--exhaustive`, который включает примеры для каждого типа сущностей):
|
||||
Инструмент генерации каркаса создаёт следующую структуру файлов:
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -148,160 +156,50 @@ my-twenty-app/
|
||||
.gitignore
|
||||
.nvmrc
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── 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
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── default-role.ts # Default role for logic functions
|
||||
├── constants/
|
||||
│ └── universal-identifiers.ts # Auto-generated UUIDs and app metadata
|
||||
└── __tests__/
|
||||
├── setup-test.ts # Test setup (server health check, config)
|
||||
└── app-install.integration-test.ts # Integration test
|
||||
```
|
||||
|
||||
По умолчанию (`--minimal`) создаются только основные файлы: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` и `logic-functions/post-install.ts`. Используйте `--exhaustive`, чтобы включить все показанные выше файлы-примеры.
|
||||
### Начните с примера
|
||||
|
||||
Чтобы начать с более полного примера с пользовательскими объектами, полями, логическими функциями, фронтенд-компонентами и многим другим, используйте флаг `--example`:
|
||||
|
||||
```bash filename="Terminal"
|
||||
npx create-twenty-app@latest my-twenty-app --example postcard
|
||||
```
|
||||
|
||||
Примеры берутся из каталога [twenty-apps/examples](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples) на GitHub. Вы также можете сгенерировать каркас отдельных сущностей в существующем проекте с помощью `yarn twenty add` (см. [Создание приложений](/l/ru/developers/extend/apps/building#scaffolding-entities-with-yarn-twenty-add)).
|
||||
|
||||
### Ключевые файлы
|
||||
|
||||
| Файл / Папка | Назначение |
|
||||
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `package.json` | Содержит имя, версию и зависимости вашего приложения. Содержит скрипт `twenty`, чтобы вы могли выполнить `yarn twenty help` и увидеть все команды. |
|
||||
| `src/application-config.ts` | **Обязательно.** Основной файл конфигурации для вашего приложения. |
|
||||
| `src/roles/` | Определяет роли, которые контролируют доступ логических функций. |
|
||||
| `src/logic-functions/` | Серверные функции, запускаемые маршрутами, расписаниями cron или событиями базы данных. |
|
||||
| `src/front-components/` | Компоненты React, которые отображаются внутри интерфейса Twenty. |
|
||||
| `src/objects/` | Пользовательские определения объектов для расширения вашей модели данных. |
|
||||
| `src/fields/` | Пользовательские поля, добавляемые к существующим объектам. |
|
||||
| `src/views/` | Конфигурации сохранённых представлений. |
|
||||
| `src/navigation-menu-items/` | Пользовательские ссылки в боковой навигации. |
|
||||
| `src/skills/` | Навыки, расширяющие возможности ИИ-агентов Twenty. |
|
||||
| `src/agents/` | ИИ-агенты с пользовательскими промптами. |
|
||||
| `src/page-layouts/` | Пользовательские макеты страниц для представлений записей. |
|
||||
| `src/__tests__/` | Интеграционные тесты (настройка + пример теста). |
|
||||
| `public/` | Статические ресурсы (изображения, шрифты), обслуживаемые вместе с вашим приложением. |
|
||||
| Файл / Папка | Назначение |
|
||||
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `package.json` | Содержит имя, версию и зависимости вашего приложения. Содержит скрипт `twenty`, чтобы вы могли выполнить `yarn twenty help` и увидеть все команды. |
|
||||
| `src/application-config.ts` | **Обязательно.** Основной файл конфигурации для вашего приложения. |
|
||||
| `src/default-role.ts` | Роль по умолчанию, которая контролирует, к чему имеют доступ ваши логические функции. |
|
||||
| `src/constants/universal-identifiers.ts` | Автоматически генерируемые UUID и метаданные приложения (отображаемое имя, описание). |
|
||||
| `src/__tests__/` | Интеграционные тесты (настройка + пример теста). |
|
||||
| `public/` | Статические ресурсы (изображения, шрифты), обслуживаемые вместе с вашим приложением. |
|
||||
|
||||
## Управление удалёнными серверами
|
||||
## Локальный сервер разработки
|
||||
|
||||
Remote — это сервер Twenty, к которому подключается ваше приложение. Во время настройки скэффолдер автоматически создаст его для вас. Вы можете в любой момент добавлять новые remotes или переключаться между ними.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Ваши учётные данные хранятся в `~/.twenty/config.json`.
|
||||
|
||||
## Локальный сервер разработки (`yarn twenty server`)
|
||||
|
||||
CLI может управлять локальным сервером Twenty, запущенным в Docker. Это тот же сервер, который автоматически запускается при создании каркаса приложения с помощью `create-twenty-app`, но им можно управлять и вручную.
|
||||
|
||||
### Запуск сервера
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
Эта команда скачивает Docker-образ `twentycrm/twenty-app-dev:latest` (если его ещё нет), создаёт контейнер с именем `twenty-app-dev` и запускает его на порту **2020**. CLI ждёт, пока сервер пройдёт проверку работоспособности, прежде чем вернуть управление.
|
||||
|
||||
Создаются два тома Docker для сохранения данных между перезапусками:
|
||||
|
||||
* `twenty-app-dev-data` — база данных PostgreSQL
|
||||
* `twenty-app-dev-storage` — файловое хранилище
|
||||
|
||||
Если порт 2020 уже используется, вы можете запустить на другом порту:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
CLI автоматически настраивает внутренние `NODE_PORT` и `SERVER_URL` контейнера в соответствии с выбранным портом, чтобы логические функции, OAuth и прочие внутренние сетевые взаимодействия работали корректно.
|
||||
|
||||
После запуска сервер автоматически регистрируется как remote `local` в конфигурации вашего CLI.
|
||||
|
||||
### Проверка состояния сервера
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Показывает, запущен ли сервер, его URL и учётные данные по умолчанию (`[email protected]` / `[email protected]`).
|
||||
|
||||
### Просмотр журналов сервера
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Выводит журналы контейнера в потоковом режиме. Используйте `--lines`, чтобы задать, сколько последних строк показывать:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Остановка сервера
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Останавливает контейнер. Ваши данные сохраняются в томах Docker — следующий `start` продолжит с того места, где вы остановились.
|
||||
|
||||
### Сброс сервера
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Удаляет контейнер и оба тома Docker, полностью стирая все данные. Следующий `start` создаст новый чистый экземпляр.
|
||||
|
||||
<Note>
|
||||
Для работы сервера необходимо, чтобы **Docker** был запущен. Если вы видите ошибку "Docker not running", убедитесь, что запущен Docker Desktop (или демон Docker).
|
||||
</Note>
|
||||
|
||||
### Справочник команд
|
||||
Генератор каркаса уже запустил для вас локальный сервер Twenty. Чтобы управлять им позже, используйте `yarn twenty server`:
|
||||
|
||||
| Команда | Описание |
|
||||
| -------------------------------------- | -------------------------------------------------------------- |
|
||||
@@ -313,65 +211,11 @@ yarn twenty server reset
|
||||
| `yarn twenty server logs --lines 100` | Показать последние 100 строк журнала |
|
||||
| `yarn twenty server reset` | Удалить все данные и начать с чистого листа |
|
||||
|
||||
## CI с GitHub Actions
|
||||
Данные сохраняются между перезапусками в двух томах Docker (`twenty-app-dev-data` для PostgreSQL, `twenty-app-dev-storage` для файлов). Используйте `reset`, чтобы стереть всё и начать заново.
|
||||
|
||||
Скэффолдер генерирует готовый к использованию workflow GitHub Actions в `.github/workflows/ci.yml`. Он автоматически запускает ваши интеграционные тесты при каждом пуше в `main` и в pull request'ах.
|
||||
|
||||
Рабочий процесс:
|
||||
|
||||
1. Извлекает ваш код
|
||||
2. Поднимает временный сервер Twenty с помощью экшена `twentyhq/twenty/.github/actions/spawn-twenty-docker-image`
|
||||
3. Устанавливает зависимости с помощью `yarn install --immutable`
|
||||
4. Запускает `yarn test` с `TWENTY_API_URL` и `TWENTY_API_KEY`, переданными из выходных данных экшена
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Вам не нужно настраивать секреты — экшен `spawn-twenty-docker-image` запускает эфемерный сервер Twenty прямо в раннере и выводит данные для подключения. Секрет `GITHUB_TOKEN` предоставляется GitHub автоматически.
|
||||
|
||||
Чтобы закрепить конкретную версию Twenty вместо `latest`, измените переменную окружения `TWENTY_VERSION` в начале workflow.
|
||||
<Note>
|
||||
Для работы сервера необходимо, чтобы **Docker** был запущен. Если вы видите ошибку "Docker not running", убедитесь, что запущен Docker Desktop (или демон Docker).
|
||||
</Note>
|
||||
|
||||
## Ручная настройка (без генератора)
|
||||
|
||||
|
||||
@@ -52,7 +52,11 @@ yarn twenty deploy
|
||||
|
||||
### Общий доступ к развернутому приложению
|
||||
|
||||
Приложения в формате tarball не отображаются в публичном маркетплейсе, поэтому другие рабочие пространства на том же сервере не найдут их при просмотре. Чтобы поделиться развернутым приложением:
|
||||
<Warning>
|
||||
Sharing private (tarball) apps across workspaces is an **Enterprise** feature. The **Distribution** tab will show an upgrade prompt instead of the share controls until your workspace has a valid Enterprise key. See [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to activate it.
|
||||
</Warning>
|
||||
|
||||
Приложения в формате tarball не отображаются в публичном маркетплейсе, поэтому другие рабочие пространства на том же сервере не найдут их при просмотре. Once your workspace is on the Enterprise plan, you can share a deployed app like this:
|
||||
|
||||
1. Перейдите в **Настройки > Приложения > Регистрации** и откройте ваше приложение
|
||||
2. На вкладке **Распространение** нажмите **Копировать ссылку для общего доступа**
|
||||
@@ -60,10 +64,6 @@ yarn twenty deploy
|
||||
|
||||
Ссылка общего доступа использует базовый URL сервера (без какого-либо поддомена рабочего пространства), поэтому она работает для любого рабочего пространства на сервере.
|
||||
|
||||
<Warning>
|
||||
Возможность делиться частными приложениями — функция Enterprise. Перейдите в [Настройки > Панель администратора > Enterprise](/settings/admin-panel#enterprise), чтобы включить её.
|
||||
</Warning>
|
||||
|
||||
### Управление версиями
|
||||
|
||||
Чтобы выпустить обновление:
|
||||
|
||||
@@ -81,7 +81,7 @@ import { defineApplication } from 'twenty-sdk';
|
||||
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role';
|
||||
|
||||
export default defineApplication({
|
||||
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
|
||||
universalIdentifier: '39783023-bcac-41e3-b0d2-ff1944d8465d',
|
||||
displayName: 'My Twenty App',
|
||||
description: 'My first Twenty app',
|
||||
icon: 'IconWorld',
|
||||
@@ -717,6 +717,13 @@ yarn twenty exec --postInstall
|
||||
|
||||
Ön uç bileşenler, Twenty'nin UI'si içinde doğrudan görüntülenen React bileşenleridir. Remote DOM kullanan izole bir Web Worker içinde çalışırlar — kodunuz izole bir ortamda (sandbox) çalışır ancak bir iframe içinde değil, sayfada yerel olarak işlenir.
|
||||
|
||||
#### Ön bileşenlerin kullanılabileceği yerler
|
||||
|
||||
Ön bileşenler, Twenty içinde iki konumda işlenebilir:
|
||||
|
||||
* **Yan panel** — Headless olmayan ön bileşenler, sağ taraftaki yan panelde açılır. Bir ön bileşen komut menüsünden tetiklendiğinde varsayılan davranış budur.
|
||||
* **Widget'lar (panolar ve kayıt sayfaları)** — Ön bileşenler, sayfa düzenlerine widget olarak gömülebilir. Bir pano veya kayıt sayfası düzeni yapılandırılırken kullanıcılar bir ön bileşen widget'ı ekleyebilir.
|
||||
|
||||
#### Basit örnek
|
||||
|
||||
Bir ön uç bileşenini çalışırken görmenin en hızlı yolu, onu bir komut olarak kaydetmektir. `isPinned: true` ile bir `command` alanı eklemek, sayfanın sağ üst köşesinde hızlı işlem düğmesi olarak görünmesini sağlar — herhangi bir sayfa düzenine gerek yoktur:
|
||||
@@ -774,9 +781,13 @@ Bileşeni satır içi işlemek için üzerine tıklayın.
|
||||
|
||||
Komutların ötesinde, bir ön uç bileşenini bir **sayfa düzeninde** widget olarak ekleyerek doğrudan bir kayıt sayfasına gömebilirsiniz. Ayrıntılar için [definePageLayout](#definepagelayout) bölümüne bakın.
|
||||
|
||||
#### Headless bileşenler (`isHeadless: true`)
|
||||
#### Headless ve headless olmayan
|
||||
|
||||
Headless bileşenler görünür bir kullanıcı arayüzü oluşturmaz ancak yine de React mantığını çalıştırır. Bu, **etki bileşenleri** için kullanışlıdır — bağlandıklarında veri senkronizasyonu yapmak, bir zamanlayıcı başlatmak, olayları dinlemek veya bir bildirimi tetiklemek gibi yan etkiler gerçekleştiren bileşenler.
|
||||
Ön bileşenler, `isHeadless` seçeneğiyle kontrol edilen iki işleme kipiyle gelir:
|
||||
|
||||
**Headless olmayan (varsayılan)** — Bileşen görünür bir kullanıcı arayüzü (UI) oluşturur. Komut menüsünden tetiklendiğinde yan panelde açılır. `isHeadless` `false` olduğunda veya belirtilmediğinde bu varsayılan davranıştır.
|
||||
|
||||
**Headless (`isHeadless: true`)** — Bileşen arka planda görünmez şekilde bağlanır. Yan paneli açmaz. Headless bileşenler, mantığı çalıştırıp ardından kendilerini kaldıran eylemler için tasarlanmıştır — örneğin, bir async görevi çalıştırma, bir sayfaya gitme veya bir onay modalı gösterme. Aşağıda açıklanan SDK Command bileşenleriyle doğal olarak eşleşirler.
|
||||
|
||||
```tsx src/front-components/sync-tracker.tsx
|
||||
import { defineFrontComponent, useRecordId, enqueueSnackbar } from 'twenty-sdk';
|
||||
@@ -803,6 +814,89 @@ export default defineFrontComponent({
|
||||
|
||||
Bileşen `null` döndürdüğü için, Twenty bunun için bir kapsayıcı oluşturmayı atlar — düzende boş alan görünmez. Bileşen yine de tüm hook'lara ve host iletişim API'sine erişime sahiptir.
|
||||
|
||||
#### SDK Command bileşenleri
|
||||
|
||||
`twenty-sdk` paketi, headless ön bileşenler için tasarlanmış dört Command yardımcı bileşeni sağlar. Her bileşen bağlandığında bir eylem yürütür, hataları bir snackbar bildirimi göstererek ele alır ve tamamlandığında ön bileşeni otomatik olarak kaldırır.
|
||||
|
||||
Bunları `twenty-sdk/command` içinden içe aktarın:
|
||||
|
||||
* **`Command`** — `execute` prop'u aracılığıyla async bir geri çağrıyı çalıştırır.
|
||||
* **`CommandLink`** — Bir uygulama yoluna gider. Props: `to`, `params`, `queryParams`, `options`.
|
||||
* **`CommandModal`** — Bir onay modalı açar. Kullanıcı onaylarsa `execute` geri çağrısını yürütür. Props: `title`, `subtitle`, `execute`, `confirmButtonText`, `confirmButtonAccent`.
|
||||
* **`CommandOpenSidePanelPage`** — Belirli bir yan panel sayfasını açar. Props: `page`, `pageTitle`, `pageIcon`.
|
||||
|
||||
`Command` kullanarak komut menüsünden bir eylem çalıştıran headless bir ön bileşenin tam örneği:
|
||||
|
||||
```tsx src/front-components/run-action.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { Command } from 'twenty-sdk/command';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const RunAction = () => {
|
||||
const execute = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
createTask: {
|
||||
__args: { data: { title: 'Created by my app' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return <Command execute={execute} />;
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'e5f6a7b8-c9d0-1234-efab-345678901234',
|
||||
name: 'run-action',
|
||||
description: 'Creates a task from the command menu',
|
||||
component: RunAction,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'f6a7b8c9-d0e1-2345-fabc-456789012345',
|
||||
label: 'Run my action',
|
||||
icon: 'IconPlayerPlay',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Ve yürütmeden önce onay istemek için `CommandModal` kullanan bir örnek:
|
||||
|
||||
```tsx src/front-components/delete-draft.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk';
|
||||
import { CommandModal } from 'twenty-sdk/command';
|
||||
|
||||
const DeleteDraft = () => {
|
||||
const execute = async () => {
|
||||
// perform the deletion
|
||||
};
|
||||
|
||||
return (
|
||||
<CommandModal
|
||||
title="Delete draft?"
|
||||
subtitle="This action cannot be undone."
|
||||
execute={execute}
|
||||
confirmButtonText="Delete"
|
||||
confirmButtonAccent="danger"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'a7b8c9d0-e1f2-3456-abcd-567890123456',
|
||||
name: 'delete-draft',
|
||||
description: 'Deletes a draft with confirmation',
|
||||
component: DeleteDraft,
|
||||
isHeadless: true,
|
||||
command: {
|
||||
universalIdentifier: 'b8c9d0e1-f2a3-4567-bcde-678901234567',
|
||||
label: 'Delete draft',
|
||||
icon: 'IconTrash',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### Çalışma zamanı bağlamına erişme
|
||||
|
||||
Bileşeninizin içinde, geçerli kullanıcıya, kayda ve bileşen örneğine erişmek için SDK hook'larını kullanın:
|
||||
@@ -859,6 +953,50 @@ Kullanılabilir hook'lar:
|
||||
| `unmountFrontComponent()` | Bileşeni kaldır (unmount) |
|
||||
| `updateProgress(progress)` | Bir ilerleme göstergesini güncelle |
|
||||
|
||||
Bir eylem tamamlandıktan sonra bir snackbar göstermek ve yan paneli kapatmak için host API'sini kullanan bir örnek:
|
||||
|
||||
```tsx src/front-components/archive-record.tsx
|
||||
import { defineFrontComponent, useRecordId } from 'twenty-sdk';
|
||||
import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const ArchiveRecord = () => {
|
||||
const recordId = useRecordId();
|
||||
|
||||
const handleArchive = async () => {
|
||||
const client = new CoreApiClient();
|
||||
|
||||
await client.mutation({
|
||||
updateTask: {
|
||||
__args: { id: recordId, data: { status: 'ARCHIVED' } },
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
await enqueueSnackbar({
|
||||
message: 'Record archived',
|
||||
variant: 'success',
|
||||
});
|
||||
|
||||
await closeSidePanel();
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px' }}>
|
||||
<p>Archive this record?</p>
|
||||
<button onClick={handleArchive}>Archive</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default defineFrontComponent({
|
||||
universalIdentifier: 'c9d0e1f2-a3b4-5678-cdef-789012345678',
|
||||
name: 'archive-record',
|
||||
description: 'Archives the current record',
|
||||
component: ArchiveRecord,
|
||||
});
|
||||
```
|
||||
|
||||
#### Komut seçenekleri
|
||||
|
||||
`defineFrontComponent` içine bir `command` alanı eklemek, bileşeni komut menüsüne (Cmd+K) kaydeder. `isPinned` `true` ise, sayfanın sağ üst köşesinde bir hızlı işlem düğmesi olarak da görünür.
|
||||
@@ -1713,3 +1851,86 @@ yarn twenty uninstall
|
||||
# Skip the confirmation prompt
|
||||
yarn twenty uninstall --yes
|
||||
```
|
||||
|
||||
## Uzakları yönetme
|
||||
|
||||
Bir **uzak**, uygulamanızın bağlandığı Twenty sunucusudur. Kurulum sırasında iskelet oluşturucu sizin için otomatik olarak bir tane oluşturur. Dilediğiniz zaman daha fazla uzak ekleyebilir veya aralarında geçiş yapabilirsiniz.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Kimlik bilgileriniz `~/.twenty/config.json` içinde saklanır.
|
||||
|
||||
## GitHub Actions ile CI
|
||||
|
||||
İskelet oluşturucu, `.github/workflows/ci.yml` konumunda kullanıma hazır bir GitHub Actions iş akışı üretir. Entegrasyon testlerinizi `main` dalına yapılan her itmede ve çekme isteklerinde otomatik olarak çalıştırır.
|
||||
|
||||
İş akışı:
|
||||
|
||||
1. Kodunuzu çalışma alanına alır
|
||||
2. `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` eylemini kullanarak geçici bir Twenty sunucusu başlatır
|
||||
3. `yarn install --immutable` ile bağımlılıkları kurar
|
||||
4. Eylem çıktılarından enjekte edilen `TWENTY_API_URL` ve `TWENTY_API_KEY` ile `yarn test` çalıştırır
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Herhangi bir gizli değişken yapılandırmanız gerekmez — `spawn-twenty-docker-image` eylemi, koşucu içinde doğrudan geçici bir Twenty sunucusu başlatır ve bağlantı ayrıntılarını çıktı olarak verir. `GITHUB_TOKEN` gizli değişkeni GitHub tarafından otomatik olarak sağlanır.
|
||||
|
||||
`latest` yerine belirli bir Twenty sürümünü sabitlemek için iş akışının başındaki `TWENTY_VERSION` ortam değişkenini değiştirin.
|
||||
|
||||
@@ -7,7 +7,9 @@ description: İlk Twenty uygulamanızı dakikalar içinde oluşturun.
|
||||
Uygulamalar şu anda alfa aşamasında. Özellik işlevsel ancak hâlâ gelişmekte.
|
||||
</Warning>
|
||||
|
||||
Uygulamalar, Twenty'yi özel nesneler, alanlar, mantık işlevleri, Yapay Zeka yetenekleri ve UI bileşenleriyle genişletmenizi sağlar — tümü kod olarak yönetilir.
|
||||
## Uygulamalar nedir?
|
||||
|
||||
Uygulamalar, Twenty'yi özel nesneler, alanlar, mantıksal işlevler, ön uç bileşenleri, yapay zekâ yetenekleri ve daha fazlasıyla genişletmenizi sağlar — tümü kod olarak yönetilir. Her şeyi UI üzerinden yapılandırmak yerine, veri modelinizi ve mantığınızı TypeScript'te tanımlar ve bunu bir veya daha fazla çalışma alanına dağıtırsınız.
|
||||
|
||||
## Ön Gereksinimler
|
||||
|
||||
@@ -17,7 +19,9 @@ Başlamadan önce, makinenizde aşağıdakilerin kurulu olduğundan emin olun:
|
||||
* **Yarn 4** — Corepack aracılığıyla Node.js ile birlikte gelir. `corepack enable` komutunu çalıştırarak etkinleştirin
|
||||
* **Docker** — [Buradan indirin](https://www.docker.com/products/docker-desktop/). Yerel bir Twenty örneğini çalıştırmak için gereklidir. Zaten çalışan bir Twenty sunucunuz varsa gerekmez.
|
||||
|
||||
## Adım 1: Uygulamanızın iskeletini oluşturun
|
||||
## İlk uygulamanızı oluşturun
|
||||
|
||||
### Uygulamanızın iskeletini oluşturun
|
||||
|
||||
Bir terminal açın ve şunu çalıştırın:
|
||||
|
||||
@@ -29,18 +33,7 @@ Uygulamanız için bir ad ve açıklama girmeniz istenecektir. Varsayılanları
|
||||
|
||||
Bu, `my-twenty-app` adlı, ihtiyacınız olan her şeyi içeren yeni bir klasör oluşturur.
|
||||
|
||||
<Note>
|
||||
İskelet oluşturucu şu bayrakları destekler:
|
||||
|
||||
* `--minimal` — yalnızca temel dosyaların iskeletini oluşturur, örnek yok (varsayılan)
|
||||
* `--exhaustive` — tüm örnek varlıkların iskeletini oluşturur
|
||||
* `--name <name>` — uygulama adını ayarlar (istemi atlar)
|
||||
* `--display-name <displayName>` — görünen adı ayarlar (istemi atlar)
|
||||
* `--description <description>` — açıklamayı ayarlar (istemi atlar)
|
||||
* `--skip-local-instance` — yerel sunucu kurulum istemini atlar
|
||||
</Note>
|
||||
|
||||
## Adım 2: Yerel bir Twenty örneği kurun
|
||||
### Yerel bir Twenty örneği kurun
|
||||
|
||||
İskelet oluşturucu şunu soracaktır:
|
||||
|
||||
@@ -53,7 +46,7 @@ Bu, `my-twenty-app` adlı, ihtiyacınız olan her şeyi içeren yeni bir klasör
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Yerel örnek başlatılsın mı?" />
|
||||
</div>
|
||||
|
||||
## Adım 3: Çalışma alanınıza giriş yapın
|
||||
### Çalışma alanınıza giriş yapın
|
||||
|
||||
Ardından, Twenty oturum açma sayfasıyla bir tarayıcı penceresi açılacaktır. Önceden eklenmiş demo hesabıyla oturum açın:
|
||||
|
||||
@@ -64,7 +57,7 @@ Ardından, Twenty oturum açma sayfasıyla bir tarayıcı penceresi açılacakt
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty oturum açma ekranı" />
|
||||
</div>
|
||||
|
||||
## Adım 4: Uygulamayı yetkilendirin
|
||||
### Uygulamayı yetkilendirin
|
||||
|
||||
Oturum açtıktan sonra bir yetkilendirme ekranı göreceksiniz. Bu, uygulamanızın çalışma alanınızla etkileşim kurmasını sağlar.
|
||||
|
||||
@@ -80,7 +73,7 @@ Yetkilendirildikten sonra terminaliniz her şeyin kurulduğunu onaylayacaktır.
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="Uygulama iskeleti başarıyla oluşturuldu" />
|
||||
</div>
|
||||
|
||||
## Adım 5: Geliştirmeye başlayın
|
||||
### Geliştirmeye başlayın
|
||||
|
||||
Yeni uygulama klasörünüze gidin ve geliştirme sunucusunu başlatın:
|
||||
|
||||
@@ -105,7 +98,7 @@ Geliştirme modu yalnızca geliştirme ortamında (`NODE_ENV=development`) çal
|
||||
<img src="/images/docs/developers/extends/apps/dev.jpg" alt="Geliştirme modu terminal çıktısı" />
|
||||
</div>
|
||||
|
||||
## Adım 6: Uygulamanızı Twenty'de görün
|
||||
### Uygulamanızı Twenty'de görün
|
||||
|
||||
Tarayıcınızda [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) adresini açın. **Settings > Apps** bölümüne gidin ve **Developer** sekmesini seçin. **Your Apps** altında uygulamanızın listelendiğini görmelisiniz:
|
||||
|
||||
@@ -133,13 +126,28 @@ Uygulamanızın sağladığı her şeyi — nesneler, alanlar, mantık işlevler
|
||||
|
||||
Her şey hazır! `src/` içindeki herhangi bir dosyayı düzenleyin; değişiklikler otomatik olarak alınacaktır.
|
||||
|
||||
Nesneler, mantık işlevleri, ön bileşenler, beceriler ve daha fazlasını oluşturma hakkında ayrıntılı bir kılavuz için [Uygulama Oluşturma](/l/tr/developers/extend/apps/building) bölümüne göz atın.
|
||||
---
|
||||
|
||||
## Oluşturabilecekleriniz
|
||||
|
||||
Uygulamalar **varlıklardan** oluşur — her biri tek bir `export default` içeren bir TypeScript dosyası olarak tanımlanır:
|
||||
|
||||
| Varlık | Ne yapar |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Nesneler ve Alanlar** | Tipli alanlarla özel veri modelleri (ör. Post Card, Invoice) tanımlayın |
|
||||
| **Mantıksal işlevler** | HTTP rotaları, cron zamanlamaları veya veritabanı olayları tarafından tetiklenen sunucu tarafı TypeScript işlevleri |
|
||||
| **Ön uç bileşenleri** | Twenty'nin arayüzünde görüntülenen React bileşenleri (yan panel, widget'lar, komut menüsü) |
|
||||
| **Beceriler ve Aracılar** | Yapay zeka yetenekleri — yeniden kullanılabilir yönergeler ve otonom asistanlar |
|
||||
| **Görünümler ve Gezinme** | Nesneleriniz için önceden yapılandırılmış liste görünümleri ve kenar çubuğu menü öğeleri |
|
||||
| **Sayfa düzenleri** | Sekmeler ve widget'lar içeren özel kayıt ayrıntı sayfaları |
|
||||
|
||||
Her varlık türü hakkında ayrıntılı bir kılavuz için [Uygulama Oluşturma](/l/tr/developers/extend/apps/building) bölümüne göz atın.
|
||||
|
||||
---
|
||||
|
||||
## Proje yapısı
|
||||
|
||||
İskelet oluşturucu aşağıdaki dosya yapısını üretir (`--exhaustive` modunda gösterilmiştir; her varlık türü için örnekler içerir):
|
||||
İskelet oluşturucu aşağıdaki dosya yapısını oluşturur:
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -148,160 +156,50 @@ my-twenty-app/
|
||||
.gitignore
|
||||
.nvmrc
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
tsconfig.spec.json # TypeScript config for tests
|
||||
vitest.config.ts # Vitest test runner configuration
|
||||
LLMS.md
|
||||
README.md
|
||||
.github/
|
||||
└── workflows/
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
└── ci.yml # GitHub Actions CI workflow
|
||||
public/ # Public assets (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── __tests__/
|
||||
│ ├── setup-test.ts # Test setup (server health check, config)
|
||||
│ └── app-install.integration-test.ts # Example integration test
|
||||
├── 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
|
||||
│ ├── create-hello-world-company.ts # Example logic function using CoreApiClient
|
||||
│ ├── pre-install.ts # Runs before installation
|
||||
│ └── post-install.ts # Runs after installation
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── page-layouts/
|
||||
│ └── example-record-page-layout.ts # Example page layout with front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
├── application-config.ts # Required — main application configuration
|
||||
├── default-role.ts # Default role for logic functions
|
||||
├── constants/
|
||||
│ └── universal-identifiers.ts # Auto-generated UUIDs and app metadata
|
||||
└── __tests__/
|
||||
├── setup-test.ts # Test setup (server health check, config)
|
||||
└── app-install.integration-test.ts # Integration test
|
||||
```
|
||||
|
||||
Varsayılan olarak (`--minimal`), yalnızca çekirdek dosyalar oluşturulur: `application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` ve `logic-functions/post-install.ts`. Yukarıda gösterilen tüm örnek dosyaları dahil etmek için `--exhaustive` kullanın.
|
||||
### Bir örnekten başlayın
|
||||
|
||||
Özel nesneler, alanlar, mantık işlevleri, ön uç bileşenleri ve daha fazlasını içeren daha kapsamlı bir örnekten başlamak için `--example` bayrağını kullanın:
|
||||
|
||||
```bash filename="Terminal"
|
||||
npx create-twenty-app@latest my-twenty-app --example postcard
|
||||
```
|
||||
|
||||
Örnekler GitHub'daki [twenty-apps/examples](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples) dizininden alınır. Ayrıca `yarn twenty add` ile mevcut bir projeye tek tek varlıklar için iskelet oluşturabilirsiniz (bkz. [Uygulama Oluşturma](/l/tr/developers/extend/apps/building#scaffolding-entities-with-yarn-twenty-add)).
|
||||
|
||||
### Temel dosyalar
|
||||
|
||||
| Dosya / Klasör | Amaç |
|
||||
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `package.json` | Uygulamanızın adını, sürümünü ve bağımlılıklarını bildirir. Tüm komutları görmek için `yarn twenty help` çalıştırabilmeniz amacıyla bir `twenty` betiği içerir. |
|
||||
| `src/application-config.ts` | **Gerekli.** Uygulamanızın ana yapılandırma dosyası. |
|
||||
| `src/roles/` | Mantık işlevlerinizin neye erişebileceğini kontrol eden rolleri tanımlar. |
|
||||
| `src/logic-functions/` | Rotalar, cron zamanlamaları veya veritabanı olayları tarafından tetiklenen sunucu tarafı işlevler. |
|
||||
| `src/front-components/` | Twenty'nin UI'si içinde görüntülenen React bileşenleri. |
|
||||
| `src/objects/` | Veri modelinizi genişletmek için özel nesne tanımları. |
|
||||
| `src/fields/` | Mevcut nesnelere eklenen özel alanlar. |
|
||||
| `src/views/` | Kaydedilmiş görünüm yapılandırmaları. |
|
||||
| `src/navigation-menu-items/` | Kenar çubuğu gezintisinde özel bağlantılar. |
|
||||
| `src/skills/` | Twenty'nin yapay zeka ajanlarının yeteneklerini genişleten beceriler. |
|
||||
| `src/agents/` | Özel istemlere sahip yapay zekâ ajanları. |
|
||||
| `src/page-layouts/` | Kayıt görünümleri için özel sayfa düzenleri. |
|
||||
| `src/__tests__/` | Entegrasyon testleri (kurulum + örnek test). |
|
||||
| `public/` | Uygulamanızla birlikte sunulan statik varlıklar (görüntüler, yazı tipleri). |
|
||||
| Dosya / Klasör | Amaç |
|
||||
| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `package.json` | Uygulamanızın adını, sürümünü ve bağımlılıklarını bildirir. Tüm komutları görmek için `yarn twenty help` çalıştırabilmeniz amacıyla bir `twenty` betiği içerir. |
|
||||
| `src/application-config.ts` | **Gerekli.** Uygulamanızın ana yapılandırma dosyası. |
|
||||
| `src/default-role.ts` | Mantık işlevlerinizin neye erişebileceğini denetleyen varsayılan rol. |
|
||||
| `src/constants/universal-identifiers.ts` | Otomatik oluşturulan UUID'ler ve uygulama meta verileri (görünen ad, açıklama). |
|
||||
| `src/__tests__/` | Entegrasyon testleri (kurulum + örnek test). |
|
||||
| `public/` | Uygulamanızla birlikte sunulan statik varlıklar (görüntüler, yazı tipleri). |
|
||||
|
||||
## Uzakları yönetme
|
||||
## Yerel geliştirme sunucusu
|
||||
|
||||
Bir **uzak**, uygulamanızın bağlandığı Twenty sunucusudur. Kurulum sırasında iskelet oluşturucu sizin için otomatik olarak bir tane oluşturur. Dilediğiniz zaman daha fazla uzak ekleyebilir veya aralarında geçiş yapabilirsiniz.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
yarn twenty remote add
|
||||
|
||||
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
|
||||
yarn twenty remote add --local
|
||||
|
||||
# Add a remote non-interactively (useful for CI)
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
|
||||
|
||||
# List all configured remotes
|
||||
yarn twenty remote list
|
||||
|
||||
# Switch the active remote
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Kimlik bilgileriniz `~/.twenty/config.json` içinde saklanır.
|
||||
|
||||
## Yerel geliştirme sunucusu (`yarn twenty server`)
|
||||
|
||||
CLI, Docker'da çalışan yerel bir Twenty sunucusunu yönetebilir. Bu, `create-twenty-app` ile bir uygulamanın iskeletini oluşturduğunuzda otomatik olarak başlatılan sunucunun aynısıdır; ancak bunu el ile de yönetebilirsiniz.
|
||||
|
||||
### Sunucuyu Başlatma
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start
|
||||
```
|
||||
|
||||
Bu, `twentycrm/twenty-app-dev:latest` Docker imajını (zaten mevcut değilse) çeker, `twenty-app-dev` adlı bir konteyner oluşturur ve **2020** portunda başlatır. CLI, dönmeden önce sunucunun sağlık kontrolünü geçmesini bekler.
|
||||
|
||||
Yeniden başlatmalar arasında verileri kalıcı kılmak için iki Docker birimi oluşturulur:
|
||||
|
||||
* `twenty-app-dev-data` — PostgreSQL veritabanı
|
||||
* `twenty-app-dev-storage` — dosya depolama
|
||||
|
||||
2020 portu zaten kullanımda ise farklı bir portta başlatabilirsiniz:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server start --port 3030
|
||||
```
|
||||
|
||||
CLI, seçilen porta uyacak şekilde konteynerin dahili `NODE_PORT` ve `SERVER_URL` ayarlarını otomatik olarak yapılandırır; böylece mantık işlevleri, OAuth ve diğer tüm dahili ağ işlemleri doğru şekilde çalışır.
|
||||
|
||||
Başlatıldığında, sunucu CLI yapılandırmanızda `local` uzak olarak otomatik olarak kaydedilir.
|
||||
|
||||
### Sunucu durumunu kontrol etme
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server status
|
||||
```
|
||||
|
||||
Sunucunun çalışıp çalışmadığını, URL'sini ve varsayılan oturum açma kimlik bilgilerini (`[email protected]` / `[email protected]`) gösterir.
|
||||
|
||||
### Sunucu günlüklerini görüntüleme
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs
|
||||
```
|
||||
|
||||
Konteyner günlüklerini akış olarak iletir. Kaç satırın gösterileceğini denetlemek için `--lines` kullanın:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server logs --lines 100
|
||||
```
|
||||
|
||||
### Sunucuyu durdurma
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server stop
|
||||
```
|
||||
|
||||
Konteyneri durdurur. Verileriniz Docker birimlerinde korunur — bir sonraki `start`, kaldığınız yerden devam eder.
|
||||
|
||||
### Sunucuyu sıfırlama
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server reset
|
||||
```
|
||||
|
||||
Konteyneri kaldırır ve her iki Docker birimini de silerek tüm verileri temizler. Sonraki `start`, yeni bir örnek oluşturur.
|
||||
|
||||
<Note>
|
||||
Sunucunun çalışması için **Docker**'ın çalışıyor olması gerekir. "Docker not running" hatası görürseniz Docker Desktop'ın (veya Docker daemon'ının) başlatıldığından emin olun.
|
||||
</Note>
|
||||
|
||||
### Komut başvurusu
|
||||
İskelet oluşturucu sizin için zaten yerel bir Twenty sunucusu başlattı. Daha sonra yönetmek için `yarn twenty server` komutunu kullanın:
|
||||
|
||||
| Komut | Açıklama |
|
||||
| -------------------------------------- | ------------------------------------------------------ |
|
||||
@@ -313,65 +211,11 @@ Konteyneri kaldırır ve her iki Docker birimini de silerek tüm verileri temizl
|
||||
| `yarn twenty server logs --lines 100` | Son 100 günlük satırını gösterir |
|
||||
| `yarn twenty server reset` | Tüm verileri siler ve sıfırdan başlatır |
|
||||
|
||||
## GitHub Actions ile CI
|
||||
Veriler, yeniden başlatmalar arasında iki Docker biriminde kalıcıdır (PostgreSQL için `twenty-app-dev-data`, dosyalar için `twenty-app-dev-storage`). Her şeyi silip baştan başlamak için `reset` kullanın.
|
||||
|
||||
İskelet oluşturucu, `.github/workflows/ci.yml` konumunda kullanıma hazır bir GitHub Actions iş akışı üretir. Entegrasyon testlerinizi `main` dalına yapılan her itmede ve çekme isteklerinde otomatik olarak çalıştırır.
|
||||
|
||||
İş akışı:
|
||||
|
||||
1. Kodunuzu depodan çıkarır
|
||||
2. `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` eylemini kullanarak geçici bir Twenty sunucusu başlatır
|
||||
3. `yarn install --immutable` ile bağımlılıkları kurar
|
||||
4. Eylem çıktılarından enjekte edilen `TWENTY_API_URL` ve `TWENTY_API_KEY` ile `yarn test` çalıştırır
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
|
||||
env:
|
||||
TWENTY_VERSION: latest
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Spawn Twenty instance
|
||||
id: twenty
|
||||
uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main
|
||||
with:
|
||||
twenty-version: ${{ env.TWENTY_VERSION }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
|
||||
- name: Run integration tests
|
||||
run: yarn test
|
||||
env:
|
||||
TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }}
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
Herhangi bir gizli değişken yapılandırmanız gerekmez — `spawn-twenty-docker-image` eylemi, koşucu içinde doğrudan geçici bir Twenty sunucusu başlatır ve bağlantı ayrıntılarını çıktı olarak verir. `GITHUB_TOKEN` gizli değişkeni GitHub tarafından otomatik olarak sağlanır.
|
||||
|
||||
`latest` yerine belirli bir Twenty sürümünü sabitlemek için iş akışının başındaki `TWENTY_VERSION` ortam değişkenini değiştirin.
|
||||
<Note>
|
||||
Sunucunun çalışması için **Docker**'ın çalışıyor olması gerekir. "Docker not running" hatası görürseniz Docker Desktop'ın (veya Docker daemon'ının) başlatıldığından emin olun.
|
||||
</Note>
|
||||
|
||||
## Manuel kurulum (iskelet oluşturucu olmadan)
|
||||
|
||||
|
||||
@@ -52,7 +52,11 @@ yarn twenty deploy
|
||||
|
||||
### Dağıtılmış bir uygulamayı paylaşma
|
||||
|
||||
Tarball uygulamaları genel pazar yerinde listelenmez; bu nedenle aynı sunucudaki diğer çalışma alanları gezinerek onları keşfedemez. Dağıtılmış bir uygulamayı paylaşmak için:
|
||||
<Warning>
|
||||
Sharing private (tarball) apps across workspaces is an **Enterprise** feature. The **Distribution** tab will show an upgrade prompt instead of the share controls until your workspace has a valid Enterprise key. See [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to activate it.
|
||||
</Warning>
|
||||
|
||||
Tarball uygulamaları genel pazar yerinde listelenmez; bu nedenle aynı sunucudaki diğer çalışma alanları gezinerek onları keşfedemez. Once your workspace is on the Enterprise plan, you can share a deployed app like this:
|
||||
|
||||
1. **Ayarlar > Uygulamalar > Kayıtlar** bölümüne gidin ve uygulamanızı açın
|
||||
2. **Dağıtım** sekmesinde, **Paylaşım bağlantısını kopyala**’ya tıklayın
|
||||
@@ -60,10 +64,6 @@ Tarball uygulamaları genel pazar yerinde listelenmez; bu nedenle aynı sunucuda
|
||||
|
||||
Paylaşım bağlantısı, sunucunun temel URL’sini (herhangi bir çalışma alanı alt alan adı olmadan) kullanır; böylece sunucudaki herhangi bir çalışma alanı için çalışır.
|
||||
|
||||
<Warning>
|
||||
Özel uygulamaları paylaşma bir Kurumsal özelliktir. [Ayarlar > Yönetim Paneli > Kurumsal](/settings/admin-panel#enterprise) bölümüne giderek etkinleştirin.
|
||||
</Warning>
|
||||
|
||||
### Sürüm yönetimi
|
||||
|
||||
Bir güncelleme yayımlamak için:
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"rules": {
|
||||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
|
||||
"no-console": ["warn", { "allow": ["group", "groupCollapsed", "groupEnd"] }],
|
||||
"no-script-url": "error",
|
||||
"no-control-regex": "off",
|
||||
"no-debugger": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
@@ -58,6 +59,7 @@
|
||||
"react/jsx-uses-react": "off",
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"react/jsx-no-useless-fragment": "off",
|
||||
"react/jsx-no-script-url": "error",
|
||||
"react/jsx-props-no-spreading": ["error", { "explicitSpread": "ignore" }],
|
||||
|
||||
"react-hooks/rules-of-hooks": "error",
|
||||
|
||||
@@ -29,6 +29,7 @@ module.exports = {
|
||||
'./src/modules/front-components/graphql/**/*.{ts,tsx}',
|
||||
|
||||
'./src/modules/page-layout/widgets/**/graphql/**/*.{ts,tsx}',
|
||||
'./src/modules/activities/emails/graphql/mutations/**/*.{ts,tsx}',
|
||||
|
||||
'./src/modules/dashboards/graphql/**/*.{ts,tsx}',
|
||||
'./src/modules/page-layout/graphql/**/*.{ts,tsx}',
|
||||
|
||||
@@ -6,7 +6,8 @@ module.exports = {
|
||||
'/graphql',
|
||||
documents: [
|
||||
'./src/modules/workflow/**/graphql/**/*.{ts,tsx}',
|
||||
'./src/modules/activities/emails/graphql/**/*.{ts,tsx}',
|
||||
'./src/modules/activities/emails/graphql/queries/**/*.{ts,tsx}',
|
||||
'./src/modules/activities/emails/graphql/operation-signatures/**/*.{ts,tsx}',
|
||||
'./src/modules/activities/calendar/graphql/**/*.{ts,tsx}',
|
||||
'./src/modules/search/graphql/**/*.{ts,tsx}',
|
||||
'./src/modules/command-menu/graphql/**/*.{ts,tsx}',
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,9 +1,11 @@
|
||||
import { useOpenSettingsMenu } from '@/navigation/hooks/useOpenSettings';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { type SettingsPath } from 'twenty-shared/types';
|
||||
import { getSettingsPath } from 'twenty-shared/utils';
|
||||
|
||||
export const useNavigateSettings = () => {
|
||||
const navigate = useNavigate();
|
||||
const { openSettingsMenu } = useOpenSettingsMenu();
|
||||
|
||||
return <T extends SettingsPath>(
|
||||
to: T,
|
||||
@@ -14,6 +16,8 @@ export const useNavigateSettings = () => {
|
||||
state?: any;
|
||||
},
|
||||
) => {
|
||||
openSettingsMenu();
|
||||
|
||||
const path = getSettingsPath(to, params, queryParams);
|
||||
return navigate(path, options);
|
||||
};
|
||||
|
||||
@@ -316,6 +316,11 @@ msgstr "{jobCount, plural, one {Dit sal dit permanent uit die waglyn verwyder. H
|
||||
msgid "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
msgstr "{jobCount, plural, one {Dit sal die geselekteerde werk herprobeer. Dit sal van vooraf weer uitgevoer word.} other {Dit sal die geselekteerde werke herprobeer. Hulle sal van vooraf weer uitgevoer word.}}"
|
||||
|
||||
#. js-lingui-id: Y32cMj
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadIntermediaryMessages.tsx
|
||||
msgid "{messagesLength} emails"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Koe99p
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationItemTableRow.tsx
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx
|
||||
@@ -451,11 +456,13 @@ msgstr "{workspaceMemberName} sal ontkoppel word van die volgende rol:"
|
||||
msgid "••••••••"
|
||||
msgstr "••••••••"
|
||||
|
||||
#. js-lingui-id: tD9raa
|
||||
#. js-lingui-id: SMgdEJ
|
||||
#. placeholder {0}: formatNumber(preview.estimatedTokenCount, { abbreviate: true, decimals: 1, })
|
||||
#. placeholder {0}: formatNumber( section.estimatedTokenCount, { abbreviate: true, decimals: 1, }, )
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~{0} tokens"
|
||||
msgstr "~{0} tokens"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~ {0} tokens"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Cx0xl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/delay-actions/components/WorkflowEditActionDelay.tsx
|
||||
@@ -1702,6 +1709,7 @@ msgstr "'n Fout het voorgekom tydens die oplaai van die prent."
|
||||
#: src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
|
||||
#: src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts
|
||||
#: src/modules/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets.ts
|
||||
#: src/modules/page-layout/hooks/useResetPageLayoutWidgetToDefault.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneFieldMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts
|
||||
@@ -1984,6 +1992,11 @@ msgstr "Goedgekeurde Domeine"
|
||||
msgid "Apps"
|
||||
msgstr "Apps"
|
||||
|
||||
#. js-lingui-id: dEnE1D
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Apps made by other developers published on npm"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8HV3WN
|
||||
#: src/pages/settings/profile/appearance/components/LocalePicker.tsx
|
||||
msgid "Arabic"
|
||||
@@ -2408,6 +2421,12 @@ msgstr "Basis-URL"
|
||||
msgid "Base URL is required"
|
||||
msgstr "Basis-URL word vereis"
|
||||
|
||||
#. js-lingui-id: /xLNEx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
@@ -2711,9 +2730,11 @@ msgstr "Kan nie skandeer nie? Kopieer die"
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Kanselleer"
|
||||
|
||||
@@ -2753,6 +2774,11 @@ msgstr "Kanselleer planwisseling"
|
||||
msgid "Cancel plan switching?"
|
||||
msgstr "Kanselleer planwisseling?"
|
||||
|
||||
#. js-lingui-id: AnRu/j
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: N6gPiD
|
||||
#: src/pages/settings/enterprise/SettingsEnterprise.tsx
|
||||
#: src/modules/settings/billing/components/SettingsBillingContent.tsx
|
||||
@@ -2821,11 +2847,22 @@ msgstr "Katalaans"
|
||||
msgid "Category"
|
||||
msgstr "Kategorie"
|
||||
|
||||
#. js-lingui-id: RpYfjZ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr "CC"
|
||||
|
||||
#. js-lingui-id: Dgsw8A
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc/Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardEditorSideMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
@@ -3776,11 +3813,6 @@ msgstr "skep"
|
||||
msgid "Create"
|
||||
msgstr "Skep"
|
||||
|
||||
#. js-lingui-id: 5XhrY3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create & Develop"
|
||||
msgstr "Skep & Ontwikkel"
|
||||
|
||||
#. js-lingui-id: 8aATyU
|
||||
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
|
||||
msgid "Create a dashboard"
|
||||
@@ -3821,6 +3853,11 @@ msgstr "Skep 'n werksvloei en kom terug hier om sy weergawes te besigtig"
|
||||
msgid "Create a workspace"
|
||||
msgstr "Skep 'n werksruimte"
|
||||
|
||||
#. js-lingui-id: /WlFSf
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create an application"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8ZjIgO
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
|
||||
msgid "Create and configure AI agents"
|
||||
@@ -4794,6 +4831,7 @@ msgstr "Beskryf wat jy wil hê die KI moet doen..."
|
||||
|
||||
#. js-lingui-id: Nu4oKW
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldEdit.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/ai/SettingsToolDetail.tsx
|
||||
@@ -5339,16 +5377,16 @@ msgstr "E-pos moet 'n geldige e-pos wees"
|
||||
msgid "Email or domain is already in blocklist"
|
||||
msgstr "E-pos of domein is reeds in bloklys"
|
||||
|
||||
#. js-lingui-id: Xl929X
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Email sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: jvneza
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Email support"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +VjrH/
|
||||
#: src/modules/side-panel/hooks/useOpenEmailThreadInSidePanel.ts
|
||||
msgid "Email Thread"
|
||||
msgstr "E-posdraad"
|
||||
|
||||
#. js-lingui-id: LimKOG
|
||||
#: src/pages/settings/security/SettingsSecurityApprovedAccessDomain.tsx
|
||||
msgid "Email verification"
|
||||
@@ -6433,6 +6471,12 @@ msgstr ""
|
||||
msgid "Failed to save workspace instructions"
|
||||
msgstr "Kon nie werkruimte-instruksies stoor nie"
|
||||
|
||||
#. js-lingui-id: Lo/GQ5
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Failed to send email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: aj02T8
|
||||
#: src/modules/settings/admin-panel/health-status/maintenance-mode/components/SettingsAdminMaintenanceMode.tsx
|
||||
msgid "Failed to set maintenance mode."
|
||||
@@ -6924,6 +6968,11 @@ msgstr "Gratis proefkrediete uitgeput. Teken nou in om voort te gaan om AI-funks
|
||||
msgid "French"
|
||||
msgstr "Frans"
|
||||
|
||||
#. js-lingui-id: ejVYRQ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qR8gT9
|
||||
#: src/modules/workflow/workflow-trigger/utils/cron-to-human/descriptors/getDayOfWeekDescription.ts
|
||||
msgid "from {startDay} to {endDay}"
|
||||
@@ -8571,7 +8620,7 @@ msgid "Loading skills..."
|
||||
msgstr "Laai vaardighede..."
|
||||
|
||||
#. js-lingui-id: 7YK6ap
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadWidget.tsx
|
||||
msgid "Loading thread"
|
||||
msgstr "Laai draad"
|
||||
|
||||
@@ -9223,10 +9272,10 @@ msgstr "mySkill"
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/data-model/constants/SettingsObjectTableMetadata.ts
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationGeneralTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTable.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
@@ -9392,6 +9441,11 @@ msgstr "Nuwe geselsie"
|
||||
msgid "New conversation"
|
||||
msgstr "Nuwe gesprek"
|
||||
|
||||
#. js-lingui-id: 3RwJHq
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
msgid "New Email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: wqoYqp
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
@@ -9590,6 +9644,11 @@ msgstr "Geen API sleutels beskikbaar nie"
|
||||
msgid "No API keys match your search"
|
||||
msgstr "Geen API sleutels voldoen aan jou soektog nie"
|
||||
|
||||
#. js-lingui-id: /VRg8Z
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "No application found"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: rxBnh8
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
msgid "No applications available"
|
||||
@@ -10018,6 +10077,7 @@ msgid "No variables found"
|
||||
msgstr "Geen veranderlikes gevind nie"
|
||||
|
||||
#. js-lingui-id: OCektF
|
||||
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationDetailEnvironmentVariablesTable.tsx
|
||||
msgid "No variables to set for this application"
|
||||
msgstr ""
|
||||
@@ -10133,6 +10193,11 @@ msgstr "nou"
|
||||
msgid "Npm package"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: p7abaY
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "NPM packages"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: VVexZo
|
||||
#: src/modules/advanced-text-editor/extensions/slash-command/DefaultSlashCommands.ts
|
||||
msgid "number"
|
||||
@@ -11357,10 +11422,11 @@ msgstr ""
|
||||
msgid "Read your profile"
|
||||
msgstr "Lees jou profiel"
|
||||
|
||||
#. js-lingui-id: tCXcL7
|
||||
#. js-lingui-id: 6pSHJ5
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "Leesalleen — bestuur deur Twenty"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
@@ -11382,6 +11448,11 @@ msgstr "Ontvang 'n e-pos met skakel om wagwoord op te dateer"
|
||||
msgid "Recent Events (oldest → newest)"
|
||||
msgstr "Onlangse Gebeure (oudste → nuutste)"
|
||||
|
||||
#. js-lingui-id: yPrbsy
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Recipients"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: b2+5uV
|
||||
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
|
||||
msgid "Recommended Models"
|
||||
@@ -11733,7 +11804,8 @@ msgid "Reorder options"
|
||||
msgstr "Herskik opsies"
|
||||
|
||||
#. js-lingui-id: ImOQa9
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailThreadBottomBar.tsx
|
||||
msgid "Reply"
|
||||
msgstr "Reageer"
|
||||
@@ -11743,6 +11815,11 @@ msgstr "Reageer"
|
||||
msgid "Reply to all"
|
||||
msgstr "Beantwoord almal"
|
||||
|
||||
#. js-lingui-id: fiPYZo
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Reply..."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tbmZmI
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Report and issue"
|
||||
@@ -11768,6 +11845,7 @@ msgstr "Stuur e-pos weer"
|
||||
#. js-lingui-id: OfhWJH
|
||||
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
|
||||
#: src/modules/views/components/ViewBarDetails.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "Reset"
|
||||
msgstr "Stel terug"
|
||||
|
||||
@@ -11788,6 +11866,8 @@ msgid "Reset to"
|
||||
msgstr "Herstel na"
|
||||
|
||||
#. js-lingui-id: L+rMC9
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/command-menu-item/server-items/edit/components/SidePanelCommandMenuItemEditPage.tsx
|
||||
msgid "Reset to default"
|
||||
@@ -12086,11 +12166,6 @@ msgstr "Stoor"
|
||||
msgid "Save as new view"
|
||||
msgstr "Stoor as nuwe aansig"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
msgstr "Skep die raamwerk vir 'n nuwe toepassing en gebruik dan die CLI om te ontwikkel, te publiseer en te versprei"
|
||||
|
||||
#. js-lingui-id: gmB6oO
|
||||
#: src/modules/workflow/workflow-trigger/components/CronExpressionHelper.tsx
|
||||
msgid "Schedule"
|
||||
@@ -12232,6 +12307,7 @@ msgid "Search an agent..."
|
||||
msgstr "Soek vir 'n agent..."
|
||||
|
||||
#. js-lingui-id: fGTI3o
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
msgid "Search an application"
|
||||
@@ -12686,6 +12762,13 @@ msgstr "Kies watter modelle as aanbevole modelle in die werkruimte se modelkiese
|
||||
msgid "Select your preferred language"
|
||||
msgstr "Kies jou voorkeurtaal"
|
||||
|
||||
#. js-lingui-id: JlFcis
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mjK8F3
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
msgid "Send an invite email to your team"
|
||||
@@ -13401,6 +13484,8 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Onderwerp"
|
||||
|
||||
@@ -13641,11 +13726,6 @@ msgstr ""
|
||||
msgid "System Prompt"
|
||||
msgstr "Stelsel Prompt"
|
||||
|
||||
#. js-lingui-id: BXGTWI
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "System Prompt ({totalTokenCount})"
|
||||
msgstr "Stelselprompt ({totalTokenCount})"
|
||||
|
||||
#. js-lingui-id: k+7QWO
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
|
||||
msgid "System relations"
|
||||
@@ -14132,6 +14212,11 @@ msgstr ""
|
||||
msgid "This week"
|
||||
msgstr "Hierdie week"
|
||||
|
||||
#. js-lingui-id: VbVocX
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4VeOo
|
||||
#: src/modules/settings/billing/hooks/useBillingWording.ts
|
||||
msgid "This will cancel the scheduled interval change and keep your current billing interval ({currentIntervalLabel})."
|
||||
@@ -14247,6 +14332,7 @@ msgstr "titel"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "To"
|
||||
msgstr "Aan"
|
||||
|
||||
@@ -14548,7 +14634,6 @@ msgstr "Twee-faktor magtiging-setup suksesvol voltooi!"
|
||||
|
||||
#. js-lingui-id: +zy2Nq
|
||||
#: src/pages/settings/data-model/SettingsObjectIndexTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
#: src/pages/settings/ai/components/SettingsToolParameterTable.tsx
|
||||
@@ -14571,6 +14656,11 @@ msgstr "Tik '/' vir opdragte, '@' vir vermeldings"
|
||||
msgid "Type anything..."
|
||||
msgstr "Tik enigiets..."
|
||||
|
||||
#. js-lingui-id: LaEX5I
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Type something or press \"/\" to see commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UhqKcC
|
||||
#: src/modules/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemRecordSubPage.tsx
|
||||
msgid "Type to search records"
|
||||
@@ -14898,6 +14988,11 @@ msgstr "Opgradeer vir toegang"
|
||||
msgid "Upgrade to Enterprise to access audit logs."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: D+7y/3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "Upgrade to Enterprise to share private applications."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +Gi3x1
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationVersionContainer.tsx
|
||||
@@ -15334,7 +15429,6 @@ msgstr "Bekyk logboeke"
|
||||
|
||||
#. js-lingui-id: 7PrSCy
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View marketplace page"
|
||||
msgstr "Bekyk markplekbladsy"
|
||||
|
||||
@@ -15348,6 +15442,11 @@ msgstr ""
|
||||
msgid "View Previous AI Chats"
|
||||
msgstr "Sien Vorige KI-kletse"
|
||||
|
||||
#. js-lingui-id: NnJpTN
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View private application page"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: hAAsm/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx
|
||||
msgid "View role"
|
||||
@@ -15942,6 +16041,11 @@ msgstr "Jy behoort reeds aan hierdie werksruimte"
|
||||
msgid "You are not allowed to create records for this object"
|
||||
msgstr "Jy mag nie rekords vir hierdie voorwerp skep nie"
|
||||
|
||||
#. js-lingui-id: iibZbD
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "You can either create a private app or share it to others"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: CNAoaw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/logic-function-action/components/WorkflowEditActionLogicFunction.tsx
|
||||
msgid "You can see the function logic in your application settings."
|
||||
@@ -16017,10 +16121,10 @@ msgstr "Jou rekening is geaktiveer."
|
||||
msgid "Your app version is out of date. Please refresh the page."
|
||||
msgstr "Jou app weergawe is verouderd. Verfris asseblief die bladsy."
|
||||
|
||||
#. js-lingui-id: oNUh7z
|
||||
#. js-lingui-id: 9pWhO+
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Your Apps"
|
||||
msgstr "Jou toepassings"
|
||||
msgid "Your apps"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +5YqGH
|
||||
#: src/modules/onboarding/constants/OnboardingSyncEmailsOptions.ts
|
||||
|
||||
@@ -316,6 +316,11 @@ msgstr "{jobCount, plural, zero {سيتم إزالة {jobCount} نهائيًا
|
||||
msgid "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
msgstr "{jobCount, plural, zero {سيتم إعادة محاولة {jobCount} وظائف. سيتم تنفيذهم مجددًا من البداية.} one {سيتم إعادة محاولة الوظيفة المحددة. سيتم تنفيذها من البداية.} two {سيتم إعادة المحاولة للوظائف المحددة. سيتم تنفيذهم من البداية.} few {سيتم إعادة المحاولة للوظائف المحددة. سيتم تنفيذهم من البداية.} many {سيتم إعادة المحاولة للوظائف المحددة. سيتم تنفيذهم من البداية.} other {سيتم إعادة المحاولة للوظائف المحددة. سيتم تنفيذهم من البداية.}}"
|
||||
|
||||
#. js-lingui-id: Y32cMj
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadIntermediaryMessages.tsx
|
||||
msgid "{messagesLength} emails"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Koe99p
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationItemTableRow.tsx
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx
|
||||
@@ -451,11 +456,13 @@ msgstr "{workspaceMemberName} سيتم إلغاء تعيينه من الدور
|
||||
msgid "••••••••"
|
||||
msgstr "••••••••"
|
||||
|
||||
#. js-lingui-id: tD9raa
|
||||
#. js-lingui-id: SMgdEJ
|
||||
#. placeholder {0}: formatNumber(preview.estimatedTokenCount, { abbreviate: true, decimals: 1, })
|
||||
#. placeholder {0}: formatNumber( section.estimatedTokenCount, { abbreviate: true, decimals: 1, }, )
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~{0} tokens"
|
||||
msgstr "~{0} رموز"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~ {0} tokens"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Cx0xl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/delay-actions/components/WorkflowEditActionDelay.tsx
|
||||
@@ -1702,6 +1709,7 @@ msgstr "حدث خطأ أثناء تحميل الصورة."
|
||||
#: src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
|
||||
#: src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts
|
||||
#: src/modules/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets.ts
|
||||
#: src/modules/page-layout/hooks/useResetPageLayoutWidgetToDefault.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneFieldMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts
|
||||
@@ -1984,6 +1992,11 @@ msgstr "النطاقات المعتمدة"
|
||||
msgid "Apps"
|
||||
msgstr "التطبيقات"
|
||||
|
||||
#. js-lingui-id: dEnE1D
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Apps made by other developers published on npm"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8HV3WN
|
||||
#: src/pages/settings/profile/appearance/components/LocalePicker.tsx
|
||||
msgid "Arabic"
|
||||
@@ -2408,6 +2421,12 @@ msgstr "عنوان URL الأساسي"
|
||||
msgid "Base URL is required"
|
||||
msgstr "عنوان URL الأساسي مطلوب"
|
||||
|
||||
#. js-lingui-id: /xLNEx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
@@ -2711,9 +2730,11 @@ msgstr "هل لا يمكنك المسح؟ انسخ الـ"
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "إلغاء"
|
||||
|
||||
@@ -2753,6 +2774,11 @@ msgstr "إلغاء تبديل الخطة"
|
||||
msgid "Cancel plan switching?"
|
||||
msgstr "إلغاء تبديل الخطة؟"
|
||||
|
||||
#. js-lingui-id: AnRu/j
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: N6gPiD
|
||||
#: src/pages/settings/enterprise/SettingsEnterprise.tsx
|
||||
#: src/modules/settings/billing/components/SettingsBillingContent.tsx
|
||||
@@ -2821,11 +2847,22 @@ msgstr "الكاتالانية"
|
||||
msgid "Category"
|
||||
msgstr "الفئة"
|
||||
|
||||
#. js-lingui-id: RpYfjZ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr "نسخة كربونية"
|
||||
|
||||
#. js-lingui-id: Dgsw8A
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc/Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardEditorSideMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
@@ -3776,11 +3813,6 @@ msgstr "إنشاء"
|
||||
msgid "Create"
|
||||
msgstr "إنشاء"
|
||||
|
||||
#. js-lingui-id: 5XhrY3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create & Develop"
|
||||
msgstr "الإنشاء والتطوير"
|
||||
|
||||
#. js-lingui-id: 8aATyU
|
||||
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
|
||||
msgid "Create a dashboard"
|
||||
@@ -3821,6 +3853,11 @@ msgstr "أنشئ سير عمل وعُد إلى هنا لرؤية إصدارات
|
||||
msgid "Create a workspace"
|
||||
msgstr "إنشاء مساحة العمل"
|
||||
|
||||
#. js-lingui-id: /WlFSf
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create an application"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8ZjIgO
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
|
||||
msgid "Create and configure AI agents"
|
||||
@@ -4794,6 +4831,7 @@ msgstr "صف ما تريد أن يقوم به الذكاء الاصطناعي...
|
||||
|
||||
#. js-lingui-id: Nu4oKW
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldEdit.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/ai/SettingsToolDetail.tsx
|
||||
@@ -5339,16 +5377,16 @@ msgstr "يجب أن يكون البريد الإلكتروني صالحًا"
|
||||
msgid "Email or domain is already in blocklist"
|
||||
msgstr "البريد الإلكتروني أو النطاق مدرج بالفعل في القائمة السوداء"
|
||||
|
||||
#. js-lingui-id: Xl929X
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Email sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: jvneza
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Email support"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +VjrH/
|
||||
#: src/modules/side-panel/hooks/useOpenEmailThreadInSidePanel.ts
|
||||
msgid "Email Thread"
|
||||
msgstr "سلسلة البريد الإلكتروني"
|
||||
|
||||
#. js-lingui-id: LimKOG
|
||||
#: src/pages/settings/security/SettingsSecurityApprovedAccessDomain.tsx
|
||||
msgid "Email verification"
|
||||
@@ -6433,6 +6471,12 @@ msgstr ""
|
||||
msgid "Failed to save workspace instructions"
|
||||
msgstr "تعذّر حفظ تعليمات مساحة العمل"
|
||||
|
||||
#. js-lingui-id: Lo/GQ5
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Failed to send email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: aj02T8
|
||||
#: src/modules/settings/admin-panel/health-status/maintenance-mode/components/SettingsAdminMaintenanceMode.tsx
|
||||
msgid "Failed to set maintenance mode."
|
||||
@@ -6924,6 +6968,11 @@ msgstr "نفدت أرصدة النسخة التجريبية المجانية. ا
|
||||
msgid "French"
|
||||
msgstr "الفرنسية"
|
||||
|
||||
#. js-lingui-id: ejVYRQ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qR8gT9
|
||||
#: src/modules/workflow/workflow-trigger/utils/cron-to-human/descriptors/getDayOfWeekDescription.ts
|
||||
msgid "from {startDay} to {endDay}"
|
||||
@@ -8571,7 +8620,7 @@ msgid "Loading skills..."
|
||||
msgstr "جارٍ تحميل المهارات..."
|
||||
|
||||
#. js-lingui-id: 7YK6ap
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadWidget.tsx
|
||||
msgid "Loading thread"
|
||||
msgstr "جارٍ تحميل السلسلة"
|
||||
|
||||
@@ -9223,10 +9272,10 @@ msgstr "mySkill"
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/data-model/constants/SettingsObjectTableMetadata.ts
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationGeneralTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTable.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
@@ -9392,6 +9441,11 @@ msgstr "دردشة جديدة"
|
||||
msgid "New conversation"
|
||||
msgstr "محادثة جديدة"
|
||||
|
||||
#. js-lingui-id: 3RwJHq
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
msgid "New Email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: wqoYqp
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
@@ -9590,6 +9644,11 @@ msgstr "لا توجد مفاتيح API متاحة"
|
||||
msgid "No API keys match your search"
|
||||
msgstr "لا توجد مفاتيح API مطابقة لبحثك"
|
||||
|
||||
#. js-lingui-id: /VRg8Z
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "No application found"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: rxBnh8
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
msgid "No applications available"
|
||||
@@ -10018,6 +10077,7 @@ msgid "No variables found"
|
||||
msgstr "لم يتم العثور على متغيرات"
|
||||
|
||||
#. js-lingui-id: OCektF
|
||||
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationDetailEnvironmentVariablesTable.tsx
|
||||
msgid "No variables to set for this application"
|
||||
msgstr ""
|
||||
@@ -10133,6 +10193,11 @@ msgstr "الآن"
|
||||
msgid "Npm package"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: p7abaY
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "NPM packages"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: VVexZo
|
||||
#: src/modules/advanced-text-editor/extensions/slash-command/DefaultSlashCommands.ts
|
||||
msgid "number"
|
||||
@@ -11357,10 +11422,11 @@ msgstr ""
|
||||
msgid "Read your profile"
|
||||
msgstr "قراءة ملفك الشخصي"
|
||||
|
||||
#. js-lingui-id: tCXcL7
|
||||
#. js-lingui-id: 6pSHJ5
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "للقراءة فقط — تُدار بواسطة Twenty"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
@@ -11382,6 +11448,11 @@ msgstr "\\\\"
|
||||
msgid "Recent Events (oldest → newest)"
|
||||
msgstr "الأحداث الأخيرة (الأقدم ← الأحدث)"
|
||||
|
||||
#. js-lingui-id: yPrbsy
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Recipients"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: b2+5uV
|
||||
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
|
||||
msgid "Recommended Models"
|
||||
@@ -11733,7 +11804,8 @@ msgid "Reorder options"
|
||||
msgstr "إعادة ترتيب الخيارات"
|
||||
|
||||
#. js-lingui-id: ImOQa9
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailThreadBottomBar.tsx
|
||||
msgid "Reply"
|
||||
msgstr "الرد"
|
||||
@@ -11743,6 +11815,11 @@ msgstr "الرد"
|
||||
msgid "Reply to all"
|
||||
msgstr "الرد على الكل"
|
||||
|
||||
#. js-lingui-id: fiPYZo
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Reply..."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tbmZmI
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Report and issue"
|
||||
@@ -11768,6 +11845,7 @@ msgstr "إعادة إرسال البريد الإلكتروني"
|
||||
#. js-lingui-id: OfhWJH
|
||||
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
|
||||
#: src/modules/views/components/ViewBarDetails.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "Reset"
|
||||
msgstr "إعادة تعيين"
|
||||
|
||||
@@ -11788,6 +11866,8 @@ msgid "Reset to"
|
||||
msgstr "\\\\"
|
||||
|
||||
#. js-lingui-id: L+rMC9
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/command-menu-item/server-items/edit/components/SidePanelCommandMenuItemEditPage.tsx
|
||||
msgid "Reset to default"
|
||||
@@ -12086,11 +12166,6 @@ msgstr "حفظ"
|
||||
msgid "Save as new view"
|
||||
msgstr "احفظ كعرض جديد"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
msgstr "أنشئ قالبًا لتطبيق جديد، ثم استخدم CLI للتطوير والنشر والتوزيع"
|
||||
|
||||
#. js-lingui-id: gmB6oO
|
||||
#: src/modules/workflow/workflow-trigger/components/CronExpressionHelper.tsx
|
||||
msgid "Schedule"
|
||||
@@ -12232,6 +12307,7 @@ msgid "Search an agent..."
|
||||
msgstr "ابحث عن وكيل..."
|
||||
|
||||
#. js-lingui-id: fGTI3o
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
msgid "Search an application"
|
||||
@@ -12686,6 +12762,13 @@ msgstr "حدد النماذج التي ستظهر كموصى بها في منت
|
||||
msgid "Select your preferred language"
|
||||
msgstr "\\\\"
|
||||
|
||||
#. js-lingui-id: JlFcis
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mjK8F3
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
msgid "Send an invite email to your team"
|
||||
@@ -13401,6 +13484,8 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Subject"
|
||||
msgstr "الموضوع"
|
||||
|
||||
@@ -13641,11 +13726,6 @@ msgstr ""
|
||||
msgid "System Prompt"
|
||||
msgstr "أمر النظام"
|
||||
|
||||
#. js-lingui-id: BXGTWI
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "System Prompt ({totalTokenCount})"
|
||||
msgstr "موجّه النظام ({totalTokenCount})"
|
||||
|
||||
#. js-lingui-id: k+7QWO
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
|
||||
msgid "System relations"
|
||||
@@ -14132,6 +14212,11 @@ msgstr ""
|
||||
msgid "This week"
|
||||
msgstr "هذا الأسبوع"
|
||||
|
||||
#. js-lingui-id: VbVocX
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4VeOo
|
||||
#: src/modules/settings/billing/hooks/useBillingWording.ts
|
||||
msgid "This will cancel the scheduled interval change and keep your current billing interval ({currentIntervalLabel})."
|
||||
@@ -14247,6 +14332,7 @@ msgstr "العنوان"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "To"
|
||||
msgstr "إلى"
|
||||
|
||||
@@ -14548,7 +14634,6 @@ msgstr "تم إكمال إعداد المصادقة الثنائية بنجاح!
|
||||
|
||||
#. js-lingui-id: +zy2Nq
|
||||
#: src/pages/settings/data-model/SettingsObjectIndexTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
#: src/pages/settings/ai/components/SettingsToolParameterTable.tsx
|
||||
@@ -14571,6 +14656,11 @@ msgstr "اكتب '/' للأوامر، و'@' للإشارات"
|
||||
msgid "Type anything..."
|
||||
msgstr "اكتب أي شيء..."
|
||||
|
||||
#. js-lingui-id: LaEX5I
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Type something or press \"/\" to see commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UhqKcC
|
||||
#: src/modules/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemRecordSubPage.tsx
|
||||
msgid "Type to search records"
|
||||
@@ -14898,6 +14988,11 @@ msgstr "الترقية للوصول"
|
||||
msgid "Upgrade to Enterprise to access audit logs."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: D+7y/3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "Upgrade to Enterprise to share private applications."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +Gi3x1
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationVersionContainer.tsx
|
||||
@@ -15334,7 +15429,6 @@ msgstr "عرض السجلات"
|
||||
|
||||
#. js-lingui-id: 7PrSCy
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View marketplace page"
|
||||
msgstr "عرض صفحة سوق التطبيقات"
|
||||
|
||||
@@ -15348,6 +15442,11 @@ msgstr ""
|
||||
msgid "View Previous AI Chats"
|
||||
msgstr "عرض الذكاءات الاصطناعية السابقة"
|
||||
|
||||
#. js-lingui-id: NnJpTN
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View private application page"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: hAAsm/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx
|
||||
msgid "View role"
|
||||
@@ -15940,6 +16039,11 @@ msgstr "أنت بالفعل تنتمي إلى هذا فضاء العمل"
|
||||
msgid "You are not allowed to create records for this object"
|
||||
msgstr "غير مسموح لك بإنشاء سجلات لهذا الكائن"
|
||||
|
||||
#. js-lingui-id: iibZbD
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "You can either create a private app or share it to others"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: CNAoaw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/logic-function-action/components/WorkflowEditActionLogicFunction.tsx
|
||||
msgid "You can see the function logic in your application settings."
|
||||
@@ -16015,10 +16119,10 @@ msgstr "تم تنشيط حسابك."
|
||||
msgid "Your app version is out of date. Please refresh the page."
|
||||
msgstr "نسخة التطبيق لديك قديمة. يُرجى تحديث الصفحة."
|
||||
|
||||
#. js-lingui-id: oNUh7z
|
||||
#. js-lingui-id: 9pWhO+
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Your Apps"
|
||||
msgstr "تطبيقاتك"
|
||||
msgid "Your apps"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +5YqGH
|
||||
#: src/modules/onboarding/constants/OnboardingSyncEmailsOptions.ts
|
||||
|
||||
@@ -316,6 +316,11 @@ msgstr "{jobCount, plural, one {Això eliminarà permanentment la cua. Aquesta a
|
||||
msgid "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
msgstr "{jobCount, plural, one {Això tornarà a intentar la feina seleccionada. Es tornarà a executar des del principi.} other {Això tornarà a intentar les feines seleccionades. Es tornaran a executar des del principi.}}"
|
||||
|
||||
#. js-lingui-id: Y32cMj
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadIntermediaryMessages.tsx
|
||||
msgid "{messagesLength} emails"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Koe99p
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationItemTableRow.tsx
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx
|
||||
@@ -451,11 +456,13 @@ msgstr "{workspaceMemberName} serà desassignat del següent rol:"
|
||||
msgid "••••••••"
|
||||
msgstr "••••••••"
|
||||
|
||||
#. js-lingui-id: tD9raa
|
||||
#. js-lingui-id: SMgdEJ
|
||||
#. placeholder {0}: formatNumber(preview.estimatedTokenCount, { abbreviate: true, decimals: 1, })
|
||||
#. placeholder {0}: formatNumber( section.estimatedTokenCount, { abbreviate: true, decimals: 1, }, )
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~{0} tokens"
|
||||
msgstr "~{0} tokens"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~ {0} tokens"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Cx0xl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/delay-actions/components/WorkflowEditActionDelay.tsx
|
||||
@@ -1702,6 +1709,7 @@ msgstr "S'ha produït un error en carregar la imatge."
|
||||
#: src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
|
||||
#: src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts
|
||||
#: src/modules/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets.ts
|
||||
#: src/modules/page-layout/hooks/useResetPageLayoutWidgetToDefault.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneFieldMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts
|
||||
@@ -1984,6 +1992,11 @@ msgstr "Dominis Aprovats"
|
||||
msgid "Apps"
|
||||
msgstr "Aplicacions"
|
||||
|
||||
#. js-lingui-id: dEnE1D
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Apps made by other developers published on npm"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8HV3WN
|
||||
#: src/pages/settings/profile/appearance/components/LocalePicker.tsx
|
||||
msgid "Arabic"
|
||||
@@ -2408,6 +2421,12 @@ msgstr "URL base"
|
||||
msgid "Base URL is required"
|
||||
msgstr "L'URL base és necessari"
|
||||
|
||||
#. js-lingui-id: /xLNEx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
@@ -2711,9 +2730,11 @@ msgstr "No pots escanejar? Copia la"
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel·la"
|
||||
|
||||
@@ -2753,6 +2774,11 @@ msgstr "Cancel·lar el canvi de pla"
|
||||
msgid "Cancel plan switching?"
|
||||
msgstr "Cancel·lar el canvi de pla?"
|
||||
|
||||
#. js-lingui-id: AnRu/j
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: N6gPiD
|
||||
#: src/pages/settings/enterprise/SettingsEnterprise.tsx
|
||||
#: src/modules/settings/billing/components/SettingsBillingContent.tsx
|
||||
@@ -2821,11 +2847,22 @@ msgstr "Català"
|
||||
msgid "Category"
|
||||
msgstr "Categoria"
|
||||
|
||||
#. js-lingui-id: RpYfjZ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr "CC"
|
||||
|
||||
#. js-lingui-id: Dgsw8A
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc/Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardEditorSideMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
@@ -3776,11 +3813,6 @@ msgstr "crea"
|
||||
msgid "Create"
|
||||
msgstr "Crea"
|
||||
|
||||
#. js-lingui-id: 5XhrY3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create & Develop"
|
||||
msgstr "Crea i desenvolupa"
|
||||
|
||||
#. js-lingui-id: 8aATyU
|
||||
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
|
||||
msgid "Create a dashboard"
|
||||
@@ -3821,6 +3853,11 @@ msgstr "Crea un flux de treball i torna aquí per veure les seves versions"
|
||||
msgid "Create a workspace"
|
||||
msgstr "Crear un espai de treball"
|
||||
|
||||
#. js-lingui-id: /WlFSf
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create an application"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8ZjIgO
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
|
||||
msgid "Create and configure AI agents"
|
||||
@@ -4794,6 +4831,7 @@ msgstr "Descriviu què voleu que faci la IA..."
|
||||
|
||||
#. js-lingui-id: Nu4oKW
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldEdit.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/ai/SettingsToolDetail.tsx
|
||||
@@ -5339,16 +5377,16 @@ msgstr "El correu electrònic ha de ser vàlid"
|
||||
msgid "Email or domain is already in blocklist"
|
||||
msgstr "El correu electrònic o domini ja està en la llista de bloqueig"
|
||||
|
||||
#. js-lingui-id: Xl929X
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Email sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: jvneza
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Email support"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +VjrH/
|
||||
#: src/modules/side-panel/hooks/useOpenEmailThreadInSidePanel.ts
|
||||
msgid "Email Thread"
|
||||
msgstr "Fil de correu electrònic"
|
||||
|
||||
#. js-lingui-id: LimKOG
|
||||
#: src/pages/settings/security/SettingsSecurityApprovedAccessDomain.tsx
|
||||
msgid "Email verification"
|
||||
@@ -6433,6 +6471,12 @@ msgstr ""
|
||||
msgid "Failed to save workspace instructions"
|
||||
msgstr "No s'han pogut desar les instruccions de l'espai de treball"
|
||||
|
||||
#. js-lingui-id: Lo/GQ5
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Failed to send email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: aj02T8
|
||||
#: src/modules/settings/admin-panel/health-status/maintenance-mode/components/SettingsAdminMaintenanceMode.tsx
|
||||
msgid "Failed to set maintenance mode."
|
||||
@@ -6924,6 +6968,11 @@ msgstr "Crèdits de la prova gratuïta esgotats. Subscriu-te ara per continuar u
|
||||
msgid "French"
|
||||
msgstr "Francès"
|
||||
|
||||
#. js-lingui-id: ejVYRQ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qR8gT9
|
||||
#: src/modules/workflow/workflow-trigger/utils/cron-to-human/descriptors/getDayOfWeekDescription.ts
|
||||
msgid "from {startDay} to {endDay}"
|
||||
@@ -8571,7 +8620,7 @@ msgid "Loading skills..."
|
||||
msgstr "Carregant habilitats..."
|
||||
|
||||
#. js-lingui-id: 7YK6ap
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadWidget.tsx
|
||||
msgid "Loading thread"
|
||||
msgstr "Carregant el fil"
|
||||
|
||||
@@ -9223,10 +9272,10 @@ msgstr "mySkill"
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/data-model/constants/SettingsObjectTableMetadata.ts
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationGeneralTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTable.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
@@ -9392,6 +9441,11 @@ msgstr "Nou xat"
|
||||
msgid "New conversation"
|
||||
msgstr "Nova conversa"
|
||||
|
||||
#. js-lingui-id: 3RwJHq
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
msgid "New Email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: wqoYqp
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
@@ -9590,6 +9644,11 @@ msgstr "No hi ha claus d'API disponibles"
|
||||
msgid "No API keys match your search"
|
||||
msgstr "Cap clau d'API concorda amb la teva cerca"
|
||||
|
||||
#. js-lingui-id: /VRg8Z
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "No application found"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: rxBnh8
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
msgid "No applications available"
|
||||
@@ -10018,6 +10077,7 @@ msgid "No variables found"
|
||||
msgstr "No s'han trobat variables"
|
||||
|
||||
#. js-lingui-id: OCektF
|
||||
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationDetailEnvironmentVariablesTable.tsx
|
||||
msgid "No variables to set for this application"
|
||||
msgstr ""
|
||||
@@ -10133,6 +10193,11 @@ msgstr "ara"
|
||||
msgid "Npm package"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: p7abaY
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "NPM packages"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: VVexZo
|
||||
#: src/modules/advanced-text-editor/extensions/slash-command/DefaultSlashCommands.ts
|
||||
msgid "number"
|
||||
@@ -11357,10 +11422,11 @@ msgstr ""
|
||||
msgid "Read your profile"
|
||||
msgstr "Llegir el teu perfil"
|
||||
|
||||
#. js-lingui-id: tCXcL7
|
||||
#. js-lingui-id: 6pSHJ5
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "Només de lectura — gestionat per Twenty"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
@@ -11382,6 +11448,11 @@ msgstr "Rep un correu que conté l'enllaç per actualitzar la contrasenya"
|
||||
msgid "Recent Events (oldest → newest)"
|
||||
msgstr "Esdeveniments recents (més antic → més nou)"
|
||||
|
||||
#. js-lingui-id: yPrbsy
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Recipients"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: b2+5uV
|
||||
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
|
||||
msgid "Recommended Models"
|
||||
@@ -11733,7 +11804,8 @@ msgid "Reorder options"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: ImOQa9
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailThreadBottomBar.tsx
|
||||
msgid "Reply"
|
||||
msgstr "Respon"
|
||||
@@ -11743,6 +11815,11 @@ msgstr "Respon"
|
||||
msgid "Reply to all"
|
||||
msgstr "Respon a tots"
|
||||
|
||||
#. js-lingui-id: fiPYZo
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Reply..."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tbmZmI
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Report and issue"
|
||||
@@ -11768,6 +11845,7 @@ msgstr "Reenviar correu electrònic"
|
||||
#. js-lingui-id: OfhWJH
|
||||
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
|
||||
#: src/modules/views/components/ViewBarDetails.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "Reset"
|
||||
msgstr "Restableix"
|
||||
|
||||
@@ -11788,6 +11866,8 @@ msgid "Reset to"
|
||||
msgstr "Reinicia a"
|
||||
|
||||
#. js-lingui-id: L+rMC9
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/command-menu-item/server-items/edit/components/SidePanelCommandMenuItemEditPage.tsx
|
||||
msgid "Reset to default"
|
||||
@@ -12086,11 +12166,6 @@ msgstr "Desa"
|
||||
msgid "Save as new view"
|
||||
msgstr "Desa com a nova vista"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
msgstr "Genera l'esquelet d'una aplicació nova, després utilitza la CLI per desenvolupar, publicar i distribuir"
|
||||
|
||||
#. js-lingui-id: gmB6oO
|
||||
#: src/modules/workflow/workflow-trigger/components/CronExpressionHelper.tsx
|
||||
msgid "Schedule"
|
||||
@@ -12232,6 +12307,7 @@ msgid "Search an agent..."
|
||||
msgstr "Cerca un agent..."
|
||||
|
||||
#. js-lingui-id: fGTI3o
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
msgid "Search an application"
|
||||
@@ -12686,6 +12762,13 @@ msgstr "Seleccioneu quins models apareixen com a recomanats al selector de model
|
||||
msgid "Select your preferred language"
|
||||
msgstr "Tria la teva llengua preferida"
|
||||
|
||||
#. js-lingui-id: JlFcis
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mjK8F3
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
msgid "Send an invite email to your team"
|
||||
@@ -13401,6 +13484,8 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Assumpte"
|
||||
|
||||
@@ -13641,11 +13726,6 @@ msgstr ""
|
||||
msgid "System Prompt"
|
||||
msgstr "Indicador del Sistema"
|
||||
|
||||
#. js-lingui-id: BXGTWI
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "System Prompt ({totalTokenCount})"
|
||||
msgstr "Prompt del sistema ({totalTokenCount})"
|
||||
|
||||
#. js-lingui-id: k+7QWO
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
|
||||
msgid "System relations"
|
||||
@@ -14132,6 +14212,11 @@ msgstr ""
|
||||
msgid "This week"
|
||||
msgstr "Aquesta setmana"
|
||||
|
||||
#. js-lingui-id: VbVocX
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4VeOo
|
||||
#: src/modules/settings/billing/hooks/useBillingWording.ts
|
||||
msgid "This will cancel the scheduled interval change and keep your current billing interval ({currentIntervalLabel})."
|
||||
@@ -14247,6 +14332,7 @@ msgstr "títol"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "To"
|
||||
msgstr "A"
|
||||
|
||||
@@ -14548,7 +14634,6 @@ msgstr "Configuració de l'autenticació de dos factors completada amb èxit!"
|
||||
|
||||
#. js-lingui-id: +zy2Nq
|
||||
#: src/pages/settings/data-model/SettingsObjectIndexTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
#: src/pages/settings/ai/components/SettingsToolParameterTable.tsx
|
||||
@@ -14571,6 +14656,11 @@ msgstr "Escriu '/' per a ordres, '@' per a mencions"
|
||||
msgid "Type anything..."
|
||||
msgstr "Teclegeu qualsevol cosa..."
|
||||
|
||||
#. js-lingui-id: LaEX5I
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Type something or press \"/\" to see commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UhqKcC
|
||||
#: src/modules/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemRecordSubPage.tsx
|
||||
msgid "Type to search records"
|
||||
@@ -14898,6 +14988,11 @@ msgstr "Actualitza per accedir"
|
||||
msgid "Upgrade to Enterprise to access audit logs."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: D+7y/3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "Upgrade to Enterprise to share private applications."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +Gi3x1
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationVersionContainer.tsx
|
||||
@@ -15334,7 +15429,6 @@ msgstr "Veure registres"
|
||||
|
||||
#. js-lingui-id: 7PrSCy
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View marketplace page"
|
||||
msgstr "Veure la pàgina del Marketplace"
|
||||
|
||||
@@ -15348,6 +15442,11 @@ msgstr ""
|
||||
msgid "View Previous AI Chats"
|
||||
msgstr "Veure els xats d'IA anteriors"
|
||||
|
||||
#. js-lingui-id: NnJpTN
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View private application page"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: hAAsm/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx
|
||||
msgid "View role"
|
||||
@@ -15942,6 +16041,11 @@ msgstr "Ja formes part d'aquest espai de treball"
|
||||
msgid "You are not allowed to create records for this object"
|
||||
msgstr "No tens permís per crear registres en aquest objecte"
|
||||
|
||||
#. js-lingui-id: iibZbD
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "You can either create a private app or share it to others"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: CNAoaw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/logic-function-action/components/WorkflowEditActionLogicFunction.tsx
|
||||
msgid "You can see the function logic in your application settings."
|
||||
@@ -16017,10 +16121,10 @@ msgstr "El teu compte s'ha activat."
|
||||
msgid "Your app version is out of date. Please refresh the page."
|
||||
msgstr "La teva versió de l'aplicació està desactualitzada. Si us plau, actualitza la pàgina."
|
||||
|
||||
#. js-lingui-id: oNUh7z
|
||||
#. js-lingui-id: 9pWhO+
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Your Apps"
|
||||
msgstr "Les teves aplicacions"
|
||||
msgid "Your apps"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +5YqGH
|
||||
#: src/modules/onboarding/constants/OnboardingSyncEmailsOptions.ts
|
||||
|
||||
@@ -316,6 +316,11 @@ msgstr "{jobCount, plural, one {Tato akce ji trvale odstraní z fronty. Tuto akc
|
||||
msgid "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
msgstr "{jobCount, plural, one {Tato akce znovu spustí vybranou úlohu. Bude spuštěna znovu od začátku.} few {Tato akce znovu spustí vybrané úlohy. Budou spuštěny znovu od začátku.} many {Tato akce znovu spustí vybrané úlohy. Budou spuštěny znovu od začátku.} other {Tato akce znovu spustí vybrané úlohy. Budou spuštěny znovu od začátku.}}"
|
||||
|
||||
#. js-lingui-id: Y32cMj
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadIntermediaryMessages.tsx
|
||||
msgid "{messagesLength} emails"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Koe99p
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationItemTableRow.tsx
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx
|
||||
@@ -451,11 +456,13 @@ msgstr "{workspaceMemberName} bude odebrán z následující role:"
|
||||
msgid "••••••••"
|
||||
msgstr "••••••••"
|
||||
|
||||
#. js-lingui-id: tD9raa
|
||||
#. js-lingui-id: SMgdEJ
|
||||
#. placeholder {0}: formatNumber(preview.estimatedTokenCount, { abbreviate: true, decimals: 1, })
|
||||
#. placeholder {0}: formatNumber( section.estimatedTokenCount, { abbreviate: true, decimals: 1, }, )
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~{0} tokens"
|
||||
msgstr "~{0} tokenů"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~ {0} tokens"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Cx0xl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/delay-actions/components/WorkflowEditActionDelay.tsx
|
||||
@@ -1702,6 +1709,7 @@ msgstr "Při nahrávání obrázku došlo k chybě."
|
||||
#: src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
|
||||
#: src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts
|
||||
#: src/modules/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets.ts
|
||||
#: src/modules/page-layout/hooks/useResetPageLayoutWidgetToDefault.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneFieldMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts
|
||||
@@ -1984,6 +1992,11 @@ msgstr "Schválené domény"
|
||||
msgid "Apps"
|
||||
msgstr "Aplikace"
|
||||
|
||||
#. js-lingui-id: dEnE1D
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Apps made by other developers published on npm"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8HV3WN
|
||||
#: src/pages/settings/profile/appearance/components/LocalePicker.tsx
|
||||
msgid "Arabic"
|
||||
@@ -2408,6 +2421,12 @@ msgstr "Základní URL"
|
||||
msgid "Base URL is required"
|
||||
msgstr "Základní adresa URL je vyžadována"
|
||||
|
||||
#. js-lingui-id: /xLNEx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
@@ -2711,9 +2730,11 @@ msgstr "Nemůžete skenovat? Zkopírujte"
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Storno"
|
||||
|
||||
@@ -2753,6 +2774,11 @@ msgstr "Zrušit změnu plánu"
|
||||
msgid "Cancel plan switching?"
|
||||
msgstr "Zrušit změnu plánu?"
|
||||
|
||||
#. js-lingui-id: AnRu/j
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: N6gPiD
|
||||
#: src/pages/settings/enterprise/SettingsEnterprise.tsx
|
||||
#: src/modules/settings/billing/components/SettingsBillingContent.tsx
|
||||
@@ -2821,11 +2847,22 @@ msgstr "Katalánština"
|
||||
msgid "Category"
|
||||
msgstr "Kategorie"
|
||||
|
||||
#. js-lingui-id: RpYfjZ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr "CC"
|
||||
|
||||
#. js-lingui-id: Dgsw8A
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc/Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardEditorSideMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
@@ -3776,11 +3813,6 @@ msgstr "vytvořit"
|
||||
msgid "Create"
|
||||
msgstr "Vytvořit"
|
||||
|
||||
#. js-lingui-id: 5XhrY3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create & Develop"
|
||||
msgstr "Vytvořit a vyvíjet"
|
||||
|
||||
#. js-lingui-id: 8aATyU
|
||||
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
|
||||
msgid "Create a dashboard"
|
||||
@@ -3821,6 +3853,11 @@ msgstr "Vytvořte workflow a vraťte se zde pro zobrazení jeho verzí"
|
||||
msgid "Create a workspace"
|
||||
msgstr "Vytvořte pracovní prostor"
|
||||
|
||||
#. js-lingui-id: /WlFSf
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create an application"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8ZjIgO
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
|
||||
msgid "Create and configure AI agents"
|
||||
@@ -4794,6 +4831,7 @@ msgstr "Popište, co chcete, aby AI dělalo..."
|
||||
|
||||
#. js-lingui-id: Nu4oKW
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldEdit.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/ai/SettingsToolDetail.tsx
|
||||
@@ -5339,16 +5377,16 @@ msgstr "E-mail musí být platný"
|
||||
msgid "Email or domain is already in blocklist"
|
||||
msgstr "E-mail nebo doména již je v seznamu blokovaných"
|
||||
|
||||
#. js-lingui-id: Xl929X
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Email sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: jvneza
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Email support"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +VjrH/
|
||||
#: src/modules/side-panel/hooks/useOpenEmailThreadInSidePanel.ts
|
||||
msgid "Email Thread"
|
||||
msgstr "E-mailové vlákno"
|
||||
|
||||
#. js-lingui-id: LimKOG
|
||||
#: src/pages/settings/security/SettingsSecurityApprovedAccessDomain.tsx
|
||||
msgid "Email verification"
|
||||
@@ -6433,6 +6471,12 @@ msgstr ""
|
||||
msgid "Failed to save workspace instructions"
|
||||
msgstr "Nepodařilo se uložit pokyny pracovního prostoru"
|
||||
|
||||
#. js-lingui-id: Lo/GQ5
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Failed to send email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: aj02T8
|
||||
#: src/modules/settings/admin-panel/health-status/maintenance-mode/components/SettingsAdminMaintenanceMode.tsx
|
||||
msgid "Failed to set maintenance mode."
|
||||
@@ -6924,6 +6968,11 @@ msgstr "Kredity ze zkušební verze byly vyčerpány. Předplaťte si nyní, aby
|
||||
msgid "French"
|
||||
msgstr "Francouzština"
|
||||
|
||||
#. js-lingui-id: ejVYRQ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qR8gT9
|
||||
#: src/modules/workflow/workflow-trigger/utils/cron-to-human/descriptors/getDayOfWeekDescription.ts
|
||||
msgid "from {startDay} to {endDay}"
|
||||
@@ -8571,7 +8620,7 @@ msgid "Loading skills..."
|
||||
msgstr "Načítání dovedností..."
|
||||
|
||||
#. js-lingui-id: 7YK6ap
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadWidget.tsx
|
||||
msgid "Loading thread"
|
||||
msgstr "Načítání vlákna"
|
||||
|
||||
@@ -9223,10 +9272,10 @@ msgstr "mySkill"
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/data-model/constants/SettingsObjectTableMetadata.ts
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationGeneralTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTable.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
@@ -9392,6 +9441,11 @@ msgstr "Nový chat"
|
||||
msgid "New conversation"
|
||||
msgstr "Nová konverzace"
|
||||
|
||||
#. js-lingui-id: 3RwJHq
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
msgid "New Email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: wqoYqp
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
@@ -9590,6 +9644,11 @@ msgstr "Žádné API klíče nejsou k dispozici"
|
||||
msgid "No API keys match your search"
|
||||
msgstr "Žádné API klíče neodpovídají vašemu vyhledávání"
|
||||
|
||||
#. js-lingui-id: /VRg8Z
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "No application found"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: rxBnh8
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
msgid "No applications available"
|
||||
@@ -10018,6 +10077,7 @@ msgid "No variables found"
|
||||
msgstr "Žádné proměnné nenalezeny"
|
||||
|
||||
#. js-lingui-id: OCektF
|
||||
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationDetailEnvironmentVariablesTable.tsx
|
||||
msgid "No variables to set for this application"
|
||||
msgstr ""
|
||||
@@ -10133,6 +10193,11 @@ msgstr "nyní"
|
||||
msgid "Npm package"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: p7abaY
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "NPM packages"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: VVexZo
|
||||
#: src/modules/advanced-text-editor/extensions/slash-command/DefaultSlashCommands.ts
|
||||
msgid "number"
|
||||
@@ -11357,10 +11422,11 @@ msgstr ""
|
||||
msgid "Read your profile"
|
||||
msgstr "Čtení vašeho profilu"
|
||||
|
||||
#. js-lingui-id: tCXcL7
|
||||
#. js-lingui-id: 6pSHJ5
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "Jen pro čtení — spravováno Twenty"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
@@ -11382,6 +11448,11 @@ msgstr "Obdržíte e-mail s odkazem na aktualizaci hesla"
|
||||
msgid "Recent Events (oldest → newest)"
|
||||
msgstr "Nedávné události (od nejstarších → k nejnovějším)"
|
||||
|
||||
#. js-lingui-id: yPrbsy
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Recipients"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: b2+5uV
|
||||
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
|
||||
msgid "Recommended Models"
|
||||
@@ -11733,7 +11804,8 @@ msgid "Reorder options"
|
||||
msgstr "Změnit pořadí možností"
|
||||
|
||||
#. js-lingui-id: ImOQa9
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailThreadBottomBar.tsx
|
||||
msgid "Reply"
|
||||
msgstr "Odpovědět"
|
||||
@@ -11743,6 +11815,11 @@ msgstr "Odpovědět"
|
||||
msgid "Reply to all"
|
||||
msgstr "Odpovědět všem"
|
||||
|
||||
#. js-lingui-id: fiPYZo
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Reply..."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tbmZmI
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Report and issue"
|
||||
@@ -11768,6 +11845,7 @@ msgstr "Znovu odeslat e-mail"
|
||||
#. js-lingui-id: OfhWJH
|
||||
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
|
||||
#: src/modules/views/components/ViewBarDetails.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "Reset"
|
||||
msgstr "Obnovit"
|
||||
|
||||
@@ -11788,6 +11866,8 @@ msgid "Reset to"
|
||||
msgstr "Obnovit na"
|
||||
|
||||
#. js-lingui-id: L+rMC9
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/command-menu-item/server-items/edit/components/SidePanelCommandMenuItemEditPage.tsx
|
||||
msgid "Reset to default"
|
||||
@@ -12086,11 +12166,6 @@ msgstr "Uložit"
|
||||
msgid "Save as new view"
|
||||
msgstr "Uložit jako nové zobrazení"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
msgstr "Vytvořte kostru nové aplikace a poté pomocí CLI vyvíjejte, publikujte a distribuujte"
|
||||
|
||||
#. js-lingui-id: gmB6oO
|
||||
#: src/modules/workflow/workflow-trigger/components/CronExpressionHelper.tsx
|
||||
msgid "Schedule"
|
||||
@@ -12232,6 +12307,7 @@ msgid "Search an agent..."
|
||||
msgstr "Hledat agenta..."
|
||||
|
||||
#. js-lingui-id: fGTI3o
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
msgid "Search an application"
|
||||
@@ -12686,6 +12762,13 @@ msgstr "Vyberte, které modely se budou zobrazovat jako doporučené ve výběru
|
||||
msgid "Select your preferred language"
|
||||
msgstr "Vyberte preferovaný jazyk"
|
||||
|
||||
#. js-lingui-id: JlFcis
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mjK8F3
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
msgid "Send an invite email to your team"
|
||||
@@ -13401,6 +13484,8 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Předmět"
|
||||
|
||||
@@ -13641,11 +13726,6 @@ msgstr ""
|
||||
msgid "System Prompt"
|
||||
msgstr "Systémová výzva"
|
||||
|
||||
#. js-lingui-id: BXGTWI
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "System Prompt ({totalTokenCount})"
|
||||
msgstr "Systémový prompt ({totalTokenCount})"
|
||||
|
||||
#. js-lingui-id: k+7QWO
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
|
||||
msgid "System relations"
|
||||
@@ -14132,6 +14212,11 @@ msgstr ""
|
||||
msgid "This week"
|
||||
msgstr "Tento týden"
|
||||
|
||||
#. js-lingui-id: VbVocX
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4VeOo
|
||||
#: src/modules/settings/billing/hooks/useBillingWording.ts
|
||||
msgid "This will cancel the scheduled interval change and keep your current billing interval ({currentIntervalLabel})."
|
||||
@@ -14247,6 +14332,7 @@ msgstr "název"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "To"
|
||||
msgstr "Komu"
|
||||
|
||||
@@ -14548,7 +14634,6 @@ msgstr "Nastavení dvoufaktorového ověřování bylo úspěšně dokončeno!"
|
||||
|
||||
#. js-lingui-id: +zy2Nq
|
||||
#: src/pages/settings/data-model/SettingsObjectIndexTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
#: src/pages/settings/ai/components/SettingsToolParameterTable.tsx
|
||||
@@ -14571,6 +14656,11 @@ msgstr "Zadejte '/' pro příkazy, '@' pro zmínky"
|
||||
msgid "Type anything..."
|
||||
msgstr "Napište cokoli..."
|
||||
|
||||
#. js-lingui-id: LaEX5I
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Type something or press \"/\" to see commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UhqKcC
|
||||
#: src/modules/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemRecordSubPage.tsx
|
||||
msgid "Type to search records"
|
||||
@@ -14898,6 +14988,11 @@ msgstr "Přejděte na vyšší verzi pro přístup"
|
||||
msgid "Upgrade to Enterprise to access audit logs."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: D+7y/3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "Upgrade to Enterprise to share private applications."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +Gi3x1
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationVersionContainer.tsx
|
||||
@@ -15334,7 +15429,6 @@ msgstr "Zobrazit protokoly"
|
||||
|
||||
#. js-lingui-id: 7PrSCy
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View marketplace page"
|
||||
msgstr "Zobrazit stránku na Marketplace"
|
||||
|
||||
@@ -15348,6 +15442,11 @@ msgstr ""
|
||||
msgid "View Previous AI Chats"
|
||||
msgstr "Zobrazit předchozí AI diskuse"
|
||||
|
||||
#. js-lingui-id: NnJpTN
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View private application page"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: hAAsm/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx
|
||||
msgid "View role"
|
||||
@@ -15942,6 +16041,11 @@ msgstr "Již patříte do tohoto workspace"
|
||||
msgid "You are not allowed to create records for this object"
|
||||
msgstr "Nemáte povoleno vytvářet záznamy pro tento objekt"
|
||||
|
||||
#. js-lingui-id: iibZbD
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "You can either create a private app or share it to others"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: CNAoaw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/logic-function-action/components/WorkflowEditActionLogicFunction.tsx
|
||||
msgid "You can see the function logic in your application settings."
|
||||
@@ -16017,10 +16121,10 @@ msgstr "Váš účet byl aktivován."
|
||||
msgid "Your app version is out of date. Please refresh the page."
|
||||
msgstr "Verze vaší aplikace je zastaralá. Aktualizujte, prosím, stránku."
|
||||
|
||||
#. js-lingui-id: oNUh7z
|
||||
#. js-lingui-id: 9pWhO+
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Your Apps"
|
||||
msgstr "Vaše aplikace"
|
||||
msgid "Your apps"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +5YqGH
|
||||
#: src/modules/onboarding/constants/OnboardingSyncEmailsOptions.ts
|
||||
|
||||
@@ -316,6 +316,11 @@ msgstr "{jobCount, plural, one {Dette vil permanent fjerne det fra køen. Denne
|
||||
msgid "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
msgstr "{jobCount, plural, one {Dette vil forsøge det valgte job igen. Det vil blive udført fra begyndelsen.} other {Dette vil forsøge de valgte jobs igen. De vil blive udført fra begyndelsen.}}"
|
||||
|
||||
#. js-lingui-id: Y32cMj
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadIntermediaryMessages.tsx
|
||||
msgid "{messagesLength} emails"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Koe99p
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationItemTableRow.tsx
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx
|
||||
@@ -451,11 +456,13 @@ msgstr "{workspaceMemberName} vil blive fjernet fra følgende rolle:"
|
||||
msgid "••••••••"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tD9raa
|
||||
#. js-lingui-id: SMgdEJ
|
||||
#. placeholder {0}: formatNumber(preview.estimatedTokenCount, { abbreviate: true, decimals: 1, })
|
||||
#. placeholder {0}: formatNumber( section.estimatedTokenCount, { abbreviate: true, decimals: 1, }, )
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~{0} tokens"
|
||||
msgstr "~{0} tokens"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~ {0} tokens"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Cx0xl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/delay-actions/components/WorkflowEditActionDelay.tsx
|
||||
@@ -1702,6 +1709,7 @@ msgstr "Der opstod en fejl under upload af billedet."
|
||||
#: src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
|
||||
#: src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts
|
||||
#: src/modules/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets.ts
|
||||
#: src/modules/page-layout/hooks/useResetPageLayoutWidgetToDefault.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneFieldMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts
|
||||
@@ -1984,6 +1992,11 @@ msgstr "Godkendte domæner"
|
||||
msgid "Apps"
|
||||
msgstr "Apps"
|
||||
|
||||
#. js-lingui-id: dEnE1D
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Apps made by other developers published on npm"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8HV3WN
|
||||
#: src/pages/settings/profile/appearance/components/LocalePicker.tsx
|
||||
msgid "Arabic"
|
||||
@@ -2408,6 +2421,12 @@ msgstr "Basis-URL"
|
||||
msgid "Base URL is required"
|
||||
msgstr "Basis-URL er påkrævet"
|
||||
|
||||
#. js-lingui-id: /xLNEx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
@@ -2711,9 +2730,11 @@ msgstr "Kan ikke scanne? Kopier"
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Annuller"
|
||||
|
||||
@@ -2753,6 +2774,11 @@ msgstr "Annuller planskift"
|
||||
msgid "Cancel plan switching?"
|
||||
msgstr "Annuller planskift?"
|
||||
|
||||
#. js-lingui-id: AnRu/j
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: N6gPiD
|
||||
#: src/pages/settings/enterprise/SettingsEnterprise.tsx
|
||||
#: src/modules/settings/billing/components/SettingsBillingContent.tsx
|
||||
@@ -2821,11 +2847,22 @@ msgstr "Catalansk"
|
||||
msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: RpYfjZ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Dgsw8A
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc/Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardEditorSideMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
@@ -3776,11 +3813,6 @@ msgstr "opret"
|
||||
msgid "Create"
|
||||
msgstr "Opret"
|
||||
|
||||
#. js-lingui-id: 5XhrY3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create & Develop"
|
||||
msgstr "Opret & udvikl"
|
||||
|
||||
#. js-lingui-id: 8aATyU
|
||||
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
|
||||
msgid "Create a dashboard"
|
||||
@@ -3821,6 +3853,11 @@ msgstr "Opret en arbejdsproces og vend tilbage hertil for at se dens versioner"
|
||||
msgid "Create a workspace"
|
||||
msgstr "Opret et arbejdsområde"
|
||||
|
||||
#. js-lingui-id: /WlFSf
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create an application"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8ZjIgO
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
|
||||
msgid "Create and configure AI agents"
|
||||
@@ -4794,6 +4831,7 @@ msgstr "Beskriv, hvad du vil have AI'en til at gøre..."
|
||||
|
||||
#. js-lingui-id: Nu4oKW
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldEdit.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/ai/SettingsToolDetail.tsx
|
||||
@@ -5339,16 +5377,16 @@ msgstr "E-mail skal være gyldig"
|
||||
msgid "Email or domain is already in blocklist"
|
||||
msgstr "E-mail eller domæne er allerede på blokeringslisten"
|
||||
|
||||
#. js-lingui-id: Xl929X
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Email sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: jvneza
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Email support"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +VjrH/
|
||||
#: src/modules/side-panel/hooks/useOpenEmailThreadInSidePanel.ts
|
||||
msgid "Email Thread"
|
||||
msgstr "E-mail-tråd"
|
||||
|
||||
#. js-lingui-id: LimKOG
|
||||
#: src/pages/settings/security/SettingsSecurityApprovedAccessDomain.tsx
|
||||
msgid "Email verification"
|
||||
@@ -6433,6 +6471,12 @@ msgstr ""
|
||||
msgid "Failed to save workspace instructions"
|
||||
msgstr "Kunne ikke gemme instruktioner for arbejdsområdet"
|
||||
|
||||
#. js-lingui-id: Lo/GQ5
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Failed to send email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: aj02T8
|
||||
#: src/modules/settings/admin-panel/health-status/maintenance-mode/components/SettingsAdminMaintenanceMode.tsx
|
||||
msgid "Failed to set maintenance mode."
|
||||
@@ -6924,6 +6968,11 @@ msgstr "Kreditter i den gratis prøveperiode er opbrugt. Abonner nu for at forts
|
||||
msgid "French"
|
||||
msgstr "Fransk"
|
||||
|
||||
#. js-lingui-id: ejVYRQ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qR8gT9
|
||||
#: src/modules/workflow/workflow-trigger/utils/cron-to-human/descriptors/getDayOfWeekDescription.ts
|
||||
msgid "from {startDay} to {endDay}"
|
||||
@@ -8571,7 +8620,7 @@ msgid "Loading skills..."
|
||||
msgstr "Indlæser færdigheder..."
|
||||
|
||||
#. js-lingui-id: 7YK6ap
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadWidget.tsx
|
||||
msgid "Loading thread"
|
||||
msgstr "Indlæser tråd"
|
||||
|
||||
@@ -9223,10 +9272,10 @@ msgstr "mySkill"
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/data-model/constants/SettingsObjectTableMetadata.ts
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationGeneralTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTable.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
@@ -9392,6 +9441,11 @@ msgstr "Ny chat"
|
||||
msgid "New conversation"
|
||||
msgstr "Ny samtale"
|
||||
|
||||
#. js-lingui-id: 3RwJHq
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
msgid "New Email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: wqoYqp
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
@@ -9590,6 +9644,11 @@ msgstr "Ingen API nøgler tilgængelige"
|
||||
msgid "No API keys match your search"
|
||||
msgstr "Ingen API nøgler matcher din søgning"
|
||||
|
||||
#. js-lingui-id: /VRg8Z
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "No application found"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: rxBnh8
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
msgid "No applications available"
|
||||
@@ -10018,6 +10077,7 @@ msgid "No variables found"
|
||||
msgstr "Ingen variabler fundet"
|
||||
|
||||
#. js-lingui-id: OCektF
|
||||
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationDetailEnvironmentVariablesTable.tsx
|
||||
msgid "No variables to set for this application"
|
||||
msgstr ""
|
||||
@@ -10133,6 +10193,11 @@ msgstr "nu"
|
||||
msgid "Npm package"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: p7abaY
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "NPM packages"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: VVexZo
|
||||
#: src/modules/advanced-text-editor/extensions/slash-command/DefaultSlashCommands.ts
|
||||
msgid "number"
|
||||
@@ -11357,10 +11422,11 @@ msgstr ""
|
||||
msgid "Read your profile"
|
||||
msgstr "Læs din profil"
|
||||
|
||||
#. js-lingui-id: tCXcL7
|
||||
#. js-lingui-id: 6pSHJ5
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "Skrivebeskyttet — administreret af Twenty"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
@@ -11382,6 +11448,11 @@ msgstr "Modtag en e-mail med link til opdatering af kodeord"
|
||||
msgid "Recent Events (oldest → newest)"
|
||||
msgstr "Seneste hændelser (ældste → nyeste)"
|
||||
|
||||
#. js-lingui-id: yPrbsy
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Recipients"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: b2+5uV
|
||||
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
|
||||
msgid "Recommended Models"
|
||||
@@ -11733,7 +11804,8 @@ msgid "Reorder options"
|
||||
msgstr "Omarranger valgmuligheder"
|
||||
|
||||
#. js-lingui-id: ImOQa9
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailThreadBottomBar.tsx
|
||||
msgid "Reply"
|
||||
msgstr "Svar"
|
||||
@@ -11743,6 +11815,11 @@ msgstr "Svar"
|
||||
msgid "Reply to all"
|
||||
msgstr "Svar til alle"
|
||||
|
||||
#. js-lingui-id: fiPYZo
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Reply..."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tbmZmI
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Report and issue"
|
||||
@@ -11768,6 +11845,7 @@ msgstr "Send e-mail igen"
|
||||
#. js-lingui-id: OfhWJH
|
||||
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
|
||||
#: src/modules/views/components/ViewBarDetails.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "Reset"
|
||||
msgstr "Nulstil"
|
||||
|
||||
@@ -11788,6 +11866,8 @@ msgid "Reset to"
|
||||
msgstr "Nulstil til"
|
||||
|
||||
#. js-lingui-id: L+rMC9
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/command-menu-item/server-items/edit/components/SidePanelCommandMenuItemEditPage.tsx
|
||||
msgid "Reset to default"
|
||||
@@ -12086,11 +12166,6 @@ msgstr "Gem"
|
||||
msgid "Save as new view"
|
||||
msgstr "Gem som ny visning"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
msgstr "Generér et skelet til en ny app, og brug derefter CLI til at udvikle, udgive og distribuere"
|
||||
|
||||
#. js-lingui-id: gmB6oO
|
||||
#: src/modules/workflow/workflow-trigger/components/CronExpressionHelper.tsx
|
||||
msgid "Schedule"
|
||||
@@ -12232,6 +12307,7 @@ msgid "Search an agent..."
|
||||
msgstr "Søg efter en agent..."
|
||||
|
||||
#. js-lingui-id: fGTI3o
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
msgid "Search an application"
|
||||
@@ -12686,6 +12762,13 @@ msgstr "Vælg hvilke modeller der vises som anbefalede i arbejdsområdets modelv
|
||||
msgid "Select your preferred language"
|
||||
msgstr "Vælg dit foretrukne sprog"
|
||||
|
||||
#. js-lingui-id: JlFcis
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mjK8F3
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
msgid "Send an invite email to your team"
|
||||
@@ -13401,6 +13484,8 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Emne"
|
||||
|
||||
@@ -13641,11 +13726,6 @@ msgstr ""
|
||||
msgid "System Prompt"
|
||||
msgstr "Systemprompt"
|
||||
|
||||
#. js-lingui-id: BXGTWI
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "System Prompt ({totalTokenCount})"
|
||||
msgstr "Systemprompt ({totalTokenCount})"
|
||||
|
||||
#. js-lingui-id: k+7QWO
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
|
||||
msgid "System relations"
|
||||
@@ -14134,6 +14214,11 @@ msgstr ""
|
||||
msgid "This week"
|
||||
msgstr "Denne uge"
|
||||
|
||||
#. js-lingui-id: VbVocX
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4VeOo
|
||||
#: src/modules/settings/billing/hooks/useBillingWording.ts
|
||||
msgid "This will cancel the scheduled interval change and keep your current billing interval ({currentIntervalLabel})."
|
||||
@@ -14249,6 +14334,7 @@ msgstr "titel"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "To"
|
||||
msgstr ""
|
||||
|
||||
@@ -14550,7 +14636,6 @@ msgstr "Opsætning af to-faktor godkendelse blev gennemført med succes!"
|
||||
|
||||
#. js-lingui-id: +zy2Nq
|
||||
#: src/pages/settings/data-model/SettingsObjectIndexTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
#: src/pages/settings/ai/components/SettingsToolParameterTable.tsx
|
||||
@@ -14573,6 +14658,11 @@ msgstr "Skriv '/' for kommandoer, '@' for omtaler"
|
||||
msgid "Type anything..."
|
||||
msgstr "Skriv noget..."
|
||||
|
||||
#. js-lingui-id: LaEX5I
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Type something or press \"/\" to see commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UhqKcC
|
||||
#: src/modules/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemRecordSubPage.tsx
|
||||
msgid "Type to search records"
|
||||
@@ -14900,6 +14990,11 @@ msgstr "Opgrader for at få adgang"
|
||||
msgid "Upgrade to Enterprise to access audit logs."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: D+7y/3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "Upgrade to Enterprise to share private applications."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +Gi3x1
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationVersionContainer.tsx
|
||||
@@ -15336,7 +15431,6 @@ msgstr "Vis logge"
|
||||
|
||||
#. js-lingui-id: 7PrSCy
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View marketplace page"
|
||||
msgstr "Se side på markedspladsen"
|
||||
|
||||
@@ -15350,6 +15444,11 @@ msgstr ""
|
||||
msgid "View Previous AI Chats"
|
||||
msgstr "Se tidligere AI-chats"
|
||||
|
||||
#. js-lingui-id: NnJpTN
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View private application page"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: hAAsm/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx
|
||||
msgid "View role"
|
||||
@@ -15944,6 +16043,11 @@ msgstr "Du er allerede medlem af dette arbejdsområde"
|
||||
msgid "You are not allowed to create records for this object"
|
||||
msgstr "Du har ikke tilladelse til at oprette poster i dette objekt"
|
||||
|
||||
#. js-lingui-id: iibZbD
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "You can either create a private app or share it to others"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: CNAoaw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/logic-function-action/components/WorkflowEditActionLogicFunction.tsx
|
||||
msgid "You can see the function logic in your application settings."
|
||||
@@ -16019,10 +16123,10 @@ msgstr "Din konto er blevet aktiveret."
|
||||
msgid "Your app version is out of date. Please refresh the page."
|
||||
msgstr "Din app-version er forældet. Opdater venligst siden."
|
||||
|
||||
#. js-lingui-id: oNUh7z
|
||||
#. js-lingui-id: 9pWhO+
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Your Apps"
|
||||
msgstr "Dine apps"
|
||||
msgid "Your apps"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +5YqGH
|
||||
#: src/modules/onboarding/constants/OnboardingSyncEmailsOptions.ts
|
||||
|
||||
@@ -316,6 +316,11 @@ msgstr "{jobCount, plural, one {Dies wird es dauerhaft von der Warteschlange ent
|
||||
msgid "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
msgstr "{jobCount, plural, one {Dies wird den ausgewählten Auftrag neu ausführen. Er wird von Anfang an neu ausgeführt.} other {Dies wird die ausgewählten Aufträge neu ausführen. Sie werden von Anfang an neu ausgeführt.}}"
|
||||
|
||||
#. js-lingui-id: Y32cMj
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadIntermediaryMessages.tsx
|
||||
msgid "{messagesLength} emails"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Koe99p
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationItemTableRow.tsx
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx
|
||||
@@ -451,11 +456,13 @@ msgstr "{workspaceMemberName} wird von folgender Rolle abgezogen:"
|
||||
msgid "••••••••"
|
||||
msgstr "••••••••"
|
||||
|
||||
#. js-lingui-id: tD9raa
|
||||
#. js-lingui-id: SMgdEJ
|
||||
#. placeholder {0}: formatNumber(preview.estimatedTokenCount, { abbreviate: true, decimals: 1, })
|
||||
#. placeholder {0}: formatNumber( section.estimatedTokenCount, { abbreviate: true, decimals: 1, }, )
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~{0} tokens"
|
||||
msgstr "~{0} Token"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~ {0} tokens"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Cx0xl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/delay-actions/components/WorkflowEditActionDelay.tsx
|
||||
@@ -1702,6 +1709,7 @@ msgstr "Beim Hochladen des Bildes ist ein Fehler aufgetreten."
|
||||
#: src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
|
||||
#: src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts
|
||||
#: src/modules/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets.ts
|
||||
#: src/modules/page-layout/hooks/useResetPageLayoutWidgetToDefault.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneFieldMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts
|
||||
@@ -1984,6 +1992,11 @@ msgstr "Genehmigte Domänen"
|
||||
msgid "Apps"
|
||||
msgstr "Apps"
|
||||
|
||||
#. js-lingui-id: dEnE1D
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Apps made by other developers published on npm"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8HV3WN
|
||||
#: src/pages/settings/profile/appearance/components/LocalePicker.tsx
|
||||
msgid "Arabic"
|
||||
@@ -2408,6 +2421,12 @@ msgstr "Basis-URL"
|
||||
msgid "Base URL is required"
|
||||
msgstr "Basis-URL ist erforderlich"
|
||||
|
||||
#. js-lingui-id: /xLNEx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
@@ -2711,9 +2730,11 @@ msgstr "Kann nicht gescannt werden? Kopieren Sie das"
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
@@ -2753,6 +2774,11 @@ msgstr "Tarifwechsel abbrechen"
|
||||
msgid "Cancel plan switching?"
|
||||
msgstr "Tarifwechsel abbrechen?"
|
||||
|
||||
#. js-lingui-id: AnRu/j
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: N6gPiD
|
||||
#: src/pages/settings/enterprise/SettingsEnterprise.tsx
|
||||
#: src/modules/settings/billing/components/SettingsBillingContent.tsx
|
||||
@@ -2821,11 +2847,22 @@ msgstr "Katalanisch"
|
||||
msgid "Category"
|
||||
msgstr "Kategorie"
|
||||
|
||||
#. js-lingui-id: RpYfjZ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr "CC"
|
||||
|
||||
#. js-lingui-id: Dgsw8A
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc/Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardEditorSideMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
@@ -3776,11 +3813,6 @@ msgstr "erstellen"
|
||||
msgid "Create"
|
||||
msgstr "Erstellen"
|
||||
|
||||
#. js-lingui-id: 5XhrY3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create & Develop"
|
||||
msgstr "Erstellen & Entwickeln"
|
||||
|
||||
#. js-lingui-id: 8aATyU
|
||||
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
|
||||
msgid "Create a dashboard"
|
||||
@@ -3821,6 +3853,11 @@ msgstr "Erstellen Sie einen Workflow und kehren Sie hierher zurück, um die Vers
|
||||
msgid "Create a workspace"
|
||||
msgstr "Arbeitsbereich erstellen"
|
||||
|
||||
#. js-lingui-id: /WlFSf
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create an application"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8ZjIgO
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
|
||||
msgid "Create and configure AI agents"
|
||||
@@ -4794,6 +4831,7 @@ msgstr "Beschreiben Sie, was die KI tun soll..."
|
||||
|
||||
#. js-lingui-id: Nu4oKW
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldEdit.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/ai/SettingsToolDetail.tsx
|
||||
@@ -5339,16 +5377,16 @@ msgstr "E-Mail muss gültig sein"
|
||||
msgid "Email or domain is already in blocklist"
|
||||
msgstr "E-Mail oder Domain ist bereits in der Blockliste"
|
||||
|
||||
#. js-lingui-id: Xl929X
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Email sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: jvneza
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Email support"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +VjrH/
|
||||
#: src/modules/side-panel/hooks/useOpenEmailThreadInSidePanel.ts
|
||||
msgid "Email Thread"
|
||||
msgstr "E-Mail-Thread"
|
||||
|
||||
#. js-lingui-id: LimKOG
|
||||
#: src/pages/settings/security/SettingsSecurityApprovedAccessDomain.tsx
|
||||
msgid "Email verification"
|
||||
@@ -6433,6 +6471,12 @@ msgstr "Fehler beim Speichern der Rollenberechtigungen: {errorMessage}"
|
||||
msgid "Failed to save workspace instructions"
|
||||
msgstr "Fehler beim Speichern der Arbeitsbereichsanweisungen"
|
||||
|
||||
#. js-lingui-id: Lo/GQ5
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Failed to send email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: aj02T8
|
||||
#: src/modules/settings/admin-panel/health-status/maintenance-mode/components/SettingsAdminMaintenanceMode.tsx
|
||||
msgid "Failed to set maintenance mode."
|
||||
@@ -6924,6 +6968,11 @@ msgstr "Kostenloses Testguthaben aufgebraucht. Abonnieren Sie jetzt, um KI-Funkt
|
||||
msgid "French"
|
||||
msgstr "Französisch"
|
||||
|
||||
#. js-lingui-id: ejVYRQ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qR8gT9
|
||||
#: src/modules/workflow/workflow-trigger/utils/cron-to-human/descriptors/getDayOfWeekDescription.ts
|
||||
msgid "from {startDay} to {endDay}"
|
||||
@@ -8571,7 +8620,7 @@ msgid "Loading skills..."
|
||||
msgstr "Skills werden geladen..."
|
||||
|
||||
#. js-lingui-id: 7YK6ap
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadWidget.tsx
|
||||
msgid "Loading thread"
|
||||
msgstr "Thread wird geladen"
|
||||
|
||||
@@ -9223,10 +9272,10 @@ msgstr "mySkill"
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/data-model/constants/SettingsObjectTableMetadata.ts
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationGeneralTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTable.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
@@ -9392,6 +9441,11 @@ msgstr "Neuer Chat"
|
||||
msgid "New conversation"
|
||||
msgstr "Neue Unterhaltung"
|
||||
|
||||
#. js-lingui-id: 3RwJHq
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
msgid "New Email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: wqoYqp
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
@@ -9590,6 +9644,11 @@ msgstr "Keine API-Schlüssel verfügbar"
|
||||
msgid "No API keys match your search"
|
||||
msgstr "Keine API-Schlüssel passen zu Ihrer Suche"
|
||||
|
||||
#. js-lingui-id: /VRg8Z
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "No application found"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: rxBnh8
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
msgid "No applications available"
|
||||
@@ -10018,6 +10077,7 @@ msgid "No variables found"
|
||||
msgstr "Keine Variablen gefunden"
|
||||
|
||||
#. js-lingui-id: OCektF
|
||||
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationDetailEnvironmentVariablesTable.tsx
|
||||
msgid "No variables to set for this application"
|
||||
msgstr ""
|
||||
@@ -10133,6 +10193,11 @@ msgstr "jetzt"
|
||||
msgid "Npm package"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: p7abaY
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "NPM packages"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: VVexZo
|
||||
#: src/modules/advanced-text-editor/extensions/slash-command/DefaultSlashCommands.ts
|
||||
msgid "number"
|
||||
@@ -11357,10 +11422,11 @@ msgstr ""
|
||||
msgid "Read your profile"
|
||||
msgstr "Ihr Profil lesen"
|
||||
|
||||
#. js-lingui-id: tCXcL7
|
||||
#. js-lingui-id: 6pSHJ5
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "Schreibgeschützt — verwaltet von Twenty"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
@@ -11382,6 +11448,11 @@ msgstr "Erhalten Sie eine E-Mail mit einem Link zur Passwortaktualisierung"
|
||||
msgid "Recent Events (oldest → newest)"
|
||||
msgstr "Aktuelle Ereignisse (älteste → neueste)"
|
||||
|
||||
#. js-lingui-id: yPrbsy
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Recipients"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: b2+5uV
|
||||
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
|
||||
msgid "Recommended Models"
|
||||
@@ -11733,7 +11804,8 @@ msgid "Reorder options"
|
||||
msgstr "Optionen neu anordnen"
|
||||
|
||||
#. js-lingui-id: ImOQa9
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailThreadBottomBar.tsx
|
||||
msgid "Reply"
|
||||
msgstr "Antworten"
|
||||
@@ -11743,6 +11815,11 @@ msgstr "Antworten"
|
||||
msgid "Reply to all"
|
||||
msgstr "Allen antworten"
|
||||
|
||||
#. js-lingui-id: fiPYZo
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Reply..."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tbmZmI
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Report and issue"
|
||||
@@ -11768,6 +11845,7 @@ msgstr "E-Mail erneut senden"
|
||||
#. js-lingui-id: OfhWJH
|
||||
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
|
||||
#: src/modules/views/components/ViewBarDetails.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "Reset"
|
||||
msgstr "Zurücksetzen"
|
||||
|
||||
@@ -11788,6 +11866,8 @@ msgid "Reset to"
|
||||
msgstr "Zurücksetzen auf"
|
||||
|
||||
#. js-lingui-id: L+rMC9
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/command-menu-item/server-items/edit/components/SidePanelCommandMenuItemEditPage.tsx
|
||||
msgid "Reset to default"
|
||||
@@ -12086,11 +12166,6 @@ msgstr "Speichern"
|
||||
msgid "Save as new view"
|
||||
msgstr "Als neue Ansicht speichern"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
msgstr "Ein neues App-Gerüst erstellen und anschließend die CLI zum Entwickeln, Veröffentlichen und Verteilen verwenden"
|
||||
|
||||
#. js-lingui-id: gmB6oO
|
||||
#: src/modules/workflow/workflow-trigger/components/CronExpressionHelper.tsx
|
||||
msgid "Schedule"
|
||||
@@ -12232,6 +12307,7 @@ msgid "Search an agent..."
|
||||
msgstr "Einen Agenten suchen..."
|
||||
|
||||
#. js-lingui-id: fGTI3o
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
msgid "Search an application"
|
||||
@@ -12686,6 +12762,13 @@ msgstr "Wählen Sie aus, welche Modelle im Modellauswahlfeld des Arbeitsbereichs
|
||||
msgid "Select your preferred language"
|
||||
msgstr "Bevorzugte Sprache auswählen"
|
||||
|
||||
#. js-lingui-id: JlFcis
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mjK8F3
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
msgid "Send an invite email to your team"
|
||||
@@ -13401,6 +13484,8 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Betreff"
|
||||
|
||||
@@ -13641,11 +13726,6 @@ msgstr ""
|
||||
msgid "System Prompt"
|
||||
msgstr "Systemaufforderung"
|
||||
|
||||
#. js-lingui-id: BXGTWI
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "System Prompt ({totalTokenCount})"
|
||||
msgstr "Systemprompt ({totalTokenCount})"
|
||||
|
||||
#. js-lingui-id: k+7QWO
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
|
||||
msgid "System relations"
|
||||
@@ -14132,6 +14212,11 @@ msgstr ""
|
||||
msgid "This week"
|
||||
msgstr "Diese Woche"
|
||||
|
||||
#. js-lingui-id: VbVocX
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4VeOo
|
||||
#: src/modules/settings/billing/hooks/useBillingWording.ts
|
||||
msgid "This will cancel the scheduled interval change and keep your current billing interval ({currentIntervalLabel})."
|
||||
@@ -14247,6 +14332,7 @@ msgstr "titel"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "To"
|
||||
msgstr "An"
|
||||
|
||||
@@ -14548,7 +14634,6 @@ msgstr "Einrichtung der Zwei-Faktor-Authentifizierung erfolgreich abgeschlossen!
|
||||
|
||||
#. js-lingui-id: +zy2Nq
|
||||
#: src/pages/settings/data-model/SettingsObjectIndexTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
#: src/pages/settings/ai/components/SettingsToolParameterTable.tsx
|
||||
@@ -14571,6 +14656,11 @@ msgstr "Geben Sie '/' für Befehle, '@' für Erwähnungen ein"
|
||||
msgid "Type anything..."
|
||||
msgstr "Geben Sie irgendetwas ein..."
|
||||
|
||||
#. js-lingui-id: LaEX5I
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Type something or press \"/\" to see commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UhqKcC
|
||||
#: src/modules/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemRecordSubPage.tsx
|
||||
msgid "Type to search records"
|
||||
@@ -14898,6 +14988,11 @@ msgstr "Upgrade, um Zugriff zu erhalten"
|
||||
msgid "Upgrade to Enterprise to access audit logs."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: D+7y/3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "Upgrade to Enterprise to share private applications."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +Gi3x1
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationVersionContainer.tsx
|
||||
@@ -15334,7 +15429,6 @@ msgstr "Protokolle anzeigen"
|
||||
|
||||
#. js-lingui-id: 7PrSCy
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View marketplace page"
|
||||
msgstr "Marktplatz-Seite anzeigen"
|
||||
|
||||
@@ -15348,6 +15442,11 @@ msgstr ""
|
||||
msgid "View Previous AI Chats"
|
||||
msgstr "Vorherige KI-Chats anzeigen"
|
||||
|
||||
#. js-lingui-id: NnJpTN
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View private application page"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: hAAsm/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx
|
||||
msgid "View role"
|
||||
@@ -15942,6 +16041,11 @@ msgstr "Sie gehören bereits zu diesem Arbeitsplatz"
|
||||
msgid "You are not allowed to create records for this object"
|
||||
msgstr "Sie dürfen keine Datensätze für dieses Objekt erstellen"
|
||||
|
||||
#. js-lingui-id: iibZbD
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "You can either create a private app or share it to others"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: CNAoaw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/logic-function-action/components/WorkflowEditActionLogicFunction.tsx
|
||||
msgid "You can see the function logic in your application settings."
|
||||
@@ -16017,10 +16121,10 @@ msgstr "Ihr Konto wurde aktiviert."
|
||||
msgid "Your app version is out of date. Please refresh the page."
|
||||
msgstr "Ihre App-Version ist veraltet. Bitte aktualisieren Sie die Seite."
|
||||
|
||||
#. js-lingui-id: oNUh7z
|
||||
#. js-lingui-id: 9pWhO+
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Your Apps"
|
||||
msgstr "Ihre Apps"
|
||||
msgid "Your apps"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +5YqGH
|
||||
#: src/modules/onboarding/constants/OnboardingSyncEmailsOptions.ts
|
||||
|
||||
@@ -316,6 +316,11 @@ msgstr "{jobCount, plural, one {Αυτό θα την αφαιρέσει ορισ
|
||||
msgid "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
msgstr "{jobCount, plural, one {Αυτό θα επαναλάβει την επιλεγμένη εργασία. Θα εκτελεστεί από την αρχή.} other {Αυτό θα επαναλάβει τις επιλεγμένες εργασίες. Θα εκτελεστούν από την αρχή.}}"
|
||||
|
||||
#. js-lingui-id: Y32cMj
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadIntermediaryMessages.tsx
|
||||
msgid "{messagesLength} emails"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Koe99p
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationItemTableRow.tsx
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx
|
||||
@@ -451,11 +456,13 @@ msgstr "Ο χρήστης {workspaceMemberName} θα αποδεσμευτεί α
|
||||
msgid "••••••••"
|
||||
msgstr "••••••••"
|
||||
|
||||
#. js-lingui-id: tD9raa
|
||||
#. js-lingui-id: SMgdEJ
|
||||
#. placeholder {0}: formatNumber(preview.estimatedTokenCount, { abbreviate: true, decimals: 1, })
|
||||
#. placeholder {0}: formatNumber( section.estimatedTokenCount, { abbreviate: true, decimals: 1, }, )
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~{0} tokens"
|
||||
msgstr "~{0} διακριτικά"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~ {0} tokens"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Cx0xl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/delay-actions/components/WorkflowEditActionDelay.tsx
|
||||
@@ -1702,6 +1709,7 @@ msgstr "Παρουσιάστηκε σφάλμα κατά τη μεταφόρτω
|
||||
#: src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
|
||||
#: src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts
|
||||
#: src/modules/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets.ts
|
||||
#: src/modules/page-layout/hooks/useResetPageLayoutWidgetToDefault.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneFieldMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts
|
||||
@@ -1984,6 +1992,11 @@ msgstr "Εγκεκριμένοι Τομείς"
|
||||
msgid "Apps"
|
||||
msgstr "Εφαρμογές"
|
||||
|
||||
#. js-lingui-id: dEnE1D
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Apps made by other developers published on npm"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8HV3WN
|
||||
#: src/pages/settings/profile/appearance/components/LocalePicker.tsx
|
||||
msgid "Arabic"
|
||||
@@ -2408,6 +2421,12 @@ msgstr "Βασικό URL"
|
||||
msgid "Base URL is required"
|
||||
msgstr "Απαιτείται το βασικό URL"
|
||||
|
||||
#. js-lingui-id: /xLNEx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
@@ -2711,9 +2730,11 @@ msgstr "Δεν μπορείτε να σαρώσετε; Αντιγράψτε το
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Ακύρωση"
|
||||
|
||||
@@ -2753,6 +2774,11 @@ msgstr "Ακύρωση αλλαγής προγράμματος"
|
||||
msgid "Cancel plan switching?"
|
||||
msgstr "Ακύρωση αλλαγής προγράμματος;"
|
||||
|
||||
#. js-lingui-id: AnRu/j
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: N6gPiD
|
||||
#: src/pages/settings/enterprise/SettingsEnterprise.tsx
|
||||
#: src/modules/settings/billing/components/SettingsBillingContent.tsx
|
||||
@@ -2821,11 +2847,22 @@ msgstr "Καταλανικά"
|
||||
msgid "Category"
|
||||
msgstr "Κατηγορία"
|
||||
|
||||
#. js-lingui-id: RpYfjZ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr "Κοινοποίηση"
|
||||
|
||||
#. js-lingui-id: Dgsw8A
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc/Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardEditorSideMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
@@ -3776,11 +3813,6 @@ msgstr "δημιουργία"
|
||||
msgid "Create"
|
||||
msgstr "Δημιουργία"
|
||||
|
||||
#. js-lingui-id: 5XhrY3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create & Develop"
|
||||
msgstr "Δημιουργία & Ανάπτυξη"
|
||||
|
||||
#. js-lingui-id: 8aATyU
|
||||
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
|
||||
msgid "Create a dashboard"
|
||||
@@ -3821,6 +3853,11 @@ msgstr "Δημιουργήστε ένα workflow και επιστρέψτε ε
|
||||
msgid "Create a workspace"
|
||||
msgstr "Δημιουργία Χώρου Εργασίας"
|
||||
|
||||
#. js-lingui-id: /WlFSf
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create an application"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8ZjIgO
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
|
||||
msgid "Create and configure AI agents"
|
||||
@@ -4794,6 +4831,7 @@ msgstr "Περιγράψτε τι θέλετε να κάνει το AI..."
|
||||
|
||||
#. js-lingui-id: Nu4oKW
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldEdit.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/ai/SettingsToolDetail.tsx
|
||||
@@ -5339,16 +5377,16 @@ msgstr "Το email πρέπει να είναι έγκυρο"
|
||||
msgid "Email or domain is already in blocklist"
|
||||
msgstr "Το email ή ο τομέας βρίσκεται ήδη στη λίστα απόκλεισης"
|
||||
|
||||
#. js-lingui-id: Xl929X
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Email sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: jvneza
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Email support"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +VjrH/
|
||||
#: src/modules/side-panel/hooks/useOpenEmailThreadInSidePanel.ts
|
||||
msgid "Email Thread"
|
||||
msgstr "Νήμα email"
|
||||
|
||||
#. js-lingui-id: LimKOG
|
||||
#: src/pages/settings/security/SettingsSecurityApprovedAccessDomain.tsx
|
||||
msgid "Email verification"
|
||||
@@ -6433,6 +6471,12 @@ msgstr ""
|
||||
msgid "Failed to save workspace instructions"
|
||||
msgstr "Αποτυχία αποθήκευσης των οδηγιών του χώρου εργασίας"
|
||||
|
||||
#. js-lingui-id: Lo/GQ5
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Failed to send email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: aj02T8
|
||||
#: src/modules/settings/admin-panel/health-status/maintenance-mode/components/SettingsAdminMaintenanceMode.tsx
|
||||
msgid "Failed to set maintenance mode."
|
||||
@@ -6924,6 +6968,11 @@ msgstr "Οι πιστώσεις της δωρεάν δοκιμής εξαντλ
|
||||
msgid "French"
|
||||
msgstr "Γαλλικά"
|
||||
|
||||
#. js-lingui-id: ejVYRQ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qR8gT9
|
||||
#: src/modules/workflow/workflow-trigger/utils/cron-to-human/descriptors/getDayOfWeekDescription.ts
|
||||
msgid "from {startDay} to {endDay}"
|
||||
@@ -8571,7 +8620,7 @@ msgid "Loading skills..."
|
||||
msgstr "Φόρτωση δεξιοτήτων..."
|
||||
|
||||
#. js-lingui-id: 7YK6ap
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadWidget.tsx
|
||||
msgid "Loading thread"
|
||||
msgstr "Φόρτωση νήματος"
|
||||
|
||||
@@ -9223,10 +9272,10 @@ msgstr "mySkill"
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/data-model/constants/SettingsObjectTableMetadata.ts
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationGeneralTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTable.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
@@ -9392,6 +9441,11 @@ msgstr "Νέα συνομιλία"
|
||||
msgid "New conversation"
|
||||
msgstr "Νέα συνομιλία"
|
||||
|
||||
#. js-lingui-id: 3RwJHq
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
msgid "New Email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: wqoYqp
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
@@ -9590,6 +9644,11 @@ msgstr "Δεν υπάρχουν διαθέσιμα κλειδιά API"
|
||||
msgid "No API keys match your search"
|
||||
msgstr "Κανένα κλειδί API δεν ταιριάζει με την αναζήτησή σας"
|
||||
|
||||
#. js-lingui-id: /VRg8Z
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "No application found"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: rxBnh8
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
msgid "No applications available"
|
||||
@@ -10018,6 +10077,7 @@ msgid "No variables found"
|
||||
msgstr "Δεν βρέθηκαν μεταβλητές"
|
||||
|
||||
#. js-lingui-id: OCektF
|
||||
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationDetailEnvironmentVariablesTable.tsx
|
||||
msgid "No variables to set for this application"
|
||||
msgstr ""
|
||||
@@ -10133,6 +10193,11 @@ msgstr "τώρα"
|
||||
msgid "Npm package"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: p7abaY
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "NPM packages"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: VVexZo
|
||||
#: src/modules/advanced-text-editor/extensions/slash-command/DefaultSlashCommands.ts
|
||||
msgid "number"
|
||||
@@ -11357,10 +11422,11 @@ msgstr ""
|
||||
msgid "Read your profile"
|
||||
msgstr "Ανάγνωση του προφίλ σας"
|
||||
|
||||
#. js-lingui-id: tCXcL7
|
||||
#. js-lingui-id: 6pSHJ5
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "Μόνο για ανάγνωση — διαχειρίζεται από την Twenty"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
@@ -11382,6 +11448,11 @@ msgstr "Λάβετε ένα email που περιέχει τον σύνδεσμ
|
||||
msgid "Recent Events (oldest → newest)"
|
||||
msgstr "Πρόσφατα Γεγονότα (παλιότερα → νεότερα)"
|
||||
|
||||
#. js-lingui-id: yPrbsy
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Recipients"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: b2+5uV
|
||||
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
|
||||
msgid "Recommended Models"
|
||||
@@ -11733,7 +11804,8 @@ msgid "Reorder options"
|
||||
msgstr "Αναδιάταξη επιλογών"
|
||||
|
||||
#. js-lingui-id: ImOQa9
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailThreadBottomBar.tsx
|
||||
msgid "Reply"
|
||||
msgstr "Απάντηση"
|
||||
@@ -11743,6 +11815,11 @@ msgstr "Απάντηση"
|
||||
msgid "Reply to all"
|
||||
msgstr "Απάντηση σε όλους"
|
||||
|
||||
#. js-lingui-id: fiPYZo
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Reply..."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tbmZmI
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Report and issue"
|
||||
@@ -11768,6 +11845,7 @@ msgstr "Επαναποστολή email"
|
||||
#. js-lingui-id: OfhWJH
|
||||
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
|
||||
#: src/modules/views/components/ViewBarDetails.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "Reset"
|
||||
msgstr "Επαναφορά"
|
||||
|
||||
@@ -11788,6 +11866,8 @@ msgid "Reset to"
|
||||
msgstr "Επαναφορά σε"
|
||||
|
||||
#. js-lingui-id: L+rMC9
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/command-menu-item/server-items/edit/components/SidePanelCommandMenuItemEditPage.tsx
|
||||
msgid "Reset to default"
|
||||
@@ -12086,11 +12166,6 @@ msgstr "Αποθήκευση"
|
||||
msgid "Save as new view"
|
||||
msgstr "Αποθήκευση ως νέα προβολή"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
msgstr "Δημιουργήστε τον σκελετό μιας νέας εφαρμογής και στη συνέχεια χρησιμοποιήστε το CLI για να την αναπτύξετε, να τη δημοσιεύσετε και να τη διανείμετε"
|
||||
|
||||
#. js-lingui-id: gmB6oO
|
||||
#: src/modules/workflow/workflow-trigger/components/CronExpressionHelper.tsx
|
||||
msgid "Schedule"
|
||||
@@ -12232,6 +12307,7 @@ msgid "Search an agent..."
|
||||
msgstr "Αναζήτηση πράκτορα..."
|
||||
|
||||
#. js-lingui-id: fGTI3o
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
msgid "Search an application"
|
||||
@@ -12686,6 +12762,13 @@ msgstr "Επιλέξτε ποια μοντέλα θα εμφανίζονται
|
||||
msgid "Select your preferred language"
|
||||
msgstr "Επιλέξτε την προτιμώμενη γλώσσα σας"
|
||||
|
||||
#. js-lingui-id: JlFcis
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mjK8F3
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
msgid "Send an invite email to your team"
|
||||
@@ -13403,6 +13486,8 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Θέμα"
|
||||
|
||||
@@ -13643,11 +13728,6 @@ msgstr ""
|
||||
msgid "System Prompt"
|
||||
msgstr "Σύστημα Προτροπής"
|
||||
|
||||
#. js-lingui-id: BXGTWI
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "System Prompt ({totalTokenCount})"
|
||||
msgstr "Προτροπή συστήματος ({totalTokenCount})"
|
||||
|
||||
#. js-lingui-id: k+7QWO
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
|
||||
msgid "System relations"
|
||||
@@ -14136,6 +14216,11 @@ msgstr ""
|
||||
msgid "This week"
|
||||
msgstr "Αυτή την εβδομάδα"
|
||||
|
||||
#. js-lingui-id: VbVocX
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4VeOo
|
||||
#: src/modules/settings/billing/hooks/useBillingWording.ts
|
||||
msgid "This will cancel the scheduled interval change and keep your current billing interval ({currentIntervalLabel})."
|
||||
@@ -14251,6 +14336,7 @@ msgstr "τίτλος"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "To"
|
||||
msgstr "Προς"
|
||||
|
||||
@@ -14552,7 +14638,6 @@ msgstr "Η εγκατάσταση δύο παραγοντικής ταυτοπο
|
||||
|
||||
#. js-lingui-id: +zy2Nq
|
||||
#: src/pages/settings/data-model/SettingsObjectIndexTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
#: src/pages/settings/ai/components/SettingsToolParameterTable.tsx
|
||||
@@ -14575,6 +14660,11 @@ msgstr "Πληκτρολογήστε '/' για εντολές, '@' για αν
|
||||
msgid "Type anything..."
|
||||
msgstr "Πληκτρολογήστε οτιδήποτε..."
|
||||
|
||||
#. js-lingui-id: LaEX5I
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Type something or press \"/\" to see commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UhqKcC
|
||||
#: src/modules/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemRecordSubPage.tsx
|
||||
msgid "Type to search records"
|
||||
@@ -14902,6 +14992,11 @@ msgstr "Αναβαθμίστε για πρόσβαση"
|
||||
msgid "Upgrade to Enterprise to access audit logs."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: D+7y/3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "Upgrade to Enterprise to share private applications."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +Gi3x1
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationVersionContainer.tsx
|
||||
@@ -15338,7 +15433,6 @@ msgstr "Προβολή αρχείων καταγραφής"
|
||||
|
||||
#. js-lingui-id: 7PrSCy
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View marketplace page"
|
||||
msgstr "Προβολή σελίδας marketplace"
|
||||
|
||||
@@ -15352,6 +15446,11 @@ msgstr ""
|
||||
msgid "View Previous AI Chats"
|
||||
msgstr "Εμφάνιση Προηγούμενων Συνομιλιών AI"
|
||||
|
||||
#. js-lingui-id: NnJpTN
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View private application page"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: hAAsm/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx
|
||||
msgid "View role"
|
||||
@@ -15946,6 +16045,11 @@ msgstr "Ανήκετε ήδη σε αυτό το workspace"
|
||||
msgid "You are not allowed to create records for this object"
|
||||
msgstr "Δεν επιτρέπεται να δημιουργείτε εγγραφές για αυτό το αντικείμενο"
|
||||
|
||||
#. js-lingui-id: iibZbD
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "You can either create a private app or share it to others"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: CNAoaw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/logic-function-action/components/WorkflowEditActionLogicFunction.tsx
|
||||
msgid "You can see the function logic in your application settings."
|
||||
@@ -16021,10 +16125,10 @@ msgstr "Ο λογαριασμός σας έχει ενεργοποιηθεί."
|
||||
msgid "Your app version is out of date. Please refresh the page."
|
||||
msgstr "Η έκδοση της εφαρμογής σας είναι παρωχημένη. Παρακαλώ ανανεώστε τη σελίδα."
|
||||
|
||||
#. js-lingui-id: oNUh7z
|
||||
#. js-lingui-id: 9pWhO+
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Your Apps"
|
||||
msgstr "Οι εφαρμογές σας"
|
||||
msgid "Your apps"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +5YqGH
|
||||
#: src/modules/onboarding/constants/OnboardingSyncEmailsOptions.ts
|
||||
|
||||
@@ -311,6 +311,11 @@ msgstr "{jobCount, plural, one {This will permanently remove it from the queue.
|
||||
msgid "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
msgstr "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
|
||||
#. js-lingui-id: Y32cMj
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadIntermediaryMessages.tsx
|
||||
msgid "{messagesLength} emails"
|
||||
msgstr "{messagesLength} emails"
|
||||
|
||||
#. js-lingui-id: Koe99p
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationItemTableRow.tsx
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx
|
||||
@@ -446,11 +451,13 @@ msgstr "{workspaceMemberName} will be unassigned from the following role:"
|
||||
msgid "••••••••"
|
||||
msgstr "••••••••"
|
||||
|
||||
#. js-lingui-id: tD9raa
|
||||
#. js-lingui-id: SMgdEJ
|
||||
#. placeholder {0}: formatNumber(preview.estimatedTokenCount, { abbreviate: true, decimals: 1, })
|
||||
#. placeholder {0}: formatNumber( section.estimatedTokenCount, { abbreviate: true, decimals: 1, }, )
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~{0} tokens"
|
||||
msgstr "~{0} tokens"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~ {0} tokens"
|
||||
msgstr "~ {0} tokens"
|
||||
|
||||
#. js-lingui-id: Cx0xl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/delay-actions/components/WorkflowEditActionDelay.tsx
|
||||
@@ -1697,6 +1704,7 @@ msgstr "An error occurred while uploading the picture."
|
||||
#: src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
|
||||
#: src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts
|
||||
#: src/modules/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets.ts
|
||||
#: src/modules/page-layout/hooks/useResetPageLayoutWidgetToDefault.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneFieldMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts
|
||||
@@ -1979,6 +1987,11 @@ msgstr "Approved Domains"
|
||||
msgid "Apps"
|
||||
msgstr "Apps"
|
||||
|
||||
#. js-lingui-id: dEnE1D
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Apps made by other developers published on npm"
|
||||
msgstr "Apps made by other developers published on npm"
|
||||
|
||||
#. js-lingui-id: 8HV3WN
|
||||
#: src/pages/settings/profile/appearance/components/LocalePicker.tsx
|
||||
msgid "Arabic"
|
||||
@@ -2403,6 +2416,12 @@ msgstr "Base URL"
|
||||
msgid "Base URL is required"
|
||||
msgstr "Base URL is required"
|
||||
|
||||
#. js-lingui-id: /xLNEx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Bcc"
|
||||
msgstr "Bcc"
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
@@ -2706,9 +2725,11 @@ msgstr "Can't scan? Copy the"
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel"
|
||||
|
||||
@@ -2748,6 +2769,11 @@ msgstr "Cancel plan switching"
|
||||
msgid "Cancel plan switching?"
|
||||
msgstr "Cancel plan switching?"
|
||||
|
||||
#. js-lingui-id: AnRu/j
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Cancel reply"
|
||||
msgstr "Cancel reply"
|
||||
|
||||
#. js-lingui-id: N6gPiD
|
||||
#: src/pages/settings/enterprise/SettingsEnterprise.tsx
|
||||
#: src/modules/settings/billing/components/SettingsBillingContent.tsx
|
||||
@@ -2816,11 +2842,22 @@ msgstr "Catalan"
|
||||
msgid "Category"
|
||||
msgstr "Category"
|
||||
|
||||
#. js-lingui-id: RpYfjZ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc"
|
||||
msgstr "Cc"
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr "CC"
|
||||
|
||||
#. js-lingui-id: Dgsw8A
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc/Bcc"
|
||||
msgstr "Cc/Bcc"
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardEditorSideMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
@@ -3771,11 +3808,6 @@ msgstr "create"
|
||||
msgid "Create"
|
||||
msgstr "Create"
|
||||
|
||||
#. js-lingui-id: 5XhrY3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create & Develop"
|
||||
msgstr "Create & Develop"
|
||||
|
||||
#. js-lingui-id: 8aATyU
|
||||
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
|
||||
msgid "Create a dashboard"
|
||||
@@ -3816,6 +3848,11 @@ msgstr "Create a workflow and return here to view its versions"
|
||||
msgid "Create a workspace"
|
||||
msgstr "Create a workspace"
|
||||
|
||||
#. js-lingui-id: /WlFSf
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create an application"
|
||||
msgstr "Create an application"
|
||||
|
||||
#. js-lingui-id: 8ZjIgO
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
|
||||
msgid "Create and configure AI agents"
|
||||
@@ -4789,6 +4826,7 @@ msgstr "Describe what you want the AI to do..."
|
||||
|
||||
#. js-lingui-id: Nu4oKW
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldEdit.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/ai/SettingsToolDetail.tsx
|
||||
@@ -5334,16 +5372,16 @@ msgstr "Email must be a valid email"
|
||||
msgid "Email or domain is already in blocklist"
|
||||
msgstr "Email or domain is already in blocklist"
|
||||
|
||||
#. js-lingui-id: Xl929X
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Email sent successfully"
|
||||
msgstr "Email sent successfully"
|
||||
|
||||
#. js-lingui-id: jvneza
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Email support"
|
||||
msgstr "Email support"
|
||||
|
||||
#. js-lingui-id: +VjrH/
|
||||
#: src/modules/side-panel/hooks/useOpenEmailThreadInSidePanel.ts
|
||||
msgid "Email Thread"
|
||||
msgstr "Email Thread"
|
||||
|
||||
#. js-lingui-id: LimKOG
|
||||
#: src/pages/settings/security/SettingsSecurityApprovedAccessDomain.tsx
|
||||
msgid "Email verification"
|
||||
@@ -6428,6 +6466,12 @@ msgstr "Failed to save role permissions: {errorMessage}"
|
||||
msgid "Failed to save workspace instructions"
|
||||
msgstr "Failed to save workspace instructions"
|
||||
|
||||
#. js-lingui-id: Lo/GQ5
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Failed to send email"
|
||||
msgstr "Failed to send email"
|
||||
|
||||
#. js-lingui-id: aj02T8
|
||||
#: src/modules/settings/admin-panel/health-status/maintenance-mode/components/SettingsAdminMaintenanceMode.tsx
|
||||
msgid "Failed to set maintenance mode."
|
||||
@@ -6919,6 +6963,11 @@ msgstr "Free trial credits exhausted. Subscribe now to continue using AI feature
|
||||
msgid "French"
|
||||
msgstr "French"
|
||||
|
||||
#. js-lingui-id: ejVYRQ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "From"
|
||||
msgstr "From"
|
||||
|
||||
#. js-lingui-id: qR8gT9
|
||||
#: src/modules/workflow/workflow-trigger/utils/cron-to-human/descriptors/getDayOfWeekDescription.ts
|
||||
msgid "from {startDay} to {endDay}"
|
||||
@@ -8566,7 +8615,7 @@ msgid "Loading skills..."
|
||||
msgstr "Loading skills..."
|
||||
|
||||
#. js-lingui-id: 7YK6ap
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadWidget.tsx
|
||||
msgid "Loading thread"
|
||||
msgstr "Loading thread"
|
||||
|
||||
@@ -9218,10 +9267,10 @@ msgstr "mySkill"
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/data-model/constants/SettingsObjectTableMetadata.ts
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationGeneralTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTable.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
@@ -9387,6 +9436,11 @@ msgstr "New chat"
|
||||
msgid "New conversation"
|
||||
msgstr "New conversation"
|
||||
|
||||
#. js-lingui-id: 3RwJHq
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
msgid "New Email"
|
||||
msgstr "New Email"
|
||||
|
||||
#. js-lingui-id: wqoYqp
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
@@ -9585,6 +9639,11 @@ msgstr "No API keys available"
|
||||
msgid "No API keys match your search"
|
||||
msgstr "No API keys match your search"
|
||||
|
||||
#. js-lingui-id: /VRg8Z
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "No application found"
|
||||
msgstr "No application found"
|
||||
|
||||
#. js-lingui-id: rxBnh8
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
msgid "No applications available"
|
||||
@@ -10013,6 +10072,7 @@ msgid "No variables found"
|
||||
msgstr "No variables found"
|
||||
|
||||
#. js-lingui-id: OCektF
|
||||
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationDetailEnvironmentVariablesTable.tsx
|
||||
msgid "No variables to set for this application"
|
||||
msgstr "No variables to set for this application"
|
||||
@@ -10128,6 +10188,11 @@ msgstr "now"
|
||||
msgid "Npm package"
|
||||
msgstr "Npm package"
|
||||
|
||||
#. js-lingui-id: p7abaY
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "NPM packages"
|
||||
msgstr "NPM packages"
|
||||
|
||||
#. js-lingui-id: VVexZo
|
||||
#: src/modules/advanced-text-editor/extensions/slash-command/DefaultSlashCommands.ts
|
||||
msgid "number"
|
||||
@@ -11352,10 +11417,11 @@ msgstr "Read the system prompts to understand how the AI works (~{0} tokens)"
|
||||
msgid "Read your profile"
|
||||
msgstr "Read your profile"
|
||||
|
||||
#. js-lingui-id: tCXcL7
|
||||
#. js-lingui-id: 6pSHJ5
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "Read-only — managed by Twenty"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only"
|
||||
msgstr "Read-only"
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
@@ -11377,6 +11443,11 @@ msgstr "Receive an email containing password update link"
|
||||
msgid "Recent Events (oldest → newest)"
|
||||
msgstr "Recent Events (oldest → newest)"
|
||||
|
||||
#. js-lingui-id: yPrbsy
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Recipients"
|
||||
msgstr "Recipients"
|
||||
|
||||
#. js-lingui-id: b2+5uV
|
||||
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
|
||||
msgid "Recommended Models"
|
||||
@@ -11728,7 +11799,8 @@ msgid "Reorder options"
|
||||
msgstr "Reorder options"
|
||||
|
||||
#. js-lingui-id: ImOQa9
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailThreadBottomBar.tsx
|
||||
msgid "Reply"
|
||||
msgstr "Reply"
|
||||
@@ -11738,6 +11810,11 @@ msgstr "Reply"
|
||||
msgid "Reply to all"
|
||||
msgstr "Reply to all"
|
||||
|
||||
#. js-lingui-id: fiPYZo
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Reply..."
|
||||
msgstr "Reply..."
|
||||
|
||||
#. js-lingui-id: tbmZmI
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Report and issue"
|
||||
@@ -11763,6 +11840,7 @@ msgstr "Resend email"
|
||||
#. js-lingui-id: OfhWJH
|
||||
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
|
||||
#: src/modules/views/components/ViewBarDetails.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "Reset"
|
||||
msgstr "Reset"
|
||||
|
||||
@@ -11783,6 +11861,8 @@ msgid "Reset to"
|
||||
msgstr "Reset to"
|
||||
|
||||
#. js-lingui-id: L+rMC9
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/command-menu-item/server-items/edit/components/SidePanelCommandMenuItemEditPage.tsx
|
||||
msgid "Reset to default"
|
||||
@@ -12081,11 +12161,6 @@ msgstr "Save"
|
||||
msgid "Save as new view"
|
||||
msgstr "Save as new view"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
msgstr "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
|
||||
#. js-lingui-id: gmB6oO
|
||||
#: src/modules/workflow/workflow-trigger/components/CronExpressionHelper.tsx
|
||||
msgid "Schedule"
|
||||
@@ -12227,6 +12302,7 @@ msgid "Search an agent..."
|
||||
msgstr "Search an agent..."
|
||||
|
||||
#. js-lingui-id: fGTI3o
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
msgid "Search an application"
|
||||
@@ -12681,6 +12757,13 @@ msgstr "Select which models appear as recommended in the workspace model picker"
|
||||
msgid "Select your preferred language"
|
||||
msgstr "Select your preferred language"
|
||||
|
||||
#. js-lingui-id: JlFcis
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Send"
|
||||
msgstr "Send"
|
||||
|
||||
#. js-lingui-id: mjK8F3
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
msgid "Send an invite email to your team"
|
||||
@@ -13396,6 +13479,8 @@ msgstr "subheading"
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Subject"
|
||||
|
||||
@@ -13636,11 +13721,6 @@ msgstr "System objects"
|
||||
msgid "System Prompt"
|
||||
msgstr "System Prompt"
|
||||
|
||||
#. js-lingui-id: BXGTWI
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "System Prompt ({totalTokenCount})"
|
||||
msgstr "System Prompt ({totalTokenCount})"
|
||||
|
||||
#. js-lingui-id: k+7QWO
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
|
||||
msgid "System relations"
|
||||
@@ -14129,6 +14209,11 @@ msgstr "This view uses {usageLabel} on object \"{0}\" which is not accessible."
|
||||
msgid "This week"
|
||||
msgstr "This week"
|
||||
|
||||
#. js-lingui-id: VbVocX
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
msgstr "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
|
||||
#. js-lingui-id: h4VeOo
|
||||
#: src/modules/settings/billing/hooks/useBillingWording.ts
|
||||
msgid "This will cancel the scheduled interval change and keep your current billing interval ({currentIntervalLabel})."
|
||||
@@ -14244,6 +14329,7 @@ msgstr "title"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "To"
|
||||
msgstr "To"
|
||||
|
||||
@@ -14545,7 +14631,6 @@ msgstr "Two-factor authentication setup completed successfully!"
|
||||
|
||||
#. js-lingui-id: +zy2Nq
|
||||
#: src/pages/settings/data-model/SettingsObjectIndexTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
#: src/pages/settings/ai/components/SettingsToolParameterTable.tsx
|
||||
@@ -14568,6 +14653,11 @@ msgstr "Type '/' for commands, '@' for mentions"
|
||||
msgid "Type anything..."
|
||||
msgstr "Type anything..."
|
||||
|
||||
#. js-lingui-id: LaEX5I
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Type something or press \"/\" to see commands"
|
||||
msgstr "Type something or press \"/\" to see commands"
|
||||
|
||||
#. js-lingui-id: UhqKcC
|
||||
#: src/modules/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemRecordSubPage.tsx
|
||||
msgid "Type to search records"
|
||||
@@ -14895,6 +14985,11 @@ msgstr "Upgrade to access"
|
||||
msgid "Upgrade to Enterprise to access audit logs."
|
||||
msgstr "Upgrade to Enterprise to access audit logs."
|
||||
|
||||
#. js-lingui-id: D+7y/3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "Upgrade to Enterprise to share private applications."
|
||||
msgstr "Upgrade to Enterprise to share private applications."
|
||||
|
||||
#. js-lingui-id: +Gi3x1
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationVersionContainer.tsx
|
||||
@@ -15331,7 +15426,6 @@ msgstr "View Logs"
|
||||
|
||||
#. js-lingui-id: 7PrSCy
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View marketplace page"
|
||||
msgstr "View marketplace page"
|
||||
|
||||
@@ -15345,6 +15439,11 @@ msgstr "View not shared"
|
||||
msgid "View Previous AI Chats"
|
||||
msgstr "View Previous AI Chats"
|
||||
|
||||
#. js-lingui-id: NnJpTN
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View private application page"
|
||||
msgstr "View private application page"
|
||||
|
||||
#. js-lingui-id: hAAsm/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx
|
||||
msgid "View role"
|
||||
@@ -15939,6 +16038,11 @@ msgstr "You already belong to this workspace"
|
||||
msgid "You are not allowed to create records for this object"
|
||||
msgstr "You are not allowed to create records for this object"
|
||||
|
||||
#. js-lingui-id: iibZbD
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "You can either create a private app or share it to others"
|
||||
msgstr "You can either create a private app or share it to others"
|
||||
|
||||
#. js-lingui-id: CNAoaw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/logic-function-action/components/WorkflowEditActionLogicFunction.tsx
|
||||
msgid "You can see the function logic in your application settings."
|
||||
@@ -16014,10 +16118,10 @@ msgstr "Your account has been activated."
|
||||
msgid "Your app version is out of date. Please refresh the page."
|
||||
msgstr "Your app version is out of date. Please refresh the page."
|
||||
|
||||
#. js-lingui-id: oNUh7z
|
||||
#. js-lingui-id: 9pWhO+
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Your Apps"
|
||||
msgstr "Your Apps"
|
||||
msgid "Your apps"
|
||||
msgstr "Your apps"
|
||||
|
||||
#. js-lingui-id: +5YqGH
|
||||
#: src/modules/onboarding/constants/OnboardingSyncEmailsOptions.ts
|
||||
|
||||
@@ -316,6 +316,11 @@ msgstr "{jobCount, plural, one {Esto lo eliminará permanentemente de la cola. E
|
||||
msgid "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
msgstr "{jobCount, plural, one {Esto reintentará el trabajo seleccionado. Será reejecutado desde el principio.} other {Esto reintentará los trabajos seleccionados. Serán reejecutados desde el principio.}}"
|
||||
|
||||
#. js-lingui-id: Y32cMj
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadIntermediaryMessages.tsx
|
||||
msgid "{messagesLength} emails"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Koe99p
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationItemTableRow.tsx
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx
|
||||
@@ -451,11 +456,13 @@ msgstr "{workspaceMemberName} dejará de estar asignado al siguiente rol:"
|
||||
msgid "••••••••"
|
||||
msgstr "••••••••"
|
||||
|
||||
#. js-lingui-id: tD9raa
|
||||
#. js-lingui-id: SMgdEJ
|
||||
#. placeholder {0}: formatNumber(preview.estimatedTokenCount, { abbreviate: true, decimals: 1, })
|
||||
#. placeholder {0}: formatNumber( section.estimatedTokenCount, { abbreviate: true, decimals: 1, }, )
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~{0} tokens"
|
||||
msgstr "~{0} tokens"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~ {0} tokens"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Cx0xl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/delay-actions/components/WorkflowEditActionDelay.tsx
|
||||
@@ -1702,6 +1709,7 @@ msgstr "Se produjo un error al subir la imagen."
|
||||
#: src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
|
||||
#: src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts
|
||||
#: src/modules/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets.ts
|
||||
#: src/modules/page-layout/hooks/useResetPageLayoutWidgetToDefault.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneFieldMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts
|
||||
@@ -1984,6 +1992,11 @@ msgstr "Dominios Aprobados"
|
||||
msgid "Apps"
|
||||
msgstr "Aplicaciones"
|
||||
|
||||
#. js-lingui-id: dEnE1D
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Apps made by other developers published on npm"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8HV3WN
|
||||
#: src/pages/settings/profile/appearance/components/LocalePicker.tsx
|
||||
msgid "Arabic"
|
||||
@@ -2408,6 +2421,12 @@ msgstr "URL base"
|
||||
msgid "Base URL is required"
|
||||
msgstr "La URL base es obligatoria"
|
||||
|
||||
#. js-lingui-id: /xLNEx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
@@ -2711,9 +2730,11 @@ msgstr "¿No puedes escanear? Copia el"
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
@@ -2753,6 +2774,11 @@ msgstr "Cancelar cambio de plan"
|
||||
msgid "Cancel plan switching?"
|
||||
msgstr "¿Cancelar cambio de plan?"
|
||||
|
||||
#. js-lingui-id: AnRu/j
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: N6gPiD
|
||||
#: src/pages/settings/enterprise/SettingsEnterprise.tsx
|
||||
#: src/modules/settings/billing/components/SettingsBillingContent.tsx
|
||||
@@ -2821,11 +2847,22 @@ msgstr "Catalán"
|
||||
msgid "Category"
|
||||
msgstr "Categoría"
|
||||
|
||||
#. js-lingui-id: RpYfjZ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr "CC"
|
||||
|
||||
#. js-lingui-id: Dgsw8A
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc/Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardEditorSideMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
@@ -3776,11 +3813,6 @@ msgstr "crear"
|
||||
msgid "Create"
|
||||
msgstr "Crear"
|
||||
|
||||
#. js-lingui-id: 5XhrY3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create & Develop"
|
||||
msgstr "Crear y Desarrollar"
|
||||
|
||||
#. js-lingui-id: 8aATyU
|
||||
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
|
||||
msgid "Create a dashboard"
|
||||
@@ -3821,6 +3853,11 @@ msgstr "Cree un workflow y vuelva aquí para ver sus versiones"
|
||||
msgid "Create a workspace"
|
||||
msgstr "Crear Espacio de Trabajo"
|
||||
|
||||
#. js-lingui-id: /WlFSf
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create an application"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8ZjIgO
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
|
||||
msgid "Create and configure AI agents"
|
||||
@@ -4794,6 +4831,7 @@ msgstr "Describa lo que quiere que la IA haga..."
|
||||
|
||||
#. js-lingui-id: Nu4oKW
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldEdit.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/ai/SettingsToolDetail.tsx
|
||||
@@ -5339,16 +5377,16 @@ msgstr "El correo electrónico debe ser válido"
|
||||
msgid "Email or domain is already in blocklist"
|
||||
msgstr "El correo electrónico o el dominio ya están en la lista de bloqueo"
|
||||
|
||||
#. js-lingui-id: Xl929X
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Email sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: jvneza
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Email support"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +VjrH/
|
||||
#: src/modules/side-panel/hooks/useOpenEmailThreadInSidePanel.ts
|
||||
msgid "Email Thread"
|
||||
msgstr "Hilo de correo electrónico"
|
||||
|
||||
#. js-lingui-id: LimKOG
|
||||
#: src/pages/settings/security/SettingsSecurityApprovedAccessDomain.tsx
|
||||
msgid "Email verification"
|
||||
@@ -6433,6 +6471,12 @@ msgstr "Error al guardar los permisos de rol: {errorMessage}"
|
||||
msgid "Failed to save workspace instructions"
|
||||
msgstr "Error al guardar las instrucciones del espacio de trabajo"
|
||||
|
||||
#. js-lingui-id: Lo/GQ5
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Failed to send email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: aj02T8
|
||||
#: src/modules/settings/admin-panel/health-status/maintenance-mode/components/SettingsAdminMaintenanceMode.tsx
|
||||
msgid "Failed to set maintenance mode."
|
||||
@@ -6924,6 +6968,11 @@ msgstr "Se han agotado los créditos de la prueba gratuita. Suscríbete ahora pa
|
||||
msgid "French"
|
||||
msgstr "Francés"
|
||||
|
||||
#. js-lingui-id: ejVYRQ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qR8gT9
|
||||
#: src/modules/workflow/workflow-trigger/utils/cron-to-human/descriptors/getDayOfWeekDescription.ts
|
||||
msgid "from {startDay} to {endDay}"
|
||||
@@ -8571,7 +8620,7 @@ msgid "Loading skills..."
|
||||
msgstr "Cargando habilidades..."
|
||||
|
||||
#. js-lingui-id: 7YK6ap
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadWidget.tsx
|
||||
msgid "Loading thread"
|
||||
msgstr "Cargando hilo"
|
||||
|
||||
@@ -9223,10 +9272,10 @@ msgstr "mySkill"
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/data-model/constants/SettingsObjectTableMetadata.ts
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationGeneralTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTable.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
@@ -9392,6 +9441,11 @@ msgstr "Nuevo chat"
|
||||
msgid "New conversation"
|
||||
msgstr "Nueva conversación"
|
||||
|
||||
#. js-lingui-id: 3RwJHq
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
msgid "New Email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: wqoYqp
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
@@ -9590,6 +9644,11 @@ msgstr "No hay claves API disponibles"
|
||||
msgid "No API keys match your search"
|
||||
msgstr "No hay claves API que coincidan con tu búsqueda"
|
||||
|
||||
#. js-lingui-id: /VRg8Z
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "No application found"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: rxBnh8
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
msgid "No applications available"
|
||||
@@ -10018,6 +10077,7 @@ msgid "No variables found"
|
||||
msgstr "No se encontraron variables"
|
||||
|
||||
#. js-lingui-id: OCektF
|
||||
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationDetailEnvironmentVariablesTable.tsx
|
||||
msgid "No variables to set for this application"
|
||||
msgstr ""
|
||||
@@ -10133,6 +10193,11 @@ msgstr "ahora"
|
||||
msgid "Npm package"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: p7abaY
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "NPM packages"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: VVexZo
|
||||
#: src/modules/advanced-text-editor/extensions/slash-command/DefaultSlashCommands.ts
|
||||
msgid "number"
|
||||
@@ -11357,10 +11422,11 @@ msgstr ""
|
||||
msgid "Read your profile"
|
||||
msgstr "Leer tu perfil"
|
||||
|
||||
#. js-lingui-id: tCXcL7
|
||||
#. js-lingui-id: 6pSHJ5
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "De solo lectura — gestionado por Twenty"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
@@ -11382,6 +11448,11 @@ msgstr "Recibir un correo electrónico con un enlace para actualizar la contrase
|
||||
msgid "Recent Events (oldest → newest)"
|
||||
msgstr "Eventos Recientes (del más antiguo → al más nuevo)"
|
||||
|
||||
#. js-lingui-id: yPrbsy
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Recipients"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: b2+5uV
|
||||
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
|
||||
msgid "Recommended Models"
|
||||
@@ -11733,7 +11804,8 @@ msgid "Reorder options"
|
||||
msgstr "Reordenar opciones"
|
||||
|
||||
#. js-lingui-id: ImOQa9
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailThreadBottomBar.tsx
|
||||
msgid "Reply"
|
||||
msgstr "Responder"
|
||||
@@ -11743,6 +11815,11 @@ msgstr "Responder"
|
||||
msgid "Reply to all"
|
||||
msgstr "Responder a todos"
|
||||
|
||||
#. js-lingui-id: fiPYZo
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Reply..."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tbmZmI
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Report and issue"
|
||||
@@ -11768,6 +11845,7 @@ msgstr "Reenviar correo electrónico"
|
||||
#. js-lingui-id: OfhWJH
|
||||
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
|
||||
#: src/modules/views/components/ViewBarDetails.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "Reset"
|
||||
msgstr "Restablecer"
|
||||
|
||||
@@ -11788,6 +11866,8 @@ msgid "Reset to"
|
||||
msgstr "Restablecer a"
|
||||
|
||||
#. js-lingui-id: L+rMC9
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/command-menu-item/server-items/edit/components/SidePanelCommandMenuItemEditPage.tsx
|
||||
msgid "Reset to default"
|
||||
@@ -12086,11 +12166,6 @@ msgstr "Guardar"
|
||||
msgid "Save as new view"
|
||||
msgstr "Guardar como nueva vista"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
msgstr "Crea la estructura inicial de una nueva aplicación y luego usa la CLI para desarrollar, publicar y distribuir"
|
||||
|
||||
#. js-lingui-id: gmB6oO
|
||||
#: src/modules/workflow/workflow-trigger/components/CronExpressionHelper.tsx
|
||||
msgid "Schedule"
|
||||
@@ -12232,6 +12307,7 @@ msgid "Search an agent..."
|
||||
msgstr "Buscar un agente..."
|
||||
|
||||
#. js-lingui-id: fGTI3o
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
msgid "Search an application"
|
||||
@@ -12686,6 +12762,13 @@ msgstr "Selecciona qué modelos aparecen como recomendados en el selector de mod
|
||||
msgid "Select your preferred language"
|
||||
msgstr "Selecciona tu idioma preferido"
|
||||
|
||||
#. js-lingui-id: JlFcis
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mjK8F3
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
msgid "Send an invite email to your team"
|
||||
@@ -13401,6 +13484,8 @@ msgstr "sub encabezado"
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Asunto"
|
||||
|
||||
@@ -13641,11 +13726,6 @@ msgstr "Objetos del sistema"
|
||||
msgid "System Prompt"
|
||||
msgstr "Aviso del sistema"
|
||||
|
||||
#. js-lingui-id: BXGTWI
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "System Prompt ({totalTokenCount})"
|
||||
msgstr "Prompt del sistema ({totalTokenCount})"
|
||||
|
||||
#. js-lingui-id: k+7QWO
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
|
||||
msgid "System relations"
|
||||
@@ -14134,6 +14214,11 @@ msgstr ""
|
||||
msgid "This week"
|
||||
msgstr "Esta semana"
|
||||
|
||||
#. js-lingui-id: VbVocX
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4VeOo
|
||||
#: src/modules/settings/billing/hooks/useBillingWording.ts
|
||||
msgid "This will cancel the scheduled interval change and keep your current billing interval ({currentIntervalLabel})."
|
||||
@@ -14249,6 +14334,7 @@ msgstr "título"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "To"
|
||||
msgstr "Para"
|
||||
|
||||
@@ -14550,7 +14636,6 @@ msgstr "¡La configuración de la autenticación de dos factores se completó co
|
||||
|
||||
#. js-lingui-id: +zy2Nq
|
||||
#: src/pages/settings/data-model/SettingsObjectIndexTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
#: src/pages/settings/ai/components/SettingsToolParameterTable.tsx
|
||||
@@ -14573,6 +14658,11 @@ msgstr "Escribe \"/\" para comandos, \"@\" para menciones"
|
||||
msgid "Type anything..."
|
||||
msgstr "Escribe cualquier cosa..."
|
||||
|
||||
#. js-lingui-id: LaEX5I
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Type something or press \"/\" to see commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UhqKcC
|
||||
#: src/modules/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemRecordSubPage.tsx
|
||||
msgid "Type to search records"
|
||||
@@ -14900,6 +14990,11 @@ msgstr "Actualiza para acceder"
|
||||
msgid "Upgrade to Enterprise to access audit logs."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: D+7y/3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "Upgrade to Enterprise to share private applications."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +Gi3x1
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationVersionContainer.tsx
|
||||
@@ -15336,7 +15431,6 @@ msgstr "Ver registros"
|
||||
|
||||
#. js-lingui-id: 7PrSCy
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View marketplace page"
|
||||
msgstr "Ver página del Marketplace"
|
||||
|
||||
@@ -15350,6 +15444,11 @@ msgstr ""
|
||||
msgid "View Previous AI Chats"
|
||||
msgstr "Ver chats previos de IA"
|
||||
|
||||
#. js-lingui-id: NnJpTN
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View private application page"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: hAAsm/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx
|
||||
msgid "View role"
|
||||
@@ -15944,6 +16043,11 @@ msgstr "Ya perteneces a este espacio de trabajo"
|
||||
msgid "You are not allowed to create records for this object"
|
||||
msgstr "No tiene permiso para crear registros en este objeto"
|
||||
|
||||
#. js-lingui-id: iibZbD
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "You can either create a private app or share it to others"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: CNAoaw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/logic-function-action/components/WorkflowEditActionLogicFunction.tsx
|
||||
msgid "You can see the function logic in your application settings."
|
||||
@@ -16019,10 +16123,10 @@ msgstr "Tu cuenta ha sido activada."
|
||||
msgid "Your app version is out of date. Please refresh the page."
|
||||
msgstr "La versión de su aplicación está desactualizada. Por favor, actualice la página."
|
||||
|
||||
#. js-lingui-id: oNUh7z
|
||||
#. js-lingui-id: 9pWhO+
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Your Apps"
|
||||
msgstr "Tus aplicaciones"
|
||||
msgid "Your apps"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +5YqGH
|
||||
#: src/modules/onboarding/constants/OnboardingSyncEmailsOptions.ts
|
||||
|
||||
@@ -316,6 +316,11 @@ msgstr "{jobCount, plural, one {Tämä poistaa sen pysyvästi jonosta. Tämä to
|
||||
msgid "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
msgstr "{jobCount, plural, one {Tämä yrittää valittua työtä uudelleen. Se suoritetaan alusta alkaen uudelleen.} other {Tämä yrittää valittuja töitä uudelleen. Ne suoritetaan alusta alkaen uudelleen.}}"
|
||||
|
||||
#. js-lingui-id: Y32cMj
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadIntermediaryMessages.tsx
|
||||
msgid "{messagesLength} emails"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Koe99p
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationItemTableRow.tsx
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx
|
||||
@@ -451,11 +456,13 @@ msgstr "{workspaceMemberName} poistetaan seuraavasta roolista:"
|
||||
msgid "••••••••"
|
||||
msgstr "••••••••"
|
||||
|
||||
#. js-lingui-id: tD9raa
|
||||
#. js-lingui-id: SMgdEJ
|
||||
#. placeholder {0}: formatNumber(preview.estimatedTokenCount, { abbreviate: true, decimals: 1, })
|
||||
#. placeholder {0}: formatNumber( section.estimatedTokenCount, { abbreviate: true, decimals: 1, }, )
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~{0} tokens"
|
||||
msgstr "~{0} tokenia"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~ {0} tokens"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Cx0xl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/delay-actions/components/WorkflowEditActionDelay.tsx
|
||||
@@ -1702,6 +1709,7 @@ msgstr "Kuvaa ladattaessa tapahtui virhe."
|
||||
#: src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
|
||||
#: src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts
|
||||
#: src/modules/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets.ts
|
||||
#: src/modules/page-layout/hooks/useResetPageLayoutWidgetToDefault.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneFieldMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts
|
||||
@@ -1984,6 +1992,11 @@ msgstr "Hyväksytyt verkkotunnukset"
|
||||
msgid "Apps"
|
||||
msgstr "Sovellukset"
|
||||
|
||||
#. js-lingui-id: dEnE1D
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Apps made by other developers published on npm"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8HV3WN
|
||||
#: src/pages/settings/profile/appearance/components/LocalePicker.tsx
|
||||
msgid "Arabic"
|
||||
@@ -2408,6 +2421,12 @@ msgstr "Perus-URL"
|
||||
msgid "Base URL is required"
|
||||
msgstr "Perus-URL on pakollinen"
|
||||
|
||||
#. js-lingui-id: /xLNEx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
@@ -2711,9 +2730,11 @@ msgstr "Et voi skannata? Kopioi"
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Peruuta"
|
||||
|
||||
@@ -2753,6 +2774,11 @@ msgstr "Peruuta suunnitelman vaihtaminen"
|
||||
msgid "Cancel plan switching?"
|
||||
msgstr "Peruuta suunnitelman vaihtaminen?"
|
||||
|
||||
#. js-lingui-id: AnRu/j
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: N6gPiD
|
||||
#: src/pages/settings/enterprise/SettingsEnterprise.tsx
|
||||
#: src/modules/settings/billing/components/SettingsBillingContent.tsx
|
||||
@@ -2821,11 +2847,22 @@ msgstr "Katalaani"
|
||||
msgid "Category"
|
||||
msgstr "Luokka"
|
||||
|
||||
#. js-lingui-id: RpYfjZ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr "Kopio"
|
||||
|
||||
#. js-lingui-id: Dgsw8A
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc/Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardEditorSideMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
@@ -3776,11 +3813,6 @@ msgstr "luo"
|
||||
msgid "Create"
|
||||
msgstr "Luo"
|
||||
|
||||
#. js-lingui-id: 5XhrY3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create & Develop"
|
||||
msgstr "Luo ja kehitä"
|
||||
|
||||
#. js-lingui-id: 8aATyU
|
||||
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
|
||||
msgid "Create a dashboard"
|
||||
@@ -3821,6 +3853,11 @@ msgstr "Luo työnkulku ja palaa tänne nähdäksesi sen versiot"
|
||||
msgid "Create a workspace"
|
||||
msgstr "Luo työtila"
|
||||
|
||||
#. js-lingui-id: /WlFSf
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create an application"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8ZjIgO
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
|
||||
msgid "Create and configure AI agents"
|
||||
@@ -4794,6 +4831,7 @@ msgstr "Kuvaile mitä haluat, että tekoäly tekee..."
|
||||
|
||||
#. js-lingui-id: Nu4oKW
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldEdit.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/ai/SettingsToolDetail.tsx
|
||||
@@ -5339,16 +5377,16 @@ msgstr "Sähköpostin on oltava kelvollinen sähköpostiosoite"
|
||||
msgid "Email or domain is already in blocklist"
|
||||
msgstr "Sähköposti tai verkkotunnus on jo estolistalla"
|
||||
|
||||
#. js-lingui-id: Xl929X
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Email sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: jvneza
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Email support"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +VjrH/
|
||||
#: src/modules/side-panel/hooks/useOpenEmailThreadInSidePanel.ts
|
||||
msgid "Email Thread"
|
||||
msgstr "Sähköpostiketju"
|
||||
|
||||
#. js-lingui-id: LimKOG
|
||||
#: src/pages/settings/security/SettingsSecurityApprovedAccessDomain.tsx
|
||||
msgid "Email verification"
|
||||
@@ -6433,6 +6471,12 @@ msgstr ""
|
||||
msgid "Failed to save workspace instructions"
|
||||
msgstr "Työtilan ohjeiden tallentaminen epäonnistui"
|
||||
|
||||
#. js-lingui-id: Lo/GQ5
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Failed to send email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: aj02T8
|
||||
#: src/modules/settings/admin-panel/health-status/maintenance-mode/components/SettingsAdminMaintenanceMode.tsx
|
||||
msgid "Failed to set maintenance mode."
|
||||
@@ -6924,6 +6968,11 @@ msgstr "Kokeilujakson krediitit on käytetty. Tilaa nyt jatkaaksesi AI-ominaisuu
|
||||
msgid "French"
|
||||
msgstr "Ranska"
|
||||
|
||||
#. js-lingui-id: ejVYRQ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qR8gT9
|
||||
#: src/modules/workflow/workflow-trigger/utils/cron-to-human/descriptors/getDayOfWeekDescription.ts
|
||||
msgid "from {startDay} to {endDay}"
|
||||
@@ -8571,7 +8620,7 @@ msgid "Loading skills..."
|
||||
msgstr "Ladataan taitoja..."
|
||||
|
||||
#. js-lingui-id: 7YK6ap
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadWidget.tsx
|
||||
msgid "Loading thread"
|
||||
msgstr "Ladataan ketjua"
|
||||
|
||||
@@ -9223,10 +9272,10 @@ msgstr "mySkill"
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/data-model/constants/SettingsObjectTableMetadata.ts
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationGeneralTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTable.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
@@ -9392,6 +9441,11 @@ msgstr "Uusi keskustelu"
|
||||
msgid "New conversation"
|
||||
msgstr "Uusi keskustelu"
|
||||
|
||||
#. js-lingui-id: 3RwJHq
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
msgid "New Email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: wqoYqp
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
@@ -9590,6 +9644,11 @@ msgstr "Ei käytettävissä olevia API-avaimia"
|
||||
msgid "No API keys match your search"
|
||||
msgstr "Yksikään API-avain ei vastaa hakua"
|
||||
|
||||
#. js-lingui-id: /VRg8Z
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "No application found"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: rxBnh8
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
msgid "No applications available"
|
||||
@@ -10018,6 +10077,7 @@ msgid "No variables found"
|
||||
msgstr "Muuttujia ei löydy"
|
||||
|
||||
#. js-lingui-id: OCektF
|
||||
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationDetailEnvironmentVariablesTable.tsx
|
||||
msgid "No variables to set for this application"
|
||||
msgstr ""
|
||||
@@ -10133,6 +10193,11 @@ msgstr "nyt"
|
||||
msgid "Npm package"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: p7abaY
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "NPM packages"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: VVexZo
|
||||
#: src/modules/advanced-text-editor/extensions/slash-command/DefaultSlashCommands.ts
|
||||
msgid "number"
|
||||
@@ -11357,10 +11422,11 @@ msgstr ""
|
||||
msgid "Read your profile"
|
||||
msgstr "Lue profiilisi"
|
||||
|
||||
#. js-lingui-id: tCXcL7
|
||||
#. js-lingui-id: 6pSHJ5
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "Vain luku — Twenty hallinnoi"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
@@ -11382,6 +11448,11 @@ msgstr "Vastaanota sähköposti salasanan päivityslinkillä"
|
||||
msgid "Recent Events (oldest → newest)"
|
||||
msgstr "Viimeisimmät tapahtumat (vanhin → uusin)"
|
||||
|
||||
#. js-lingui-id: yPrbsy
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Recipients"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: b2+5uV
|
||||
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
|
||||
msgid "Recommended Models"
|
||||
@@ -11733,7 +11804,8 @@ msgid "Reorder options"
|
||||
msgstr "Järjestä vaihtoehdot uudelleen"
|
||||
|
||||
#. js-lingui-id: ImOQa9
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailThreadBottomBar.tsx
|
||||
msgid "Reply"
|
||||
msgstr "Vastaa"
|
||||
@@ -11743,6 +11815,11 @@ msgstr "Vastaa"
|
||||
msgid "Reply to all"
|
||||
msgstr "Vastaa kaikille"
|
||||
|
||||
#. js-lingui-id: fiPYZo
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Reply..."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tbmZmI
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Report and issue"
|
||||
@@ -11768,6 +11845,7 @@ msgstr "Lähetä sähköposti uudelleen"
|
||||
#. js-lingui-id: OfhWJH
|
||||
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
|
||||
#: src/modules/views/components/ViewBarDetails.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "Reset"
|
||||
msgstr "Nollaa"
|
||||
|
||||
@@ -11788,6 +11866,8 @@ msgid "Reset to"
|
||||
msgstr "Palauta"
|
||||
|
||||
#. js-lingui-id: L+rMC9
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/command-menu-item/server-items/edit/components/SidePanelCommandMenuItemEditPage.tsx
|
||||
msgid "Reset to default"
|
||||
@@ -12086,11 +12166,6 @@ msgstr "Tallenna"
|
||||
msgid "Save as new view"
|
||||
msgstr "Tallenna uutena näkymänä"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
msgstr "Luo uuden sovelluksen perusrakenne ja käytä sitten CLI:tä kehittämiseen, julkaisuun ja jakeluun"
|
||||
|
||||
#. js-lingui-id: gmB6oO
|
||||
#: src/modules/workflow/workflow-trigger/components/CronExpressionHelper.tsx
|
||||
msgid "Schedule"
|
||||
@@ -12232,6 +12307,7 @@ msgid "Search an agent..."
|
||||
msgstr "Etsi agenttia..."
|
||||
|
||||
#. js-lingui-id: fGTI3o
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
msgid "Search an application"
|
||||
@@ -12686,6 +12762,13 @@ msgstr "Valitse, mitkä mallit näkyvät suositeltuina työtilan mallivalitsimes
|
||||
msgid "Select your preferred language"
|
||||
msgstr "Valitse suosimasi kieli"
|
||||
|
||||
#. js-lingui-id: JlFcis
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mjK8F3
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
msgid "Send an invite email to your team"
|
||||
@@ -13401,6 +13484,8 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Aihe"
|
||||
|
||||
@@ -13641,11 +13726,6 @@ msgstr ""
|
||||
msgid "System Prompt"
|
||||
msgstr "Järjestelmäkehotus"
|
||||
|
||||
#. js-lingui-id: BXGTWI
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "System Prompt ({totalTokenCount})"
|
||||
msgstr "Järjestelmäkehote ({totalTokenCount})"
|
||||
|
||||
#. js-lingui-id: k+7QWO
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
|
||||
msgid "System relations"
|
||||
@@ -14132,6 +14212,11 @@ msgstr ""
|
||||
msgid "This week"
|
||||
msgstr "Tämä viikko"
|
||||
|
||||
#. js-lingui-id: VbVocX
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4VeOo
|
||||
#: src/modules/settings/billing/hooks/useBillingWording.ts
|
||||
msgid "This will cancel the scheduled interval change and keep your current billing interval ({currentIntervalLabel})."
|
||||
@@ -14247,6 +14332,7 @@ msgstr "otsikko"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "To"
|
||||
msgstr "Vastaanottaja"
|
||||
|
||||
@@ -14548,7 +14634,6 @@ msgstr "Kaksivaiheisen todennuksen asennus on valmis!"
|
||||
|
||||
#. js-lingui-id: +zy2Nq
|
||||
#: src/pages/settings/data-model/SettingsObjectIndexTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
#: src/pages/settings/ai/components/SettingsToolParameterTable.tsx
|
||||
@@ -14571,6 +14656,11 @@ msgstr "Kirjoita '/' komentoja varten, '@' mainintoja varten"
|
||||
msgid "Type anything..."
|
||||
msgstr "Kirjoita jotain..."
|
||||
|
||||
#. js-lingui-id: LaEX5I
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Type something or press \"/\" to see commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UhqKcC
|
||||
#: src/modules/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemRecordSubPage.tsx
|
||||
msgid "Type to search records"
|
||||
@@ -14898,6 +14988,11 @@ msgstr "Päivitä saadaksesi käyttöoikeuden"
|
||||
msgid "Upgrade to Enterprise to access audit logs."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: D+7y/3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "Upgrade to Enterprise to share private applications."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +Gi3x1
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationVersionContainer.tsx
|
||||
@@ -15334,7 +15429,6 @@ msgstr "Näytä lokit"
|
||||
|
||||
#. js-lingui-id: 7PrSCy
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View marketplace page"
|
||||
msgstr "Avaa markkinapaikan sivu"
|
||||
|
||||
@@ -15348,6 +15442,11 @@ msgstr ""
|
||||
msgid "View Previous AI Chats"
|
||||
msgstr "Näytä edelliset AI Keskustelut"
|
||||
|
||||
#. js-lingui-id: NnJpTN
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View private application page"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: hAAsm/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx
|
||||
msgid "View role"
|
||||
@@ -15942,6 +16041,11 @@ msgstr "Kuulut jo tähän työtilaan"
|
||||
msgid "You are not allowed to create records for this object"
|
||||
msgstr "Et voi luoda tietueita tälle objektille"
|
||||
|
||||
#. js-lingui-id: iibZbD
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "You can either create a private app or share it to others"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: CNAoaw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/logic-function-action/components/WorkflowEditActionLogicFunction.tsx
|
||||
msgid "You can see the function logic in your application settings."
|
||||
@@ -16017,10 +16121,10 @@ msgstr "Tilisi on aktivoitu."
|
||||
msgid "Your app version is out of date. Please refresh the page."
|
||||
msgstr "Sovelluksesi versio on vanhentunut. Ole hyvä, päivitä sivu."
|
||||
|
||||
#. js-lingui-id: oNUh7z
|
||||
#. js-lingui-id: 9pWhO+
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Your Apps"
|
||||
msgstr "Omat sovellukset"
|
||||
msgid "Your apps"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +5YqGH
|
||||
#: src/modules/onboarding/constants/OnboardingSyncEmailsOptions.ts
|
||||
|
||||
@@ -316,6 +316,11 @@ msgstr "{jobCount, plural, one {Cela le retirera définitivement de la file d'at
|
||||
msgid "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
msgstr "{jobCount, plural, one {Ceci va réessayer la tâche sélectionnée. Elle sera ré-exécutée depuis le début.} other {Ceci va réessayer les tâches sélectionnées. Elles seront ré-exécutées depuis le début.}}"
|
||||
|
||||
#. js-lingui-id: Y32cMj
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadIntermediaryMessages.tsx
|
||||
msgid "{messagesLength} emails"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Koe99p
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationItemTableRow.tsx
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx
|
||||
@@ -451,11 +456,13 @@ msgstr "{workspaceMemberName} sera retiré du rôle suivant :"
|
||||
msgid "••••••••"
|
||||
msgstr "••••••••"
|
||||
|
||||
#. js-lingui-id: tD9raa
|
||||
#. js-lingui-id: SMgdEJ
|
||||
#. placeholder {0}: formatNumber(preview.estimatedTokenCount, { abbreviate: true, decimals: 1, })
|
||||
#. placeholder {0}: formatNumber( section.estimatedTokenCount, { abbreviate: true, decimals: 1, }, )
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~{0} tokens"
|
||||
msgstr "~{0} jetons"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~ {0} tokens"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Cx0xl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/delay-actions/components/WorkflowEditActionDelay.tsx
|
||||
@@ -1702,6 +1709,7 @@ msgstr "Une erreur s'est produite lors du téléversement de l'image."
|
||||
#: src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
|
||||
#: src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts
|
||||
#: src/modules/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets.ts
|
||||
#: src/modules/page-layout/hooks/useResetPageLayoutWidgetToDefault.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneFieldMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts
|
||||
@@ -1984,6 +1992,11 @@ msgstr "Domaines approuvés"
|
||||
msgid "Apps"
|
||||
msgstr "Applications"
|
||||
|
||||
#. js-lingui-id: dEnE1D
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Apps made by other developers published on npm"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8HV3WN
|
||||
#: src/pages/settings/profile/appearance/components/LocalePicker.tsx
|
||||
msgid "Arabic"
|
||||
@@ -2408,6 +2421,12 @@ msgstr "URL de base"
|
||||
msgid "Base URL is required"
|
||||
msgstr "L'URL de base est requise"
|
||||
|
||||
#. js-lingui-id: /xLNEx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
@@ -2711,9 +2730,11 @@ msgstr "Impossible de scanner ? Copiez le"
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
@@ -2753,6 +2774,11 @@ msgstr "Annuler le changement de plan"
|
||||
msgid "Cancel plan switching?"
|
||||
msgstr "Annuler le changement de plan ?"
|
||||
|
||||
#. js-lingui-id: AnRu/j
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: N6gPiD
|
||||
#: src/pages/settings/enterprise/SettingsEnterprise.tsx
|
||||
#: src/modules/settings/billing/components/SettingsBillingContent.tsx
|
||||
@@ -2821,11 +2847,22 @@ msgstr "Catalan"
|
||||
msgid "Category"
|
||||
msgstr "Catégorie"
|
||||
|
||||
#. js-lingui-id: RpYfjZ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr "Cc"
|
||||
|
||||
#. js-lingui-id: Dgsw8A
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc/Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardEditorSideMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
@@ -3776,11 +3813,6 @@ msgstr "créer"
|
||||
msgid "Create"
|
||||
msgstr "Créer"
|
||||
|
||||
#. js-lingui-id: 5XhrY3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create & Develop"
|
||||
msgstr "Créer et développer"
|
||||
|
||||
#. js-lingui-id: 8aATyU
|
||||
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
|
||||
msgid "Create a dashboard"
|
||||
@@ -3821,6 +3853,11 @@ msgstr "Créez un workflow et revenez ici pour voir ses versions"
|
||||
msgid "Create a workspace"
|
||||
msgstr "Créer un espace de travail"
|
||||
|
||||
#. js-lingui-id: /WlFSf
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create an application"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8ZjIgO
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
|
||||
msgid "Create and configure AI agents"
|
||||
@@ -4794,6 +4831,7 @@ msgstr "Décrivez ce que vous voulez que l'IA fasse..."
|
||||
|
||||
#. js-lingui-id: Nu4oKW
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldEdit.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/ai/SettingsToolDetail.tsx
|
||||
@@ -5339,16 +5377,16 @@ msgstr "L'adresse e-mail doit être valide"
|
||||
msgid "Email or domain is already in blocklist"
|
||||
msgstr "Le courriel ou le domaine est déjà dans la liste de blocage"
|
||||
|
||||
#. js-lingui-id: Xl929X
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Email sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: jvneza
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Email support"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +VjrH/
|
||||
#: src/modules/side-panel/hooks/useOpenEmailThreadInSidePanel.ts
|
||||
msgid "Email Thread"
|
||||
msgstr "Fil de discussion e-mail"
|
||||
|
||||
#. js-lingui-id: LimKOG
|
||||
#: src/pages/settings/security/SettingsSecurityApprovedAccessDomain.tsx
|
||||
msgid "Email verification"
|
||||
@@ -6433,6 +6471,12 @@ msgstr ""
|
||||
msgid "Failed to save workspace instructions"
|
||||
msgstr "Impossible d'enregistrer les instructions de l'espace de travail"
|
||||
|
||||
#. js-lingui-id: Lo/GQ5
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Failed to send email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: aj02T8
|
||||
#: src/modules/settings/admin-panel/health-status/maintenance-mode/components/SettingsAdminMaintenanceMode.tsx
|
||||
msgid "Failed to set maintenance mode."
|
||||
@@ -6924,6 +6968,11 @@ msgstr "Crédits d'essai gratuits épuisés. Abonnez-vous maintenant pour contin
|
||||
msgid "French"
|
||||
msgstr "Français"
|
||||
|
||||
#. js-lingui-id: ejVYRQ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qR8gT9
|
||||
#: src/modules/workflow/workflow-trigger/utils/cron-to-human/descriptors/getDayOfWeekDescription.ts
|
||||
msgid "from {startDay} to {endDay}"
|
||||
@@ -8571,7 +8620,7 @@ msgid "Loading skills..."
|
||||
msgstr "Chargement des compétences..."
|
||||
|
||||
#. js-lingui-id: 7YK6ap
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadWidget.tsx
|
||||
msgid "Loading thread"
|
||||
msgstr "Chargement du fil de discussion"
|
||||
|
||||
@@ -9223,10 +9272,10 @@ msgstr "mySkill"
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/data-model/constants/SettingsObjectTableMetadata.ts
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationGeneralTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTable.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
@@ -9392,6 +9441,11 @@ msgstr "Nouveau chat"
|
||||
msgid "New conversation"
|
||||
msgstr "Nouvelle conversation"
|
||||
|
||||
#. js-lingui-id: 3RwJHq
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
msgid "New Email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: wqoYqp
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
@@ -9590,6 +9644,11 @@ msgstr "Aucune clé API disponible"
|
||||
msgid "No API keys match your search"
|
||||
msgstr "Aucune clé API ne correspond à votre recherche"
|
||||
|
||||
#. js-lingui-id: /VRg8Z
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "No application found"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: rxBnh8
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
msgid "No applications available"
|
||||
@@ -10018,6 +10077,7 @@ msgid "No variables found"
|
||||
msgstr "Aucune variable trouvée"
|
||||
|
||||
#. js-lingui-id: OCektF
|
||||
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationDetailEnvironmentVariablesTable.tsx
|
||||
msgid "No variables to set for this application"
|
||||
msgstr ""
|
||||
@@ -10133,6 +10193,11 @@ msgstr "maintenant"
|
||||
msgid "Npm package"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: p7abaY
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "NPM packages"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: VVexZo
|
||||
#: src/modules/advanced-text-editor/extensions/slash-command/DefaultSlashCommands.ts
|
||||
msgid "number"
|
||||
@@ -11357,10 +11422,11 @@ msgstr ""
|
||||
msgid "Read your profile"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tCXcL7
|
||||
#. js-lingui-id: 6pSHJ5
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "Lecture seule — géré par Twenty"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
@@ -11382,6 +11448,11 @@ msgstr "Recevoir un email contenant un lien de mise à jour du mot de passe"
|
||||
msgid "Recent Events (oldest → newest)"
|
||||
msgstr "Événements récents (du plus ancien au plus récent)"
|
||||
|
||||
#. js-lingui-id: yPrbsy
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Recipients"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: b2+5uV
|
||||
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
|
||||
msgid "Recommended Models"
|
||||
@@ -11733,7 +11804,8 @@ msgid "Reorder options"
|
||||
msgstr "Réordonner les options"
|
||||
|
||||
#. js-lingui-id: ImOQa9
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailThreadBottomBar.tsx
|
||||
msgid "Reply"
|
||||
msgstr "Répondre"
|
||||
@@ -11743,6 +11815,11 @@ msgstr "Répondre"
|
||||
msgid "Reply to all"
|
||||
msgstr "Répondre à tous"
|
||||
|
||||
#. js-lingui-id: fiPYZo
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Reply..."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tbmZmI
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Report and issue"
|
||||
@@ -11768,6 +11845,7 @@ msgstr "Renvoyer l'email"
|
||||
#. js-lingui-id: OfhWJH
|
||||
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
|
||||
#: src/modules/views/components/ViewBarDetails.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "Reset"
|
||||
msgstr "Réinitialiser"
|
||||
|
||||
@@ -11788,6 +11866,8 @@ msgid "Reset to"
|
||||
msgstr "Réinitialiser à"
|
||||
|
||||
#. js-lingui-id: L+rMC9
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/command-menu-item/server-items/edit/components/SidePanelCommandMenuItemEditPage.tsx
|
||||
msgid "Reset to default"
|
||||
@@ -12086,11 +12166,6 @@ msgstr "Enregistrer"
|
||||
msgid "Save as new view"
|
||||
msgstr "Enregistrer comme nouvelle vue"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
msgstr "Générez le squelette d'une nouvelle application, puis utilisez la CLI pour développer, publier et distribuer"
|
||||
|
||||
#. js-lingui-id: gmB6oO
|
||||
#: src/modules/workflow/workflow-trigger/components/CronExpressionHelper.tsx
|
||||
msgid "Schedule"
|
||||
@@ -12232,6 +12307,7 @@ msgid "Search an agent..."
|
||||
msgstr "Rechercher un agent..."
|
||||
|
||||
#. js-lingui-id: fGTI3o
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
msgid "Search an application"
|
||||
@@ -12686,6 +12762,13 @@ msgstr "Sélectionnez les modèles qui apparaissent comme recommandés dans le s
|
||||
msgid "Select your preferred language"
|
||||
msgstr "Sélectionnez votre langue préférée"
|
||||
|
||||
#. js-lingui-id: JlFcis
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mjK8F3
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
msgid "Send an invite email to your team"
|
||||
@@ -13401,6 +13484,8 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Subject"
|
||||
msgstr "Objet"
|
||||
|
||||
@@ -13641,11 +13726,6 @@ msgstr ""
|
||||
msgid "System Prompt"
|
||||
msgstr "Invite système"
|
||||
|
||||
#. js-lingui-id: BXGTWI
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "System Prompt ({totalTokenCount})"
|
||||
msgstr "Invite système ({totalTokenCount})"
|
||||
|
||||
#. js-lingui-id: k+7QWO
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
|
||||
msgid "System relations"
|
||||
@@ -14134,6 +14214,11 @@ msgstr ""
|
||||
msgid "This week"
|
||||
msgstr "Cette semaine"
|
||||
|
||||
#. js-lingui-id: VbVocX
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4VeOo
|
||||
#: src/modules/settings/billing/hooks/useBillingWording.ts
|
||||
msgid "This will cancel the scheduled interval change and keep your current billing interval ({currentIntervalLabel})."
|
||||
@@ -14249,6 +14334,7 @@ msgstr "titre"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "To"
|
||||
msgstr "À"
|
||||
|
||||
@@ -14550,7 +14636,6 @@ msgstr "Configuration de l'authentification à deux facteurs terminée avec succ
|
||||
|
||||
#. js-lingui-id: +zy2Nq
|
||||
#: src/pages/settings/data-model/SettingsObjectIndexTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
#: src/pages/settings/ai/components/SettingsToolParameterTable.tsx
|
||||
@@ -14573,6 +14658,11 @@ msgstr "Tapez '/' pour les commandes, '@' pour les mentions"
|
||||
msgid "Type anything..."
|
||||
msgstr "Tapez n'importe quoi..."
|
||||
|
||||
#. js-lingui-id: LaEX5I
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Type something or press \"/\" to see commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UhqKcC
|
||||
#: src/modules/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemRecordSubPage.tsx
|
||||
msgid "Type to search records"
|
||||
@@ -14900,6 +14990,11 @@ msgstr "Passez à un forfait supérieur pour y accéder"
|
||||
msgid "Upgrade to Enterprise to access audit logs."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: D+7y/3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "Upgrade to Enterprise to share private applications."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +Gi3x1
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationVersionContainer.tsx
|
||||
@@ -15336,7 +15431,6 @@ msgstr "Afficher les journaux"
|
||||
|
||||
#. js-lingui-id: 7PrSCy
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View marketplace page"
|
||||
msgstr "Voir la page de la marketplace"
|
||||
|
||||
@@ -15350,6 +15444,11 @@ msgstr ""
|
||||
msgid "View Previous AI Chats"
|
||||
msgstr "Voir les Discussions AI Précédentes"
|
||||
|
||||
#. js-lingui-id: NnJpTN
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View private application page"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: hAAsm/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx
|
||||
msgid "View role"
|
||||
@@ -15944,6 +16043,11 @@ msgstr "Vous appartenez déjà à cet espace de travail"
|
||||
msgid "You are not allowed to create records for this object"
|
||||
msgstr "Vous n'êtes pas autorisé à créer des enregistrements pour cet objet"
|
||||
|
||||
#. js-lingui-id: iibZbD
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "You can either create a private app or share it to others"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: CNAoaw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/logic-function-action/components/WorkflowEditActionLogicFunction.tsx
|
||||
msgid "You can see the function logic in your application settings."
|
||||
@@ -16019,10 +16123,10 @@ msgstr "Votre compte a été activé."
|
||||
msgid "Your app version is out of date. Please refresh the page."
|
||||
msgstr "Votre version de l'application est obsolète. Veuillez rafraîchir la page."
|
||||
|
||||
#. js-lingui-id: oNUh7z
|
||||
#. js-lingui-id: 9pWhO+
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Your Apps"
|
||||
msgstr "Vos applications"
|
||||
msgid "Your apps"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +5YqGH
|
||||
#: src/modules/onboarding/constants/OnboardingSyncEmailsOptions.ts
|
||||
|
||||
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
@@ -316,6 +316,11 @@ msgstr "{jobCount, plural, one {זה יסיר אותה מהתור לצמיתות
|
||||
msgid "{jobCount, plural, one {This will retry the selected job. It will be re-executed from the beginning.} other {This will retry the selected jobs. They will be re-executed from the beginning.}}"
|
||||
msgstr "{jobCount, plural, one {זה ינסה להפעיל מחדש את העבודה הנבחרת. היא תבוצע שוב מההתחלה.} two {זה ינסה להפעיל מחדש את העבודות הנבחרות. הן תבוצענה שוב מההתחלה.} many {זה ינסה להפעיל מחדש את העבודות הנבחרות. הן תבוצענה שוב מההתחלה.} other {זה ינסה להפעיל מחדש את העבודות הנבחרות. הן תבוצענה שוב מההתחלה.}}"
|
||||
|
||||
#. js-lingui-id: Y32cMj
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadIntermediaryMessages.tsx
|
||||
msgid "{messagesLength} emails"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Koe99p
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationItemTableRow.tsx
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx
|
||||
@@ -451,11 +456,13 @@ msgstr "{workspaceMemberName} יוסר מהתפקיד הבא:"
|
||||
msgid "••••••••"
|
||||
msgstr "••••••••"
|
||||
|
||||
#. js-lingui-id: tD9raa
|
||||
#. js-lingui-id: SMgdEJ
|
||||
#. placeholder {0}: formatNumber(preview.estimatedTokenCount, { abbreviate: true, decimals: 1, })
|
||||
#. placeholder {0}: formatNumber( section.estimatedTokenCount, { abbreviate: true, decimals: 1, }, )
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~{0} tokens"
|
||||
msgstr "~{0} אסימונים"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "~ {0} tokens"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: Cx0xl3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/delay-actions/components/WorkflowEditActionDelay.tsx
|
||||
@@ -1702,6 +1709,7 @@ msgstr "אירעה שגיאה בעת העלאת התמונה."
|
||||
#: src/modules/views/hooks/internal/usePerformViewAPIPersist.ts
|
||||
#: src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts
|
||||
#: src/modules/page-layout/hooks/useUpdatePageLayoutWithTabsAndWidgets.ts
|
||||
#: src/modules/page-layout/hooks/useResetPageLayoutWidgetToDefault.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneObjectMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useUpdateOneFieldMetadataItem.ts
|
||||
#: src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts
|
||||
@@ -1984,6 +1992,11 @@ msgstr "דומיינים מאושרים"
|
||||
msgid "Apps"
|
||||
msgstr "אפליקציות"
|
||||
|
||||
#. js-lingui-id: dEnE1D
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Apps made by other developers published on npm"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8HV3WN
|
||||
#: src/pages/settings/profile/appearance/components/LocalePicker.tsx
|
||||
msgid "Arabic"
|
||||
@@ -2408,6 +2421,12 @@ msgstr "כתובת URL בסיסית"
|
||||
msgid "Base URL is required"
|
||||
msgstr "נדרשת כתובת URL בסיסית"
|
||||
|
||||
#. js-lingui-id: /xLNEx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: PFohi3
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "BCC"
|
||||
@@ -2711,9 +2730,11 @@ msgstr "לא ניתן לסרוק? העתק את"
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
|
||||
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
|
||||
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Cancel"
|
||||
msgstr "בטל"
|
||||
|
||||
@@ -2753,6 +2774,11 @@ msgstr "ביטול החלפת תכנית"
|
||||
msgid "Cancel plan switching?"
|
||||
msgstr "האם לבטל את החלפת התכנית?"
|
||||
|
||||
#. js-lingui-id: AnRu/j
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Cancel reply"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: N6gPiD
|
||||
#: src/pages/settings/enterprise/SettingsEnterprise.tsx
|
||||
#: src/modules/settings/billing/components/SettingsBillingContent.tsx
|
||||
@@ -2821,11 +2847,22 @@ msgstr "קטלאנית"
|
||||
msgid "Category"
|
||||
msgstr "קטגוריה"
|
||||
|
||||
#. js-lingui-id: RpYfjZ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: XdZeJk
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
msgid "CC"
|
||||
msgstr "CC"
|
||||
|
||||
#. js-lingui-id: Dgsw8A
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Cc/Bcc"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tHntRt
|
||||
#: src/modules/page-layout/widgets/standalone-rich-text/components/DashboardEditorSideMenu.tsx
|
||||
#: src/modules/blocknote-editor/components/CustomSideMenu.tsx
|
||||
@@ -3776,11 +3813,6 @@ msgstr "צור"
|
||||
msgid "Create"
|
||||
msgstr "צור"
|
||||
|
||||
#. js-lingui-id: 5XhrY3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create & Develop"
|
||||
msgstr "יצירה ופיתוח"
|
||||
|
||||
#. js-lingui-id: 8aATyU
|
||||
#: src/modules/ai/components/suggested-prompts/default-suggested-prompts.ts
|
||||
msgid "Create a dashboard"
|
||||
@@ -3821,6 +3853,11 @@ msgstr "צור זרימת עבודה וחזור לכאן כדי לצפות בג
|
||||
msgid "Create a workspace"
|
||||
msgstr "צור מרחב עבודה"
|
||||
|
||||
#. js-lingui-id: /WlFSf
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Create an application"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: 8ZjIgO
|
||||
#: src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
|
||||
msgid "Create and configure AI agents"
|
||||
@@ -4794,6 +4831,7 @@ msgstr "תאר מה אתה רוצה שהבינה המלאכותית תעשה..."
|
||||
|
||||
#. js-lingui-id: Nu4oKW
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldEdit.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/ai/SettingsToolDetail.tsx
|
||||
@@ -5339,16 +5377,16 @@ msgstr "יש להזין כתובת דוא\"ל תקינה"
|
||||
msgid "Email or domain is already in blocklist"
|
||||
msgstr "דוא\"ל או תחום כבר נמצאים ברשימת החסימה"
|
||||
|
||||
#. js-lingui-id: Xl929X
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Email sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: jvneza
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Email support"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +VjrH/
|
||||
#: src/modules/side-panel/hooks/useOpenEmailThreadInSidePanel.ts
|
||||
msgid "Email Thread"
|
||||
msgstr "שרשור דוא\"ל"
|
||||
|
||||
#. js-lingui-id: LimKOG
|
||||
#: src/pages/settings/security/SettingsSecurityApprovedAccessDomain.tsx
|
||||
msgid "Email verification"
|
||||
@@ -6433,6 +6471,12 @@ msgstr ""
|
||||
msgid "Failed to save workspace instructions"
|
||||
msgstr "אירע כשל בשמירת הנחיות סביבת העבודה"
|
||||
|
||||
#. js-lingui-id: Lo/GQ5
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
#: src/modules/activities/emails/hooks/useSendEmail.ts
|
||||
msgid "Failed to send email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: aj02T8
|
||||
#: src/modules/settings/admin-panel/health-status/maintenance-mode/components/SettingsAdminMaintenanceMode.tsx
|
||||
msgid "Failed to set maintenance mode."
|
||||
@@ -6924,6 +6968,11 @@ msgstr "קרדיטי הניסיון בחינם אזלו. הירשם כעת כד
|
||||
msgid "French"
|
||||
msgstr "צרפתית"
|
||||
|
||||
#. js-lingui-id: ejVYRQ
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "From"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: qR8gT9
|
||||
#: src/modules/workflow/workflow-trigger/utils/cron-to-human/descriptors/getDayOfWeekDescription.ts
|
||||
msgid "from {startDay} to {endDay}"
|
||||
@@ -8571,7 +8620,7 @@ msgid "Loading skills..."
|
||||
msgstr "טוען מיומנויות..."
|
||||
|
||||
#. js-lingui-id: 7YK6ap
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadWidget.tsx
|
||||
msgid "Loading thread"
|
||||
msgstr "טוען שרשור"
|
||||
|
||||
@@ -9223,10 +9272,10 @@ msgstr "mySkill"
|
||||
#: src/pages/settings/developers/api-keys/SettingsDevelopersApiKeyDetail.tsx
|
||||
#: src/pages/settings/data-model/SettingsObjectFieldTable.tsx
|
||||
#: src/pages/settings/data-model/constants/SettingsObjectTableMetadata.ts
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationGeneralTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationNameDescriptionTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTable.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
@@ -9392,6 +9441,11 @@ msgstr "צ'אט חדש"
|
||||
msgid "New conversation"
|
||||
msgstr "שיחה חדשה"
|
||||
|
||||
#. js-lingui-id: 3RwJHq
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
msgid "New Email"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: wqoYqp
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
#: src/pages/settings/emailing-domains/SettingsNewEmailingDomain.tsx
|
||||
@@ -9590,6 +9644,11 @@ msgstr "אין מפתחות API זמינים"
|
||||
msgid "No API keys match your search"
|
||||
msgstr "לא נמצאו מפתחות API תואמים לחיפוש שלך"
|
||||
|
||||
#. js-lingui-id: /VRg8Z
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "No application found"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: rxBnh8
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
msgid "No applications available"
|
||||
@@ -10018,6 +10077,7 @@ msgid "No variables found"
|
||||
msgstr "לא נמצאו משתנים"
|
||||
|
||||
#. js-lingui-id: OCektF
|
||||
#: src/pages/settings/applications/SettingsApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationDetailEnvironmentVariablesTable.tsx
|
||||
msgid "No variables to set for this application"
|
||||
msgstr ""
|
||||
@@ -10133,6 +10193,11 @@ msgstr "עכשיו"
|
||||
msgid "Npm package"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: p7abaY
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "NPM packages"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: VVexZo
|
||||
#: src/modules/advanced-text-editor/extensions/slash-command/DefaultSlashCommands.ts
|
||||
msgid "number"
|
||||
@@ -11357,10 +11422,11 @@ msgstr ""
|
||||
msgid "Read your profile"
|
||||
msgstr "קריאת הפרופיל שלך"
|
||||
|
||||
#. js-lingui-id: tCXcL7
|
||||
#. js-lingui-id: 6pSHJ5
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only — managed by Twenty"
|
||||
msgstr "קריאה בלבד — מנוהל על ידי Twenty"
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "Read-only"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: W+ApAD
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
@@ -11382,6 +11448,11 @@ msgstr "\\"
|
||||
msgid "Recent Events (oldest → newest)"
|
||||
msgstr "אירועים אחרונים (ישן → חדש)"
|
||||
|
||||
#. js-lingui-id: yPrbsy
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Recipients"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: b2+5uV
|
||||
#: src/modules/settings/admin-panel/ai/components/SettingsAdminAI.tsx
|
||||
msgid "Recommended Models"
|
||||
@@ -11733,7 +11804,8 @@ msgid "Reorder options"
|
||||
msgstr "סדר אופציות מחדש"
|
||||
|
||||
#. js-lingui-id: ImOQa9
|
||||
#: src/modules/side-panel/pages/message-thread/components/SidePanelMessageThreadPage.tsx
|
||||
#: src/modules/side-panel/hooks/useOpenComposeEmailInSidePanel.ts
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailThreadBottomBar.tsx
|
||||
msgid "Reply"
|
||||
msgstr "תגובה"
|
||||
@@ -11743,6 +11815,11 @@ msgstr "תגובה"
|
||||
msgid "Reply to all"
|
||||
msgstr "השב לכולם"
|
||||
|
||||
#. js-lingui-id: fiPYZo
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
msgid "Reply..."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: tbmZmI
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
msgid "Report and issue"
|
||||
@@ -11768,6 +11845,7 @@ msgstr "שלח שוב את הדוא\"ל"
|
||||
#. js-lingui-id: OfhWJH
|
||||
#: src/pages/settings/admin-panel/SettingsAdminConfigVariableDetails.tsx
|
||||
#: src/modules/views/components/ViewBarDetails.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "Reset"
|
||||
msgstr "איפוס"
|
||||
|
||||
@@ -11788,6 +11866,8 @@ msgid "Reset to"
|
||||
msgstr "\\"
|
||||
|
||||
#. js-lingui-id: L+rMC9
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
#: src/modules/settings/data-model/fields/forms/address/components/SettingsDataModelFieldAddressForm.tsx
|
||||
#: src/modules/command-menu-item/server-items/edit/components/SidePanelCommandMenuItemEditPage.tsx
|
||||
msgid "Reset to default"
|
||||
@@ -12086,11 +12166,6 @@ msgstr "שמור"
|
||||
msgid "Save as new view"
|
||||
msgstr "שמור כתצוגה חדשה"
|
||||
|
||||
#. js-lingui-id: veLq3R
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Scaffold a new app, then use the CLI to develop, publish, and distribute"
|
||||
msgstr "צור שלד לאפליקציה חדשה, ולאחר מכן השתמש ב-CLI כדי לפתח, לפרסם ולהפיץ"
|
||||
|
||||
#. js-lingui-id: gmB6oO
|
||||
#: src/modules/workflow/workflow-trigger/components/CronExpressionHelper.tsx
|
||||
msgid "Schedule"
|
||||
@@ -12232,6 +12307,7 @@ msgid "Search an agent..."
|
||||
msgstr "חפש סוכן..."
|
||||
|
||||
#. js-lingui-id: fGTI3o
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsAvailableTab.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationsTable.tsx
|
||||
msgid "Search an application"
|
||||
@@ -12686,6 +12762,13 @@ msgstr "בחרו אילו מודלים יופיעו כמומלצים בבורר
|
||||
msgid "Select your preferred language"
|
||||
msgstr "\\"
|
||||
|
||||
#. js-lingui-id: JlFcis
|
||||
#: src/modules/side-panel/pages/compose-email/components/SidePanelComposeEmailPage.tsx
|
||||
#: src/modules/page-layout/widgets/email-thread/components/EmailThreadComposer.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposer.tsx
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: mjK8F3
|
||||
#: src/pages/settings/members/SettingsWorkspaceMembers.tsx
|
||||
msgid "Send an invite email to your team"
|
||||
@@ -13401,6 +13484,8 @@ msgstr ""
|
||||
|
||||
#. js-lingui-id: UJmAAK
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Subject"
|
||||
msgstr "נושא"
|
||||
|
||||
@@ -13641,11 +13726,6 @@ msgstr ""
|
||||
msgid "System Prompt"
|
||||
msgstr "הנחיית מערכת"
|
||||
|
||||
#. js-lingui-id: BXGTWI
|
||||
#: src/pages/settings/ai/SettingsAIPrompts.tsx
|
||||
msgid "System Prompt ({totalTokenCount})"
|
||||
msgstr "הנחיית מערכת ({totalTokenCount})"
|
||||
|
||||
#. js-lingui-id: k+7QWO
|
||||
#: src/modules/settings/data-model/object-details/components/SettingsObjectRelationsTable.tsx
|
||||
msgid "System relations"
|
||||
@@ -14132,6 +14212,11 @@ msgstr ""
|
||||
msgid "This week"
|
||||
msgstr "השבוע"
|
||||
|
||||
#. js-lingui-id: VbVocX
|
||||
#: src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutFieldsSettings.tsx
|
||||
msgid "This will cancel all modifications done on the widget. This action cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: h4VeOo
|
||||
#: src/modules/settings/billing/hooks/useBillingWording.ts
|
||||
msgid "This will cancel the scheduled interval change and keep your current billing interval ({currentIntervalLabel})."
|
||||
@@ -14247,6 +14332,7 @@ msgstr "כותרת"
|
||||
|
||||
#. js-lingui-id: /jQctM
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "To"
|
||||
msgstr "אל"
|
||||
|
||||
@@ -14548,7 +14634,6 @@ msgstr "הגדרת האימות הדו-שלבי הושלמה בהצלחה!"
|
||||
|
||||
#. js-lingui-id: +zy2Nq
|
||||
#: src/pages/settings/data-model/SettingsObjectIndexTable.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationDataTableRow.tsx
|
||||
#: src/pages/settings/ai/constants/SettingsSkillTableMetadata.ts
|
||||
#: src/pages/settings/ai/constants/SettingsAiAgentTableMetadata.ts
|
||||
#: src/pages/settings/ai/components/SettingsToolParameterTable.tsx
|
||||
@@ -14571,6 +14656,11 @@ msgstr "הקלד/י '/' עבור פקודות, '@' עבור אזכורים"
|
||||
msgid "Type anything..."
|
||||
msgstr "הקלד כל דבר..."
|
||||
|
||||
#. js-lingui-id: LaEX5I
|
||||
#: src/modules/activities/emails/components/EmailComposerFields.tsx
|
||||
msgid "Type something or press \"/\" to see commands"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: UhqKcC
|
||||
#: src/modules/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemRecordSubPage.tsx
|
||||
msgid "Type to search records"
|
||||
@@ -14898,6 +14988,11 @@ msgstr "שדרגו כדי לגשת"
|
||||
msgid "Upgrade to Enterprise to access audit logs."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: D+7y/3
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "Upgrade to Enterprise to share private applications."
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +Gi3x1
|
||||
#: src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
|
||||
#: src/pages/settings/applications/components/SettingsApplicationVersionContainer.tsx
|
||||
@@ -15334,7 +15429,6 @@ msgstr "צפה ביומנים"
|
||||
|
||||
#. js-lingui-id: 7PrSCy
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View marketplace page"
|
||||
msgstr "צפייה בדף המרקטפלייס"
|
||||
|
||||
@@ -15348,6 +15442,11 @@ msgstr ""
|
||||
msgid "View Previous AI Chats"
|
||||
msgstr "הצג שיחות AI קודמות"
|
||||
|
||||
#. js-lingui-id: NnJpTN
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationRegistrationDistributionTab.tsx
|
||||
msgid "View private application page"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: hAAsm/
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx
|
||||
msgid "View role"
|
||||
@@ -15942,6 +16041,11 @@ msgstr "אתה כבר משתייך לסביבת העבודה הזו"
|
||||
msgid "You are not allowed to create records for this object"
|
||||
msgstr "אין לך הרשאה ליצור רשומות באובייקט זה"
|
||||
|
||||
#. js-lingui-id: iibZbD
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "You can either create a private app or share it to others"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: CNAoaw
|
||||
#: src/modules/workflow/workflow-steps/workflow-actions/logic-function-action/components/WorkflowEditActionLogicFunction.tsx
|
||||
msgid "You can see the function logic in your application settings."
|
||||
@@ -16017,10 +16121,10 @@ msgstr "החשבון שלך הופעל."
|
||||
msgid "Your app version is out of date. Please refresh the page."
|
||||
msgstr "גרסת האפליקציה שלך אינה מעודכנת. אנא רענן את הדף."
|
||||
|
||||
#. js-lingui-id: oNUh7z
|
||||
#. js-lingui-id: 9pWhO+
|
||||
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
|
||||
msgid "Your Apps"
|
||||
msgstr "האפליקציות שלך"
|
||||
msgid "Your apps"
|
||||
msgstr ""
|
||||
|
||||
#. js-lingui-id: +5YqGH
|
||||
#: src/modules/onboarding/constants/OnboardingSyncEmailsOptions.ts
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user