Show the opposite trace endpoint
Why: The trace view selected an endpoint by lexical ID order and could present the current section as its own source. Evidence: Focused presentation tests cover both selected directions of a source-to-section relationship. Impact: Source and impact columns now identify the object opposite the selected node. Refs: rdm-two-trees-latest-templates
This commit is contained in:
@@ -7,6 +7,7 @@ import { Chip, Collapsible, EmptyState, SectionLabel } from '@ui'
|
||||
import { classifyRdmError } from '../rdmErrors'
|
||||
import {
|
||||
describeAuditEvent, describeTreeItem, humanizeKind, humanizeRelation, humanizeState, isTreeItemExpandable,
|
||||
relationOtherEndpoint,
|
||||
type AuditEventViewInput,
|
||||
} from '../rdmAuditPresentation'
|
||||
import { store, useStore } from '../store'
|
||||
@@ -478,11 +479,11 @@ function TraceTab({ pid }: { pid: string }) {
|
||||
<div className="rdm-audit-trace-cols">
|
||||
<div className="rdm-audit-trace-col">
|
||||
<SectionLabel>来源依据({sources.length})</SectionLabel>
|
||||
{sources.length === 0 ? <div className="empty-note">无来源</div> : sources.map((r, i) => <RelationRow key={i} r={r} />)}
|
||||
{sources.length === 0 ? <div className="empty-note">无来源</div> : sources.map((r, i) => <RelationRow key={i} r={r} selected={sel} />)}
|
||||
</div>
|
||||
<div className="rdm-audit-trace-col">
|
||||
<SectionLabel>影响对象({impacts.length})</SectionLabel>
|
||||
{impacts.length === 0 ? <div className="empty-note">无影响</div> : impacts.map((r, i) => <RelationRow key={i} r={r} />)}
|
||||
{impacts.length === 0 ? <div className="empty-note">无影响</div> : impacts.map((r, i) => <RelationRow key={i} r={r} selected={sel} />)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -491,8 +492,8 @@ function TraceTab({ pid }: { pid: string }) {
|
||||
)
|
||||
}
|
||||
|
||||
function RelationRow({ r }: { r: RelationEntry }) {
|
||||
const other = r.from?.id && r.to?.id ? (r.from?.id < r.to?.id ? r.from : r.to) : (r.from || r.to)
|
||||
function RelationRow({ r, selected }: { r: RelationEntry; selected: { kind: string; id: string } }) {
|
||||
const other = relationOtherEndpoint(r, selected)
|
||||
const readable = humanizeRelation(r)
|
||||
return (
|
||||
<div className="rdm-audit-rel">
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { describeAuditEvent, describeTreeItem, humanizeKind, humanizeRelation, humanizeState, isTreeItemExpandable } from './rdmAuditPresentation'
|
||||
import {
|
||||
describeAuditEvent, describeTreeItem, humanizeKind, humanizeRelation, humanizeState,
|
||||
isTreeItemExpandable, relationOtherEndpoint,
|
||||
} from './rdmAuditPresentation'
|
||||
|
||||
describe('RDM audit presentation', () => {
|
||||
it('turns a structured document event into a readable action and impact', () => {
|
||||
@@ -74,4 +77,13 @@ describe('RDM audit presentation', () => {
|
||||
title: '模板内容 3',
|
||||
})
|
||||
})
|
||||
|
||||
it('shows the endpoint opposite the selected object in a trace relationship', () => {
|
||||
const relation = {
|
||||
from: { kind: 'slice', id: 'slc-6' },
|
||||
to: { kind: 'section', id: 'sec-2' },
|
||||
}
|
||||
expect(relationOtherEndpoint(relation, { kind: 'section', id: 'sec-2' })).toEqual(relation.from)
|
||||
expect(relationOtherEndpoint(relation, { kind: 'slice', id: 'slc-6' })).toEqual(relation.to)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -157,6 +157,15 @@ export function humanizeRelation(input: { layer?: string; type?: string; kind?:
|
||||
}
|
||||
}
|
||||
|
||||
export function relationOtherEndpoint<T extends { kind?: string; id?: string }>(
|
||||
relation: { from?: T; to?: T },
|
||||
selected: { kind: string; id: string },
|
||||
): T | undefined {
|
||||
if (relation.to?.kind === selected.kind && relation.to.id === selected.id) return relation.from
|
||||
if (relation.from?.kind === selected.kind && relation.from.id === selected.id) return relation.to
|
||||
return relation.from || relation.to
|
||||
}
|
||||
|
||||
export function isTreeItemExpandable(item: { kind: string; hasChildren?: boolean; id?: string; title?: string }): boolean {
|
||||
return item.kind === 'doc' || item.hasChildren === true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user