Skip to main content
Каждый объект в Twenty содержит системные метаданные, которые вы сами никогда не объявляете, например набор полей и основное представление списка с его столбцами. Сервер создаёт всё это при подготовке объекта, и этот набор растёт по мере развития Twenty. Поскольку вы это не объявляете, у вас нет константы universalIdentifier, которую можно импортировать. Вместо этого сервер выводит каждый идентификатор детерминированным образом, а twenty-sdk предоставляет тот же механизм вывода, чтобы ваш манифест мог получить точное значение, которое использует сервер.

Системные поля

Скалярные поля, присутствующие в каждом объекте, ни одно из которых вы не объявляете с помощью defineField(): id, createdAt, updatedAt, deletedAt, createdBy, updatedBy, position, searchVector Тогда как сослаться на createdAt как на столбец в представлении?

Проблема

Начиная с Twenty 2.19, универсальный идентификатор системного поля детерминированно выводится сервером из трех входных данных: универсального идентификатора приложения, универсального идентификатора объекта и имени поля. Придумать id и захардкодить его не получится: он не соответствует ничему на сервере, и синхронизация отклоняет висящую ссылку:

Решение

getFieldUniversalIdentifier доступен, начиная с twenty-sdk версии 2.21.
Используйте getFieldUniversalIdentifier, чтобы получить в точности то же значение, которое использует сервер. Он принимает три входных параметра и возвращает универсальный идентификатор поля:
  • applicationUniversalIdentifier — это идентификатор вашего приложения, тот, который вы передаете в defineApplication().
  • objectUniversalIdentifier — это идентификатор объекта, к которому принадлежит поле.
  • name — это имя системного поля, одно из значений, перечисленных выше.

Пример: столбец createdAt в представлении

Типичный случай — добавление столбца createdAt в представление одного из ваших пользовательских объектов. Разрешите id поля и ссылайтесь на него так же, как на любой другой fieldMetadataUniversalIdentifier:
src/views/example-view.ts
Тот же разрешенный id работает везде, где ожидается fieldMetadataUniversalIdentifier: поля представления, фильтры, сортировки, группировки и виджеты макета страницы.
Разрешайте id, не хардкодьте его. Поскольку сервер выводит значение из id приложения, id объекта и имени поля, вызов getFieldUniversalIdentifier сохраняет вашу ссылку корректной, даже если эти входные данные изменятся, и предотвращает расхождение, если способ вывода когда-нибудь изменится.

Системные поля связей

getSystemRelationFieldUniversalIdentifier доступен в twenty-sdk, начиная с версии 2.23, и требует сервер Twenty версии 2.23 или новее.
Помимо перечисленных выше скалярных системных полей, сервер также подготавливает четыре системных поля связей для каждого объекта: timelineActivities, attachments, noteTargets и taskTargets, каждое из которых указывает на соответствующий стандартный объект связи. Таким образом, эти поля не разрешаются с помощью getFieldUniversalIdentifier: их идентификатор выводится безотносительно имени из объекта, содержащего поле, и объекта, на который поле указывает. Таким образом, переименование объекта никогда не изменяет идентификаторы его полей связей. Используйте getSystemRelationFieldUniversalIdentifier, чтобы разрешить их:
  • objectUniversalIdentifier — это объект, содержащий поле.
  • relationTargetObjectUniversalIdentifier — это объект, на который указывает поле.
Направление кодируется порядком аргументов. Чтобы получить обратную сторону (например, attachment.targetRocket, morph‑поле, которое сервер создаёт на стандартном объекте связи), поменяйте их местами:
Как и в случае со скалярными системными полями, разрешённый id работает везде, где ожидается fieldMetadataUniversalIdentifier.

Системные представления

getSystemViewUniversalIdentifier и getSystemViewFieldUniversalIdentifier доступны в twenty-sdk, начиная с версии 2.26, и требуют сервер Twenty версии 2.26 или новее.
Сервер также подготавливает системное представление для каждого объекта: основное представление списка (All {objectLabelPlural}, с ключом ViewKey.INDEX (полученным с помощью SYSTEM_VIEW_KEYS.INDEX)), с одним столбцом на каждое отображаемое поле. Как и у системных полей связей, их идентификаторы выводятся без использования имён, поэтому переименование объекта или поля никогда их не меняет. Используйте getSystemViewUniversalIdentifier, чтобы получить идентификатор представления:
  • objectMetadataApplicationUniversalIdentifier — это приложение, которому принадлежит объект, и именно по нему задаётся пространство имён представления.
  • objectUniversalIdentifier — это объект, который отображается в представлении.
  • viewKey — это дискриминатор системного представления: SYSTEM_VIEW_KEYS.INDEX для основного представления списка, SYSTEM_VIEW_KEYS.FIELDS_WIDGET для представления виджета полей на странице записи. Он определяет способ вычисления представления; только INDEX также сохраняется в строке представления.
Полученный идентификатор подходит везде, где ожидается viewUniversalIdentifier, например для пункта боковой панели NavigationMenuItemType.VIEW. Чтобы просто открыть основной список объекта, предпочитайте NavigationMenuItemType.OBJECT с targetObjectUniversalIdentifier: здесь не нужен вывод идентификатора. getSystemViewFieldUniversalIdentifier определяет идентификатор одного столбца в системном представлении по самому представлению и отображаемому в нём полю:
Обратите внимание на первый аргумент: пространство имён столбца задаётся приложением, которому принадлежит поле, отображаемое в нём, а не приложением, которому принадлежит представление. Поле, которое ваше приложение добавляет к стандартному объекту, получает свой столбец, выводимый в пространстве имён вашего приложения, на представлении, принадлежащем Twenty.
Системные представления и их столбцы принадлежат серверу: разрешайте их идентификаторы, чтобы ссылаться на них, но никогда не объявляйте их сами. key в defineView() устарел и игнорируется, поэтому представление из манифеста никогда не может заявить ключ INDEX, а сервер уже подготавливает столбец для каждого добавленного вами поля, так что объявление собственного defineViewField() для того же поля в системном представлении конфликтует с ним.

Стандартные объекты Twenty

Для стандартного объекта Twenty (Person, Company, Opportunity, …) вам не нужно ничего выводить: идентификаторы как полей, так и представлений — это заранее вычисленные константы, которые вы можете импортировать напрямую.
Используйте указанные выше вспомогательные функции, когда объект — это объект, который ваше приложение определяет с помощью defineObject(), где такой константы не существует.
name — это поле по умолчанию, а не системное поле. У него есть собственный захардкоженный универсальный идентификатор, и он не разрешается через getFieldUniversalIdentifier. В определяемых вами объектах ссылайтесь на поле name по идентификатору, который вы задали ему в defineObject().