Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s
205 lines
11 KiB
Plaintext
205 lines
11 KiB
Plaintext
---
|
||
title: Sistem Meta Verilerini Hedefleme
|
||
description: Twenty meta verilerinin deterministik evrensel tanımlayıcılarını her nesnede otomatik olarak çözümleyin; böylece uygulamanız bunlara, değerleri kodun içine gömmek zorunda kalmadan başvurabilir.
|
||
icon: gears
|
||
---
|
||
|
||
Twenty içindeki her nesne, kendi başınıza asla bildirmediğiniz **sistem meta verileriyle** birlikte gelir; bir alan kümesi ve sütunlarıyla birlikte ana liste görünümü gibi. Sunucu, nesne sağlandığında bunların hepsini oluşturur ve Twenty büyüdükçe bu küme de büyür.
|
||
|
||
Siz bunu bildirmediğiniz için, içe aktarabileceğiniz bir `universalIdentifier` sabiti yoktur. Bunun yerine, sunucu her tanımlayıcıyı deterministik olarak **türetir** ve `twenty-sdk`, bildirim dosyanızın sunucunun kullandığı kesin değeri çözümleyebilmesi için aynı türetmeyi dışa açar.
|
||
|
||
## Sistem Alanları
|
||
|
||
Her nesnede bulunan, hiçbirini [`defineField()`](/l/tr/developers/extend/apps/data/extending-objects) ile bildirmediğiniz skaler alanlar:
|
||
|
||
`id`, `createdAt`, `updatedAt`, `deletedAt`, `createdBy`, `updatedBy`, `position`, `searchVector`
|
||
|
||
Peki bir [görünümde](/l/tr/developers/extend/apps/layout/views) `createdAt` alanına sütun olarak nasıl referans verirsiniz?
|
||
|
||
### Sorun
|
||
|
||
Twenty 2.19'dan beri, bir sistem alanının evrensel tanımlayıcısı, sunucu tarafından üç girdiden **deterministik olarak türetilir**: uygulama evrensel tanımlayıcısı, nesne evrensel tanımlayıcısı ve alan adı. Rastgele bir id uydurup onu hardcode etmek işe yaramaz: sunucudaki hiçbir şeyle eşleşmez ve senkronizasyon, askıda kalan referansı reddeder:
|
||
|
||
```
|
||
Dev sync failed: viewField: INVALID_VIEW_DATA: Field metadata not found
|
||
```
|
||
|
||
### Çözüm
|
||
|
||
<Note>
|
||
`getFieldUniversalIdentifier`, `twenty-sdk` 2.21 sürümünden itibaren kullanılabilir.
|
||
</Note>
|
||
|
||
Sunucunun kullandığıyla tamamen aynı değeri elde etmek için `getFieldUniversalIdentifier` kullanın. Üç girdiyi alır ve alanın evrensel tanımlayıcısını döndürür:
|
||
|
||
```ts
|
||
import { getFieldUniversalIdentifier } from 'twenty-sdk/define';
|
||
|
||
const createdAtFieldId = getFieldUniversalIdentifier({
|
||
applicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
|
||
objectUniversalIdentifier: MY_OBJECT_UNIVERSAL_IDENTIFIER,
|
||
name: 'createdAt',
|
||
});
|
||
```
|
||
|
||
* `applicationUniversalIdentifier`, uygulamanızın tanımlayıcısıdır; [`defineApplication()`](/l/tr/developers/extend/apps/config/application) çağrısına aktardığınız tanımlayıcı.
|
||
* `objectUniversalIdentifier`, alanın ait olduğu nesnenin tanımlayıcısıdır.
|
||
* `name`, sistem alan adıdır; yukarıda listelenen değerlerden biridir.
|
||
|
||
### Örnek: bir görünümde createdAt sütunu
|
||
|
||
Tipik durum, özel nesnelerinizden birinin görünümüne bir `createdAt` sütunu eklemektir. Alan id'sini çözümleyin ve ona, herhangi bir `fieldMetadataUniversalIdentifier` gibi referans verin:
|
||
|
||
```ts src/views/example-view.ts
|
||
import {
|
||
defineView,
|
||
getFieldUniversalIdentifier,
|
||
} from 'twenty-sdk/define';
|
||
|
||
const APPLICATION_UNIVERSAL_IDENTIFIER =
|
||
'0b04e15c-27b2-4741-9046-b32e07469072';
|
||
const MY_OBJECT_UNIVERSAL_IDENTIFIER =
|
||
'c782b61c-70fd-4c88-9cd6-4e61ab8d7591';
|
||
|
||
export default defineView({
|
||
universalIdentifier: '70f10d44-144a-4da8-8c6f-3ec2422138c0',
|
||
name: 'All records',
|
||
objectUniversalIdentifier: MY_OBJECT_UNIVERSAL_IDENTIFIER,
|
||
icon: 'IconList',
|
||
position: 0,
|
||
fields: [
|
||
{
|
||
universalIdentifier: '75a90bc4-d901-4df4-85e0-af29db5e0104',
|
||
fieldMetadataUniversalIdentifier: getFieldUniversalIdentifier({
|
||
applicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
|
||
objectUniversalIdentifier: MY_OBJECT_UNIVERSAL_IDENTIFIER,
|
||
name: 'createdAt',
|
||
}),
|
||
position: 0,
|
||
isVisible: true,
|
||
size: 200,
|
||
},
|
||
],
|
||
});
|
||
```
|
||
|
||
Aynı çözümlenen id, bir `fieldMetadataUniversalIdentifier` beklendiği her yerde çalışır: görünüm alanları, filtreler, sıralamalar, gruplar ve sayfa düzeni bileşenleri.
|
||
|
||
<Note>
|
||
Id'yi çözümleyin, hardcode etmeyin. Sunucu değeri uygulama id'si, nesne id'si ve alan adından
|
||
türettiği için, `getFieldUniversalIdentifier` çağrısı, bu girdiler değişse bile referansınızı doğru tutar ve türetme zaman içinde gelişirse sapmayı önler.
|
||
</Note>
|
||
|
||
### Sistem ilişki alanları
|
||
|
||
<Note>
|
||
`getSystemRelationFieldUniversalIdentifier` 2.23 sürümünden itibaren `twenty-sdk` içinde kullanılabilir ve Twenty sunucusunun 2.23 veya daha yeni bir sürümünü gerektirir.
|
||
</Note>
|
||
|
||
Yukarıdaki skaler sistem alanlarının yanı sıra, sunucu her nesne üzerinde dört **sistem ilişki alanı** da sağlar: `timelineActivities`, `attachments`, `noteTargets` ve `taskTargets`. Bunların her biri, karşılık gelen standart ilişki nesnesini işaret eder.
|
||
|
||
Bu alanlar `getFieldUniversalIdentifier` ile çözümlenmez: tanımlayıcıları, alanı barındıran nesne ve alanın işaret ettiği nesneden **isimden bağımsız** olarak türetilir. Bu sayede bir nesnenin adını değiştirmek, ilişki alanlarının tanımlayıcılarını asla değiştirmez.
|
||
|
||
Bunları çözümlemek için `getSystemRelationFieldUniversalIdentifier` kullanın:
|
||
|
||
```ts
|
||
import {
|
||
getSystemRelationFieldUniversalIdentifier,
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
|
||
} from 'twenty-sdk/define';
|
||
|
||
// rocket.attachments — the relation field hosted on your custom object
|
||
const rocketAttachmentsFieldId = getSystemRelationFieldUniversalIdentifier({
|
||
applicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
|
||
objectUniversalIdentifier: ROCKET_OBJECT_UNIVERSAL_IDENTIFIER,
|
||
relationTargetObjectUniversalIdentifier:
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.attachment.universalIdentifier,
|
||
});
|
||
```
|
||
|
||
* `objectUniversalIdentifier`, alanın **barındırıldığı** nesnedir.
|
||
* `relationTargetObjectUniversalIdentifier`, alanın **işaret ettiği** nesnedir.
|
||
|
||
Yön, argüman sırasına göre kodlanır. Ters tarafı çözümlemek için (örneğin, `attachment.targetRocket`, sunucunun standart ilişki nesnesi üzerinde oluşturduğu morph alanı), ikisini değiştirin:
|
||
|
||
```ts
|
||
// attachment.targetRocket — the reverse morph field on Attachment
|
||
const attachmentTargetRocketFieldId =
|
||
getSystemRelationFieldUniversalIdentifier({
|
||
applicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
|
||
objectUniversalIdentifier:
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.attachment.universalIdentifier,
|
||
relationTargetObjectUniversalIdentifier: ROCKET_OBJECT_UNIVERSAL_IDENTIFIER,
|
||
});
|
||
```
|
||
|
||
Skaler sistem alanlarında olduğu gibi, çözümlenen kimlik, `fieldMetadataUniversalIdentifier` beklendiği her yerde çalışır.
|
||
|
||
## Sistem görünümleri
|
||
|
||
<Note>
|
||
`getSystemViewUniversalIdentifier` ve `getSystemViewFieldUniversalIdentifier`, `twenty-sdk` 2.26 sürümünden itibaren kullanılabilir ve Twenty sunucusunun 2.26 veya daha yeni bir sürümünü gerektirir.
|
||
</Note>
|
||
|
||
Sunucu ayrıca her nesnede bir **sistem görünümü** de sağlar: ana liste görünümü (`All {objectLabelPlural}`, `ViewKey.INDEX` ( `SYSTEM_VIEW_KEYS.INDEX` ile türetilmiş) anahtarıyla), gösterilebilir her alan için bir sütunla. Sistem ilişki alanlarında olduğu gibi, tanımlayıcıları **isimden bağımsız** olarak türetilir; bu nedenle bir nesnenin veya alanın adını değiştirmeniz onları asla değiştirmez.
|
||
|
||
Görünümü çözümlemek için `getSystemViewUniversalIdentifier` kullanın:
|
||
|
||
```ts
|
||
import {
|
||
getSystemViewUniversalIdentifier,
|
||
SYSTEM_VIEW_KEYS,
|
||
} from 'twenty-sdk/define';
|
||
|
||
const rocketIndexViewId = getSystemViewUniversalIdentifier({
|
||
objectMetadataApplicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
|
||
objectUniversalIdentifier: ROCKET_OBJECT_UNIVERSAL_IDENTIFIER,
|
||
viewKey: SYSTEM_VIEW_KEYS.INDEX,
|
||
});
|
||
```
|
||
|
||
* `objectMetadataApplicationUniversalIdentifier`, görünümün ad alanını belirleyen, **nesneye** sahip olan uygulamadır.
|
||
* `objectUniversalIdentifier`, görünümün listelediği nesnedir.
|
||
* `viewKey`, sistem görünümü ayırt edicisidir: ana liste görünümü için `SYSTEM_VIEW_KEYS.INDEX`, kayıt sayfası alanları bileşen görünümü için `SYSTEM_VIEW_KEYS.FIELDS_WIDGET`. Türetmenin anahtarını belirler; yalnızca `INDEX` görünüm satırında da saklanır.
|
||
|
||
Çözümlenen kimlik, bir `viewUniversalIdentifier` beklendiği her yerde, örneğin bir [`NavigationMenuItemType.VIEW`](/l/tr/developers/extend/apps/layout/navigation-menu-items) kenar çubuğu girdisinde çalışır. Sadece bir nesnenin ana listesini açmak için, `targetObjectUniversalIdentifier` ile `NavigationMenuItemType.OBJECT` kullanmayı tercih edin: hiçbir türetmeye ihtiyaç duymaz.
|
||
|
||
`getSystemViewFieldUniversalIdentifier`, bir sistem görünümündeki tek bir **sütunu**, görünümden ve görüntülediği alandan yola çıkarak çözümler:
|
||
|
||
```ts
|
||
import { getSystemViewFieldUniversalIdentifier } from 'twenty-sdk/define';
|
||
|
||
const rocketNameColumnId = getSystemViewFieldUniversalIdentifier({
|
||
fieldMetadataApplicationUniversalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
|
||
viewUniversalIdentifier: rocketIndexViewId,
|
||
fieldMetadataUniversalIdentifier: ROCKET_NAME_FIELD_UNIVERSAL_IDENTIFIER,
|
||
});
|
||
```
|
||
|
||
İlk argümana dikkat edin: bir sütun, **görüntülediği alana** sahip olan uygulamanın ad alanındadır, görünüme sahip olanın değil. Uygulamanızın standart bir nesneye eklediği bir alan, Twenty'ye ait bir görünüm üzerinde, kendi uygulamanız altında türetilen bir sütun alır.
|
||
|
||
<Warning>
|
||
Sistem görünümleri ve sütunları **sunucuya aittir**: bunları bildirmek için değil, yalnızca onlara başvurmak için tanımlayıcılarını çözümleyin. [`defineView()`](/l/tr/developers/extend/apps/layout/views) üzerindeki
|
||
`key` kullanımdan kaldırılmıştır ve yok sayılır; bu nedenle bir bildirim görünümü asla `INDEX` anahtarını talep edemez ve sunucu, eklediğiniz her alan için zaten bir sütun sağlar; bu yüzden bir sistem görünümünde aynı alan için kendi `defineViewField()` bildiriminizi yapmak bununla çelişir.
|
||
</Warning>
|
||
|
||
## Standart Twenty nesneleri
|
||
|
||
**Standart** bir Twenty nesnesi (Person, Company, Opportunity, …) için hiçbir şey türetmeniz gerekmez: hem alanlar hem de görünümler için, doğrudan içe aktarabileceğiniz önceden hesaplanmış sabit tanımlayıcılar vardır.
|
||
|
||
```ts
|
||
import { STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS } from 'twenty-sdk/define';
|
||
|
||
// STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.createdAt.universalIdentifier
|
||
// STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.fields.updatedAt.universalIdentifier
|
||
// STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.views.allPeople.universalIdentifier
|
||
```
|
||
|
||
Yukarıdaki yardımcı işlevlere, [`defineObject()`](/l/tr/developers/extend/apps/data/objects) ile **uygulamanızın** tanımladığı ve böyle bir sabitin bulunmadığı nesneler için başvurun.
|
||
|
||
<Note>
|
||
`name`, bir sistem alanı değil, bir **varsayılan** alandır. Kendi hardcode edilmiş
|
||
evrensel tanımlayıcısını korur ve
|
||
`getFieldUniversalIdentifier` ile çözülmez. Tanımladığınız nesnelerde, `name` alanına `defineObject()` içinde ona verdiğiniz tanımlayıcı ile referans verin.
|
||
</Note>
|