datahub-web-react/src/app/entityV2/document/changeHistory/changeMessages/README.md
This directory contains the individual components for rendering different types of document changes in the change history timeline.
ChangeMessageComponents.tsx: Contains all individual change message components and the main routerFollow these steps to add support for a new document change type:
First, add your new change type to the enum in datahub-graphql-core/src/main/resources/knowledge.graphql:
enum DocumentChangeType {
CREATED
TITLE_CHANGED
TEXT_CHANGED
# ... existing types ...
MY_NEW_CHANGE_TYPE # Add your new type here
}
If you need to capture additional data, update DocumentInfoChangeEventGenerator.java to include relevant parameters in the change event.
In ChangeMessageComponents.tsx, create a new component:
export const MyNewChangeMessage: React.FC<BaseChangeMessageProps> = ({ actorName, details }) => (
<ActionText>
<ActorName>{actorName}</ActorName> performed a new action on {details.someField}
</ActionText>
);
Tips:
<ActorName> for bold text (actor names, titles, etc.)details propParentChangedMessage for example)onAction propIn the ChangeMessage component's switch statement, add your new case:
export const ChangeMessage: React.FC<ChangeMessageProps> = ({
changeType,
actorName,
details,
description,
onSeeVersion,
}) => {
switch (changeType) {
// ... existing cases ...
case DocumentChangeType.MyNewChangeType:
return <MyNewChangeMessage actorName={actorName} details={details} />;
// ... rest of cases ...
}
};
Run yarn generate to regenerate GraphQL types from the schema.
ActionText for the message wrapperActorName for bold text (names, titles, important values)SeeVersionLink for clickable linksFollow this pattern for consistency:
{ActorName} {action verb} {optional object}
Examples:
John Doe created documentJane Smith changed title to New TitleBob Johnson moved document to Marketing FolderIf you need to fetch additional data:
const { data } = useGetSomeQuery({
variables: { urn: details.someUrn },
skip: !details.someUrn, // Only fetch when needed
});
export const CreatedMessage: React.FC<BaseChangeMessageProps> = ({ actorName }) => (
<ActionText>
<ActorName>{actorName}</ActorName> created document
</ActionText>
);
export const TitleChangedMessage: React.FC<BaseChangeMessageProps> = ({ actorName, details }) => (
<ActionText>
<ActorName>{actorName}</ActorName> changed title to <ActorName>{details.newTitle}</ActorName>
</ActionText>
);
export const ParentChangedMessage: React.FC<BaseChangeMessageProps> = ({ actorName, details }) => {
const { data } = useGetDocumentQuery({
variables: { urn: details.newParent || '' },
skip: !details.newParent,
});
const parentTitle = data?.document?.info?.title || 'Unknown';
return (
<ActionText>
<ActorName>{actorName}</ActorName> moved document to <ActorName>{parentTitle}</ActorName>
</ActionText>
);
};
interface MyMessageProps extends BaseChangeMessageProps {
onAction: () => void;
}
export const MyMessage: React.FC<MyMessageProps> = ({ actorName, onAction }) => (
<ActionText>
<ActorName>{actorName}</ActorName> did something.{' '}
<SeeVersionLink onClick={onAction}>Click here</SeeVersionLink>
</ActionText>
);