Skip to content

Commit a6e1b38

Browse files
committed
msg: working-partially with LS;
- Duplicate data now flows directly from controller >> chatwrapper >> new-component - but it is also being forwarded to chatitem-card - buttons not showing up - file-click not working
1 parent 55a1081 commit a6e1b38

File tree

4 files changed

+87
-77
lines changed

4 files changed

+87
-77
lines changed

src/components/__test__/modified-files-tracker.spec.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ describe('ModifiedFilesTracker', () => {
9090
type: ChatItemType.ANSWER,
9191
header: {
9292
fileList: {
93-
filePaths: ['test.ts']
93+
filePaths: [ 'test.ts' ]
9494
}
9595
}
9696
};
97-
97+
9898
const tracker = new ModifiedFilesTracker({
9999
tabId: 'test-tab',
100100
chatItem
@@ -118,7 +118,7 @@ describe('ModifiedFilesTracker', () => {
118118
type: ChatItemType.ANSWER,
119119
header: {
120120
fileList: {
121-
filePaths: ['test.ts'],
121+
filePaths: [ 'test.ts' ],
122122
details: {
123123
'test.ts': {
124124
visibleName: 'test.ts'
@@ -195,8 +195,6 @@ describe('ModifiedFilesTracker', () => {
195195
});
196196
});
197197

198-
199-
200198
describe('setVisible method', () => {
201199
it('should show tracker when setVisible(true) is called', () => {
202200
const tracker = new ModifiedFilesTracker({

src/components/chat-item/chat-wrapper.ts

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export class ChatWrapper {
5959
private readonly dragBlurOverlay: HTMLElement;
6060
private dragOverlayVisibility: boolean = true;
6161
private imageContextFeatureEnabled: boolean = false;
62-
private modifiedFilesTracker: ModifiedFilesTracker;
62+
private readonly modifiedFilesTracker: ModifiedFilesTracker;
6363
private modifiedFilesChatItem: ChatItem | null = null;
6464

6565
constructor (props: ChatWrapperProps) {
@@ -100,7 +100,6 @@ export class ChatWrapper {
100100
tabId: this.props.tabId
101101
});
102102

103-
104103
MynahUITabsStore.getInstance().addListenerToDataStore(this.props.tabId, 'chatItems', (chatItems: ChatItem[]) => {
105104
const chatItemToInsert: ChatItem = chatItems[chatItems.length - 1];
106105

@@ -388,6 +387,12 @@ export class ChatWrapper {
388387
};
389388

390389
private readonly insertChatItem = (chatItem: ChatItem): void => {
390+
// Log chatItem details (only non-undefined properties)
391+
const definedProps = Object.fromEntries(
392+
Object.entries(chatItem).filter(([ _, value ]) => value !== undefined)
393+
);
394+
console.log('[ChatWrapper] insertChatItem received chatItem:', definedProps);
395+
391396
this.removeEmptyCardsAndFollowups();
392397
const currentMessageId: string = (chatItem.messageId != null && chatItem.messageId !== '') ? chatItem.messageId : `TEMP_${generateUID()}`;
393398
const chatItemCard = new ChatItemCard({
@@ -419,16 +424,13 @@ export class ChatWrapper {
419424
// Add to all rendered chat items map
420425
this.allRenderedChatItems[currentMessageId] = chatItemCard;
421426

422-
// Update ModifiedFilesTracker if chatItem has file data
423-
console.log('[ChatWrapper] Checking chatItem for file data:', {
424-
messageId: chatItem.messageId,
425-
hasHeader: !!chatItem.header,
426-
hasFileList: !!chatItem.header?.fileList,
427-
fileList: chatItem.header?.fileList
428-
});
429-
if (chatItem.header?.fileList != null) {
430-
console.log('[ChatWrapper] Setting ModifiedFilesChatItem with fileList:', chatItem.header.fileList);
431-
this.setModifiedFilesChatItem(chatItem);
427+
// Update ModifiedFilesTracker only if chatItem messageId contains suffix "modified-files-"
428+
if (chatItem.messageId != null && chatItem.header?.fileList != null) {
429+
if (chatItem.messageId.includes('modified-files-')) {
430+
console.log('[ChatWrapper] Setting ModifiedFilesChatItem with fileList:', chatItem.header.fileList);
431+
this.setModifiedFilesChatItem(chatItem);
432+
}
433+
return;
432434
}
433435

434436
if (chatItem.type === ChatItemType.PROMPT || chatItem.type === ChatItemType.SYSTEM_PROMPT) {
@@ -566,24 +568,8 @@ export class ChatWrapper {
566568
}
567569

568570
public updateModifiedFilesTracker (): void {
569-
console.log('[ChatWrapper] updateModifiedFilesTracker called with modifiedFilesChatItem:', this.modifiedFilesChatItem);
570571
if (this.modifiedFilesChatItem != null) {
571-
console.log('[ChatWrapper] Creating new ModifiedFilesTracker with chatItem:', {
572-
tabId: this.props.tabId,
573-
chatItem: this.modifiedFilesChatItem
574-
});
575-
// Create a new ModifiedFilesTracker with the chatItem
576-
const newTracker = new ModifiedFilesTracker({
577-
tabId: this.props.tabId,
578-
chatItem: this.modifiedFilesChatItem
579-
});
580-
console.log('[ChatWrapper] New ModifiedFilesTracker created:', newTracker);
581-
// Replace the old tracker
582-
this.modifiedFilesTracker.render.replaceWith(newTracker.render);
583-
this.modifiedFilesTracker = newTracker;
584-
console.log('[ChatWrapper] ModifiedFilesTracker replaced successfully');
585-
} else {
586-
console.log('[ChatWrapper] No modifiedFilesChatItem to update tracker with');
572+
this.modifiedFilesTracker.addChatItem(this.modifiedFilesChatItem);
587573
}
588574
}
589575

src/components/modified-files-tracker.ts

Lines changed: 68 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ export class ModifiedFilesTracker {
2222
private readonly props: ModifiedFilesTrackerProps;
2323
private readonly collapsibleContent: CollapsibleContent;
2424
public titleText: string = 'No files modified!';
25+
private readonly allFiles: Map<string, { fileList: NonNullable<ChatItemContent['fileList']>; messageId: string }> = new Map();
2526

2627
constructor (props: ModifiedFilesTrackerProps) {
2728
console.log('[ModifiedFilesTracker] Constructor called with props:', {
2829
tabId: props.tabId,
29-
hasChatItem: !!props.chatItem,
30+
hasChatItem: !(props.chatItem == null),
3031
chatItem: props.chatItem,
3132
fileList: props.chatItem?.header?.fileList
3233
});
@@ -53,23 +54,30 @@ export class ModifiedFilesTracker {
5354

5455
console.log('[ModifiedFilesTracker] Render element created:', this.render);
5556

56-
if (this.props.chatItem?.header?.fileList) {
57+
if ((this.props.chatItem?.header?.fileList) != null) {
5758
console.log('[ModifiedFilesTracker] Rendering modified files with fileList:', this.props.chatItem.header.fileList);
58-
this.renderModifiedFiles(this.props.chatItem.header.fileList);
59+
this.renderModifiedFiles(this.props.chatItem.header.fileList, this.props.chatItem.messageId);
5960
} else {
6061
console.log('[ModifiedFilesTracker] No fileList found, rendering empty state');
6162
this.renderModifiedFiles(null);
6263
}
6364
}
6465

65-
private renderModifiedFiles (fileList: ChatItemContent['fileList'] | null): void {
66+
private renderModifiedFiles (fileList: ChatItemContent['fileList'] | null, chatItemMessageId?: string): void {
6667
const contentWrapper = this.collapsibleContent.render.querySelector('.mynah-collapsible-content-label-content-wrapper');
6768
if (contentWrapper == null) return;
6869

70+
// Add files to the collection if provided
71+
if (fileList != null && (fileList.filePaths?.length ?? 0) > 0) {
72+
const messageId = chatItemMessageId ?? `modified-files-tracker-${this.props.tabId}`;
73+
this.allFiles.set(messageId, { fileList, messageId });
74+
}
75+
76+
// Clear and re-render all files
6977
contentWrapper.innerHTML = '';
7078

71-
if ((fileList?.filePaths?.length ?? 0) > 0 && fileList != null) {
72-
this.renderFilePills(contentWrapper, fileList);
79+
if (this.allFiles.size > 0) {
80+
this.renderAllFilePills(contentWrapper);
7381
} else {
7482
this.renderEmptyState(contentWrapper);
7583
}
@@ -83,44 +91,61 @@ export class ModifiedFilesTracker {
8391
}));
8492
}
8593

86-
private renderFilePills (contentWrapper: Element, fileList: NonNullable<ChatItemContent['fileList']> & { messageId?: string }): void {
87-
const messageId = fileList.messageId ?? `modified-files-tracker-${this.props.tabId}`;
88-
89-
// Render the file tree with actions and buttons as provided by the data
90-
contentWrapper.appendChild(new ChatItemTreeViewWrapper({
91-
tabId: this.props.tabId,
92-
messageId,
93-
files: fileList.filePaths ?? [],
94-
cardTitle: '',
95-
rootTitle: fileList.rootFolderTitle,
96-
deletedFiles: fileList.deletedFiles ?? [],
97-
flatList: fileList.flatList ?? true,
98-
actions: (fileList as any).actions ?? {},
99-
details: fileList.details ?? {},
100-
hideFileCount: fileList.hideFileCount ?? true,
101-
collapsed: fileList.collapsed ?? false,
102-
referenceSuggestionLabel: '',
103-
references: [],
104-
onRootCollapsedStateChange: () => {}
105-
}).render);
106-
107-
// Render buttons if they exist
108-
const fileListWithButtons = fileList as ChatItemContent['fileList'] & { buttons?: ChatItemButton[] };
109-
const buttons: ChatItemButton[] | undefined = fileListWithButtons.buttons;
110-
if (Array.isArray(buttons) && buttons.length > 0) {
111-
const buttonsWrapper = new ChatItemButtonsWrapper({
112-
tabId: this.props.tabId,
113-
buttons,
114-
onActionClick: (action: ChatItemButton) => {
115-
MynahUIGlobalEvents.getInstance().dispatch(MynahEventNames.BODY_ACTION_CLICKED, {
116-
tabId: this.props.tabId,
117-
messageId: (action as any).messageId != null ? (action as any).messageId : messageId,
118-
actionId: action.id,
119-
actionText: action.text
120-
});
121-
}
94+
private renderAllFilePills (contentWrapper: Element): void {
95+
this.allFiles.forEach(({ fileList, messageId }) => {
96+
const { filePaths = [], deletedFiles = [], actions, details, flatList } = fileList;
97+
98+
// Create a wrapper for each file group
99+
const fileGroupWrapper = DomBuilder.getInstance().build({
100+
type: 'div',
101+
classNames: [ 'mynah-modified-files-group' ],
102+
children: []
122103
});
123-
contentWrapper.appendChild(buttonsWrapper.render);
104+
105+
// Render the file tree with actions and buttons as provided by the data
106+
fileGroupWrapper.appendChild(new ChatItemTreeViewWrapper({
107+
tabId: this.props.tabId,
108+
messageId,
109+
files: filePaths,
110+
cardTitle: '',
111+
rootTitle: fileList.rootFolderTitle,
112+
deletedFiles,
113+
flatList,
114+
actions,
115+
details,
116+
hideFileCount: fileList.hideFileCount ?? true,
117+
collapsed: fileList.collapsed ?? false,
118+
referenceSuggestionLabel: '',
119+
references: [],
120+
onRootCollapsedStateChange: () => {}
121+
}).render);
122+
123+
// Render buttons if they exist
124+
const fileListWithButtons = fileList as ChatItemContent['fileList'] & { buttons?: ChatItemButton[] };
125+
const buttons: ChatItemButton[] | undefined = fileListWithButtons.buttons;
126+
if (Array.isArray(buttons) && buttons.length > 0) {
127+
const buttonsWrapper = new ChatItemButtonsWrapper({
128+
tabId: this.props.tabId,
129+
buttons,
130+
onActionClick: (action: ChatItemButton) => {
131+
MynahUIGlobalEvents.getInstance().dispatch(MynahEventNames.BODY_ACTION_CLICKED, {
132+
tabId: this.props.tabId,
133+
messageId: (action as any).messageId != null ? (action as any).messageId : messageId,
134+
actionId: action.id,
135+
actionText: action.text
136+
});
137+
}
138+
});
139+
fileGroupWrapper.appendChild(buttonsWrapper.render);
140+
}
141+
142+
contentWrapper.appendChild(fileGroupWrapper);
143+
});
144+
}
145+
146+
public addChatItem (chatItem: ChatItem): void {
147+
if (chatItem.header?.fileList != null) {
148+
this.renderModifiedFiles(chatItem.header.fileList, chatItem.messageId);
124149
}
125150
}
126151

src/static.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ export interface MynahUITabStoreModel {
211211
[tabId: string]: MynahUITabStoreTab;
212212
}
213213

214+
// Event names for MynahUI component interactions
214215
export enum MynahEventNames {
215216
RESET_STORE = 'resetStore',
216217
FEEDBACK_SET = 'feedbackSet',

0 commit comments

Comments
 (0)