Docyrus

RecordActivityPanel

Timeline of a record's Docyrus activity log with per-operation icons, tenant-aware timestamps and translatable copy.

iOSAndroid
Preview RecordActivityPanel on your device

Scan with Expo Go

Download Expo Go, then scan the QR code to preview native components.

Installation

pnpm dlx @docyrus/cli add @docyrus/rn-record-activity-panel
Required Packages(3 packages)
pnpm add @shopify/flash-list react-native-svg react-native-reanimated

Usage

Pass the rows returned by the Docyrus activity-log endpoint as-is — the type matches the backend row shape:

import { RecordActivityPanel } from '@/components/docyrus-native/record-activity-panel';

<RecordActivityPanel
  activities={activityQuery.data ?? []}
  isLoading={activityQuery.isLoading}
  maxItems={20}
/>
  • Rows are sorted newest first (created_on; rows with a null date go last) and capped by maxItems.
  • The text is shortDescription, falling back to description.
  • The actor is firstname lastname, then name, then t('ui.recordActivity.system', 'System').
  • The timestamp uses the explicit dateFormatter, else formatDateTime from a mounted <DateFormatProvider> / <DocyrusTenantProvider> (tenant format + timezone), else Intl (Mar 4, 3:05 PM). Rows without created_on show no timestamp.

Custom copy and labels

<RecordActivityPanel
  activities={activities}
  messages={{ empty: 'Nothing happened yet', system: 'Automation' }}
  operationLabelFormatter={(op) => ({ INSERT: 'created', UPDATE: 'edited' } as Record<string, string>)[op] ?? op}
  dateFormatter={(iso) => format(new Date(iso), 'dd.MM.yyyy HH:mm')}
/>

Operations

OperationIconColour
INSERTfal circle-plusgreen
UPDATEfal pen-to-squareblue
DELETE, TRASHfal trash-canred
STATUS_UPDATEfal arrow-right-arrow-leftyellow
INSERT_COMMENT, UPDATE_COMMENTfal messagepurple
DELETE_COMMENTfal messagered
INSERT_FILE, UPDATE_FILEfal papercliporange
DELETE_FILEfal paperclipred
Legacy native codes (RESTORE, SHARE, UNSHARE, COMMENT, ATTACHMENT, STATUS_CHANGE, ASSIGNMENT, APPROVAL, REJECTION, ESCALATION, MERGE, SPLIT, ARCHIVE, UNARCHIVE, LOCK, UNLOCK, IMPORT, EXPORT)dedicated icons—
Any other stringfal wave-pulsemuted

API Reference

RecordActivityPanelProps

PropTypeDefaultDescription
activitiesRecordActivity[]—Activity rows (backend shape).
messagesRecordActivityPanelMessages—Optional copy overrides; each missing field falls back to useUiTranslation().
isLoadingbooleanfalseShows a spinner, the loading label and skeleton rows.
emptyMessagestring—Empty-state title override (wins over messages.empty).
maxItemsnumber—Limits the rendered rows after sorting newest first (native extra).
showConnectorbooleantrueShows the vertical timeline connector (native extra).
dateFormatter(date: string) => stringDateFormatProvider.formatDateTime, else IntlTimestamp formatter (native extra).
operationLabelFormatter(operation: RecordActivityOperation) => stringlower-cased, _ → spaceOperation label next to the actor (native extra).
classNamestring—Additional container classes.
contentContainerClassNamestring—Additional classes for the list content wrapper.

RecordActivityPanelMessages

All fields are optional.

FieldTypeDefaultDescription
emptystringt('ui.recordActivity.empty', 'No activity yet')Empty-state title.
emptyDescriptionstringt('ui.recordActivity.emptyDescription', 'Activity will appear here when changes are made to this record.')Empty-state hint.
loadingstringt('ui.recordActivity.loading', 'Loading activity…')Loading label.
systemstringt('ui.recordActivity.system', 'System')Actor label when the row has no user (or the user has no name).

RecordActivity

FieldTypeDescription
idstringRow id.
descriptionstringFull description.
shortDescriptionstring | nullShort description — rendered when present.
iconstring | nullBackend icon (not rendered; the operation decides the icon).
colorstring | nullBackend colour (not rendered).
table_namestring | nullPhysical table name.
operationRecordActivityOperationOperation code — open string.
tenant_data_source_id{ id: string; name: string | null } | nullData source reference.
created_onstring | nullISO timestamp.
created_bystring | nullActor user id.
created_by_userRecordActivityUser | nullActor.
data_source_namestring | nullData source display name.
titlestring | nullRecord title.

Every field except id, description, operation and created_on is optional on native, so hand-written rows stay short.

RecordActivityUser

FieldTypeDescription
namestring | nullUsername / display name.
emailstring | nullEmail.
mobilestring | nullMobile number.
firstnamestring | nullFirst name.
lastnamestring | nullLast name.

Components

ComponentDescription
RecordActivityPanelFlashList-backed activity timeline.

Type Exports

TypeDescription
RecordActivityPanelPropsProps for RecordActivityPanel.
RecordActivityActivity row (backend shape).
RecordActivityUserActor.
RecordActivityOperationKnown operation codes | (string & {}).
RecordActivityPanelMessagesOptional copy overrides.

Breaking changes

  • messages is now optional and every field of RecordActivityPanelMessages is optional (defaults come from useUiTranslation()).
  • RecordActivity.created_on is string | null, created_by_user may be null, and RecordActivityUser fields are nullable — code that reads these types must handle null. dateFormatter is only called for non-null dates.
  • Actor order changed to web parity: firstname lastname → name → System. The email fallback was removed.
  • shortDescription is rendered in place of description when present.
  • Timeline dots became 28 px icon circles; the operation label is muted instead of coloured.
  • Without dateFormatter, timestamps now follow a mounted DateFormatProvider (tenant format) before falling back to Intl.

On this page