fix(skill): pin preview tabs when remote sync only dirties metadata

This commit is contained in:
yyh
2026-03-27 14:04:40 +08:00
parent 9e1638ca74
commit c43e496cc2
2 changed files with 49 additions and 4 deletions

View File

@@ -682,6 +682,50 @@ describe('FileContentPanel', () => {
expect(mocks.workflowActions.clearDraftContent).toHaveBeenCalledWith('file-1')
expect(mocks.workflowActions.pinTab).not.toHaveBeenCalled()
})
it('should pin the tab when remote collaboration sync only dirties metadata', async () => {
// Arrange
mocks.fileTypeInfo = {
isMarkdown: true,
isCodeOrText: false,
isImage: false,
isVideo: false,
isPdf: false,
isSQLite: false,
isEditable: true,
isPreviewable: true,
}
mocks.fileData.fileContent = {
content: `linked §[file].[app].[${FILE_REFERENCE_ID}`,
metadata: {},
}
mocks.workflowState.fileMetadata = new Map<string, Record<string, unknown>>([
['file-1', {}],
])
mocks.nodeMapData = new Map<string, AppAssetTreeView>([
['file-1', createNode({ name: 'prompt.md', extension: 'md' })],
[FILE_REFERENCE_ID, createNode({ id: FILE_REFERENCE_ID, name: 'kb.txt', extension: 'txt' })],
])
// Act
render(<FileContentPanel />)
await screen.findByTestId('markdown-editor')
const firstCall = mocks.useSkillMarkdownCollaboration.mock.calls[0]
const args = firstCall?.[0] as UseSkillMarkdownCollaborationArgs | undefined
args?.onRemoteChange?.(`linked §[file].[app].[${FILE_REFERENCE_ID}`)
// Assert
expect(mocks.workflowActions.clearDraftContent).toHaveBeenCalledWith('file-1')
expect(mocks.workflowActions.setDraftMetadata).toHaveBeenCalledWith(
'file-1',
expect.objectContaining({
files: expect.objectContaining({
[FILE_REFERENCE_ID]: expect.objectContaining({ id: FILE_REFERENCE_ID }),
}),
}),
)
expect(mocks.workflowActions.pinTab).toHaveBeenCalledWith('file-1')
})
})
describe('Preview modes', () => {

View File

@@ -86,7 +86,7 @@ export const useFileContentController = (): FileContentControllerState => {
const updateFileReferenceMetadata = useCallback((content: string) => {
if (!fileTabId)
return
return false
const referenceIds = extractFileReferenceIds(content)
const metadata = (currentMetadata || {}) as SkillFileMetadata
@@ -108,9 +108,10 @@ export const useFileContentController = (): FileContentControllerState => {
delete nextMetadata.files
if (isDeepEqual(metadata, nextMetadata))
return
return false
storeApi.getState().setDraftMetadata(fileTabId, nextMetadata)
return true
}, [currentMetadata, fileTabId, nodeMap, storeApi])
const applyContentChange = useCallback((
@@ -130,8 +131,8 @@ export const useFileContentController = (): FileContentControllerState => {
else
state.setDraftContent(fileTabId, nextValue)
updateFileReferenceMetadata(nextValue)
if (nextValue !== originalContent || options?.pinWhenContentMatchesOriginal)
const didUpdateMetadata = updateFileReferenceMetadata(nextValue)
if (nextValue !== originalContent || didUpdateMetadata || options?.pinWhenContentMatchesOriginal)
state.pinTab(fileTabId)
}, [fileTabId, isEditable, originalContent, storeApi, updateFileReferenceMetadata])