Skip to content

Conversation

@sacrodge
Copy link

@sacrodge sacrodge commented Oct 8, 2025

Problem

Modified files are scattered across multiple chatItem cards and can seem lost to users if too many files are modified and has verbose explanation. Needed access to all files modified as part of the conversation in one place.

Solution

Created a new separate component which renders just modified files along with undo button per each file. Still working on styling the component a little better.

  • Currently handles file clicks, undo and undoall buttons
  • Files are just displayed per prompt (not conversation). So for each prompt the previous files are removed
  • Implemented comprehensive unit tests
  • Fixed the unexpected collapsing of component upon fileclick
  • Arranged buttons inline for better visuals
10.17.2025.mov

ToDos :

  • Currently controlling clearing of the component per prompt from chat-wrapper. Handle that from LS
  • Also, title of the component (x files modified) is handled by chat-wrapper as I could not find a property to use for these use cases in LS >> chatMessage.

Tests

  • [ + ] I have tested this change on VSCode
  • [ - ] I have tested this change on JetBrains
  • [ - ] I have added/updated the documentation (if applicable)

License

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

…le in diff mode. Logging enabled, disable later. Undo buttons still not working
…le in diff mode. Logging enabled, disable later. Undo buttons still not working
…le in diff mode. Logging enabled, disable later. Undo buttons still not working
…le in diff mode. Logging enabled, disable later. Undo buttons still not working
…le in diff mode. Logging enabled, disable later. Undo buttons still not working
- Currently gets file details just like chatItemCard
- Files are listed but other functionalities are lacking
- Currently gets file details just like chatItemCard
- Files are listed but other functionalities are lacking
- undo buttons are showing per file
- Upon clicking the button it undoes the chnages correctly
- Added chat=wrapper support to handle title
- Should ideally be controller but no title property in chatMessage
@sacrodge sacrodge changed the base branch from main to feature/upgrade-modified-files-ux October 8, 2025 23:08
});

// Demo will be handled through chatItem approach now
mynahUI.addChatItem(tabId, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious: Why we need two addChatItem here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will remove this and find a way to provide demo differently

details: {
'Running': {
description: 'Work in progress!',
description: 'Work in progress...',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not necessary!

this.hideTooltip();
if (this.props.details?.clickable !== false) {
const fileMessageId = this.props.details?.data?.messageId ?? this.props.messageId;
console.log('[ChatItemTreeFile] File clicked - originalFilePath:', this.props.originalFilePath);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need multiple console logs here? Can we combine into one instead?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will remove unnecessary logging

- Added session functionality for every new chat the modified files are getting cleared
achieves all the functionalities needed
might need testing and use set for storing files
needs more styling, refer previous versions
- removed previous unnecesary edits
- removed example for now
@sacrodge sacrodge marked this pull request as ready for review October 14, 2025 01:16
@sacrodge sacrodge requested a review from a team as a code owner October 14, 2025 01:16
- Switched buttons to header and kept undoall button at top level
… height. Temporarily updated the snapshots. Once the component is made invisible, will revert to correct snapshots
- Aligned the per file undo buttons correctly
- Set undoall button to the right for view consistency
- Fixed on file click propogation, so the component doesn't collapse now unexpectedly
- Removed unnecessary code changes from previous PR feedback
- Fixed failing unit tests due to new changes for preventing collapsing
this.renderModifiedFiles(null);
}

public setVisible (visible: boolean): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this function?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will remove it for now, as I am no longer marking the component invisible yet

// Normal flow on initially opening ui requires the currentMessageId;
this.removeEmptyCardsAndFollowups();
const currentMessageId: string = (chatItem.messageId != null && chatItem.messageId !== '') ? chatItem.messageId : `TEMP_${generateUID()}`;
// Check if messageId contains "modified-files-" prefix
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add this to documentation or add some comments why we are checking for this prefix?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comments for now

if (chatItem.header?.fileList !== null && chatItem.header?.fileList !== undefined) {
this.allRenderedModifiedFileChatItems[chatItem.messageId] = chatItem;
const size = Object.keys(this.allRenderedModifiedFileChatItems).length;
chatItem.title = size === 1 ? '1 file modified!' : `${size} files modified!`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

chatItem.title = `${fileCount} file${fileCount === 1 ? '' : 's'} modified!`;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed


if (chatItem.type === ChatItemType.PROMPT || chatItem.type === ChatItemType.SYSTEM_PROMPT) {
// Clear modified files tracker on new prompt
this.allRenderedModifiedFileChatItems = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a blocker but this does not work if we introduce intermediate input handling from the user.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

render: ExtendedHTMLElement;
private readonly props: ModifiedFilesTrackerProps;
private readonly collapsibleContent: CollapsibleContent;
public titleText: string = 'No files modified!';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this a default value ? Can we reset this from LS?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently we do not have any property in chatMessage, that can be used for titleText

children: [ this.collapsibleContent.render ]
});

console.log('[ModifiedFilesTracker] Render element created:', this.render);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this console.log?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed


public clear (): void {
this.allFiles.clear();
this.titleText = 'No files modified!';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add const and assign this !

if (chatItem.messageId !== undefined && chatItem.messageId !== null && chatItem.messageId !== '') {
undoAllMessageId = this.getOriginalMessageId(chatItem.messageId);
} else {
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add early return

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants