Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .changeset/approvals-reassign-and-system-actor-display.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
"@object-ui/console": patch
"@object-ui/app-shell": patch
"@object-ui/i18n": patch
---

fix(console,app-shell): readable reassign hand-off + "System" label for svc:* audit actors — objectstack#4365 / objectstack#4366

- **Approvals inbox** (`ApprovalsInboxPage`): a reassign timeline entry now
renders "from A to B" from the structured
`reassign_from`/`reassign_to` fields (and their server-resolved
`*_name` companions) that objectstack#4365 added to
`sys_approval_action`, instead of relying on the old default comment that
baked two raw user ids into user-facing text. Legacy rows without the
structured fields keep the comment fallback. New i18n key
`approvalsInbox.reassignFromTo` across all ten locales.
- **Record history** (`RecordDetailView`): an audit row attributed to a
service principal (`svc:*` on the `actor` column — e.g. a
`runAs:'system'` flow's `svc:flow:<name>` label from objectstack#4366) now
renders the localized "System" label instead of the raw principal string;
the raw value stays on the entry for tooling.
19 changes: 19 additions & 0 deletions apps/console/src/pages/system/ApprovalsInboxPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1904,6 +1904,25 @@ export function ApprovalsInboxPage() {
{formatRelative(a.created_at)}
</span>
</div>
{/* Structured reassign hand-off (framework#4365): render
"from A to B" from the resolved parties. Legacy rows
predate the fields and only carry the old default
comment — those keep the comment fallback below. */}
{(() => {
const ax = a as typeof a & {
reassign_from?: string; reassign_to?: string;
reassign_from_name?: string; reassign_to_name?: string;
};
if (a.action !== 'reassign' || (!ax.reassign_from && !ax.reassign_to)) return null;
return (
<div className="text-muted-foreground mt-0.5">
{tr('reassignFromTo', 'from {{from}} to {{to}}', {
from: ax.reassign_from_name ?? formatIdentity(ax.reassign_from),
to: ax.reassign_to_name ?? formatIdentity(ax.reassign_to),
})}
</div>
);
})()}
{a.comment && (
<div className="text-muted-foreground italic mt-0.5">"{a.comment}"</div>
)}
Expand Down
10 changes: 8 additions & 2 deletions packages/app-shell/src/views/RecordDetailView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1225,12 +1225,18 @@ export function RecordDetailView({ dataSource, objects, onEdit, objectNameOverri
const enriched = items.map((it, idx) => {
const u = it?.user_id ? userMap.get(it.user_id) : undefined;
// Attribution fallback chain: resolved user name → service/automation
// principal from the `actor` column (e.g. "svc:scheduler") → null
// principal from the `actor` column (e.g. "svc:flow:<name>") → null
// (the timeline then shows its localized unknown-user text).
const actorLabel =
// A `svc:*` principal is a machine, not a person — render the
// localized "System" label rather than the raw principal string
// (framework#4366); the raw value stays available on the entry.
const rawActor =
typeof it?.actor === 'string' && it.actor.trim() && it.actor !== it?.user_id
? it.actor.trim()
: null;
const actorLabel = rawActor?.startsWith('svc:')
? t('detail.systemActor', { defaultValue: 'System' })
: rawActor;
const changes = rawChangesPerItem[idx].map((c) => ({
field: c.field,
label: fieldLabels[c.field] || c.field,
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/locales/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2757,6 +2757,7 @@ const ar = {
slaRemaining: 'SLA المتبقي {{dur}}',
slaOverdue: 'SLA متأخر {{dur}}',
actReassign: 'إعادة إسناد',
reassignFromTo: 'من {{from}} إلى {{to}}',
actRemind: 'تذكير',
actRequestInfo: 'طلب معلومات',
actComment: 'تعليق',
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2757,6 +2757,7 @@ const de = {
slaRemaining: 'SLA noch {{dur}}',
slaOverdue: 'SLA überfällig {{dur}}',
actReassign: 'Übergeben',
reassignFromTo: 'von {{from}} an {{to}}',
actRemind: 'Erinnert',
actRequestInfo: 'Rückfrage gestellt',
actComment: 'Kommentiert',
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2861,6 +2861,7 @@ const en = {
slaRemaining: 'SLA {{dur}} left',
slaOverdue: 'SLA overdue {{dur}}',
actReassign: 'Reassigned',
reassignFromTo: 'from {{from}} to {{to}}',
actRemind: 'Reminder sent',
actRequestInfo: 'Requested more info',
actComment: 'Commented',
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/locales/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2757,6 +2757,7 @@ const es = {
slaRemaining: 'SLA: quedan {{dur}}',
slaOverdue: 'SLA vencido {{dur}}',
actReassign: 'Reasignada',
reassignFromTo: 'de {{from}} a {{to}}',
actRemind: 'Recordatorio',
actRequestInfo: 'Pidió más información',
actComment: 'Comentó',
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2757,6 +2757,7 @@ const fr = {
slaRemaining: 'SLA : {{dur}} restants',
slaOverdue: 'SLA dépassé de {{dur}}',
actReassign: 'Réattribuée',
reassignFromTo: 'de {{from}} à {{to}}',
actRemind: 'Relance',
actRequestInfo: 'Infos demandées',
actComment: 'Commentaire',
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/locales/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2757,6 +2757,7 @@ const ja = {
slaRemaining: 'SLA 残り {{dur}}',
slaOverdue: 'SLA 超過 {{dur}}',
actReassign: '引き継ぎ',
reassignFromTo: '{{from}} から {{to}} へ',
actRemind: 'リマインド',
actRequestInfo: '追加情報を要求',
actComment: 'コメント',
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/locales/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2757,6 +2757,7 @@ const ko = {
slaRemaining: 'SLA {{dur}} 남음',
slaOverdue: 'SLA {{dur}} 초과',
actReassign: '재할당',
reassignFromTo: '{{from}} 님에서 {{to}} 님으로',
actRemind: '독촉',
actRequestInfo: '보완 요청',
actComment: '댓글',
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/locales/pt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2757,6 +2757,7 @@ const pt = {
slaRemaining: 'SLA: faltam {{dur}}',
slaOverdue: 'SLA vencido há {{dur}}',
actReassign: 'Reatribuída',
reassignFromTo: 'de {{from}} para {{to}}',
actRemind: 'Lembrete',
actRequestInfo: 'Pediu mais informações',
actComment: 'Comentou',
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2757,6 +2757,7 @@ const ru = {
slaRemaining: 'SLA: осталось {{dur}}',
slaOverdue: 'SLA просрочен на {{dur}}',
actReassign: 'Передано',
reassignFromTo: 'от {{from}} к {{to}}',
actRemind: 'Напоминание',
actRequestInfo: 'Запрошены данные',
actComment: 'Комментарий',
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2845,6 +2845,7 @@ const zh = {
slaRemaining: 'SLA 剩余 {{dur}}',
slaOverdue: 'SLA 已超期 {{dur}}',
actReassign: '转签',
reassignFromTo: '从 {{from}} 转给 {{to}}',
actRemind: '催办',
actRequestInfo: '要求补充材料',
actComment: '评论',
Expand Down
Loading