Skip to content

Commit e40d59f

Browse files
authored
Fix: Refresh files to avoid duplicates (#2213)
1 parent ac71bae commit e40d59f

File tree

2 files changed

+140
-117
lines changed

2 files changed

+140
-117
lines changed

web/client/src/context/project.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,7 @@ export const useStoreProject = create<ProjectStore>((set, get) => ({
9292
refreshFiles() {
9393
const s = get()
9494

95-
set(() => ({
96-
files: new Map(s.files),
97-
}))
95+
s.setFiles(s.project.allFiles)
9896
},
9997
}))
10098

web/client/src/library/pages/root/Root.tsx

Lines changed: 139 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,125 @@ export default function Root(): JSX.Element {
184184
[synchronizeEnvironment, environment],
185185
)
186186

187+
const updateFiles = useCallback(
188+
function updateFiles({
189+
changes,
190+
directories,
191+
}: {
192+
changes: Array<{
193+
change: FileExplorerChange
194+
path: string
195+
file: ModelFile
196+
}>
197+
directories: Record<string, Directory>
198+
}): void {
199+
changes.sort((a: any) =>
200+
a.change === EnumFileExplorerChange.Deleted ? -1 : 1,
201+
)
202+
203+
changes.forEach(({ change, path, file }) => {
204+
if (change === EnumFileExplorerChange.Modified) {
205+
const currentFile = files.get(path)
206+
207+
if (isNil(currentFile) || isNil(file)) return
208+
209+
currentFile.update(file)
210+
}
211+
212+
if (change === EnumFileExplorerChange.Deleted) {
213+
const artifact = findArtifactByPath(path) ?? files.get(path)
214+
215+
if (isNil(artifact)) return
216+
217+
if (artifact instanceof ModelDirectory) {
218+
artifact.parent?.removeDirectory(artifact)
219+
}
220+
221+
if (artifact instanceof ModelFile) {
222+
artifact.parent?.removeFile(artifact)
223+
224+
if (inTabs(artifact)) {
225+
closeTab(artifact)
226+
}
227+
}
228+
}
229+
})
230+
231+
for (const path in directories) {
232+
const directory = directories[path]!
233+
234+
const currentDirectory = findArtifactByPath(
235+
path,
236+
) as Optional<ModelDirectory>
237+
238+
if (isNil(currentDirectory)) continue
239+
240+
directory.directories?.forEach(d => {
241+
const directory = findArtifactByPath(
242+
d.path,
243+
) as Optional<ModelDirectory>
244+
245+
if (isNil(directory)) {
246+
currentDirectory.addDirectory(
247+
new ModelDirectory(d, currentDirectory),
248+
)
249+
}
250+
})
251+
252+
directory.files?.forEach(f => {
253+
const file = files.get(f.path)
254+
255+
if (isNil(file)) {
256+
currentDirectory.addFile(new ModelFile(f, currentDirectory))
257+
}
258+
})
259+
260+
currentDirectory.directories.sort((a, b) => (a.name > b.name ? 1 : -1))
261+
currentDirectory.files.sort((a, b) => (a.name > b.name ? 1 : -1))
262+
}
263+
264+
refreshFiles()
265+
setActiveRange()
266+
},
267+
[files],
268+
)
269+
270+
const formatFile = useCallback(
271+
function formatFile(formatFileStatus: FormatFileStatus): void {
272+
const file = files.get(formatFileStatus.path)
273+
274+
if (isNotNil(file)) {
275+
file.isFormatted = formatFileStatus.status === Status.success
276+
277+
refreshFiles()
278+
}
279+
},
280+
[files],
281+
)
282+
283+
const restoreEditorTabsFromSaved = useCallback(
284+
function restoreEditorTabsFromSaved(files: ModelFile[]): void {
285+
if (isArrayEmpty(storedTabs)) return
286+
287+
const tabs = storedTabs.map(({ id, content }) => {
288+
const file = files.find(file => file.id === id) ?? createLocalFile(id)
289+
const storedTab = createTab(file)
290+
291+
storedTab.file.content = content ?? storedTab.file.content ?? ''
292+
293+
return storedTab
294+
})
295+
const tab = tabs.find(tab => tab.file.id === storedTabId)
296+
297+
addTabs(tabs)
298+
299+
if (isNotNil(tab) && isNil(selectedFile)) {
300+
selectTab(tab)
301+
}
302+
},
303+
[selectTab],
304+
)
305+
187306
useEffect(() => {
188307
void getMeta().then(({ data }) => {
189308
setVersion(data?.version)
@@ -200,12 +319,8 @@ export default function Root(): JSX.Element {
200319
const channelErrors = channel('errors', displayErrors)
201320
const channelTests = channel('tests', updateTests)
202321
const channelModels = channel('models', updateModels)
203-
const channelFile = channel('file', updateFiles)
204-
const channelFormatFile = channel('format-file', formatFile)
205322

206323
channelModels.subscribe()
207-
channelFormatFile.subscribe()
208-
channelFile.subscribe()
209324

210325
if (modules.hasPlans) {
211326
channelTests.subscribe()
@@ -234,8 +349,6 @@ export default function Root(): JSX.Element {
234349
void cancelRequestModels()
235350

236351
channelModels.unsubscribe()
237-
channelFormatFile?.unsubscribe()
238-
channelFile?.unsubscribe()
239352

240353
if (modules.hasPlans) {
241354
cancelRequestEnvironments()
@@ -304,6 +417,26 @@ export default function Root(): JSX.Element {
304417
}
305418
}, [updatePlanCancelTracker])
306419

420+
useEffect(() => {
421+
const channelFile = channel('file', updateFiles)
422+
423+
channelFile.subscribe()
424+
425+
return () => {
426+
channelFile?.unsubscribe()
427+
}
428+
}, [updateFiles])
429+
430+
useEffect(() => {
431+
const channelFormatFile = channel('format-file', formatFile)
432+
433+
channelFormatFile.subscribe()
434+
435+
return () => {
436+
channelFormatFile?.unsubscribe()
437+
}
438+
}, [formatFile])
439+
307440
useEffect(() => {
308441
if (location.pathname === EnumRoutes.Home) {
309442
navigate(modules.defaultNavigationRoute(), { replace: true })
@@ -329,84 +462,6 @@ export default function Root(): JSX.Element {
329462
setTests(tests)
330463
}
331464

332-
function updateFiles({
333-
changes,
334-
directories,
335-
}: {
336-
changes: Array<{
337-
change: FileExplorerChange
338-
path: string
339-
file: ModelFile
340-
}>
341-
directories: Record<string, Directory>
342-
}): void {
343-
changes.sort((a: any) =>
344-
a.change === EnumFileExplorerChange.Deleted ? -1 : 1,
345-
)
346-
347-
changes.forEach(({ change, path, file }) => {
348-
if (change === EnumFileExplorerChange.Modified) {
349-
const currentFile = files.get(path)
350-
351-
if (isNil(currentFile) || isNil(file)) return
352-
353-
currentFile.update(file)
354-
}
355-
356-
if (change === EnumFileExplorerChange.Deleted) {
357-
const artifact = findArtifactByPath(path) ?? files.get(path)
358-
359-
if (isNil(artifact)) return
360-
361-
if (artifact instanceof ModelDirectory) {
362-
artifact.parent?.removeDirectory(artifact)
363-
}
364-
365-
if (artifact instanceof ModelFile) {
366-
artifact.parent?.removeFile(artifact)
367-
368-
if (inTabs(artifact)) {
369-
closeTab(artifact)
370-
}
371-
}
372-
}
373-
})
374-
375-
for (const path in directories) {
376-
const directory = directories[path]!
377-
378-
const currentDirectory = findArtifactByPath(path) as
379-
| ModelDirectory
380-
| undefined
381-
382-
if (isNil(currentDirectory)) continue
383-
384-
directory.directories?.forEach((d: any) => {
385-
const directory = findArtifactByPath(d.path) as
386-
| ModelDirectory
387-
| undefined
388-
389-
if (isNil(directory)) {
390-
currentDirectory.addDirectory(new ModelDirectory(d, currentDirectory))
391-
}
392-
})
393-
394-
directory.files?.forEach((f: any) => {
395-
const file = files.get(path)
396-
397-
if (isNil(file)) {
398-
currentDirectory.addFile(new ModelFile(f, currentDirectory))
399-
}
400-
})
401-
402-
currentDirectory.directories.sort((a, b) => (a.name > b.name ? 1 : -1))
403-
currentDirectory.files.sort((a, b) => (a.name > b.name ? 1 : -1))
404-
}
405-
406-
refreshFiles()
407-
setActiveRange()
408-
}
409-
410465
function updateEnviroments(data: Optional<Environments>): void {
411466
const { environments, default_target_environment, pinned_environments } =
412467
data ?? {}
@@ -420,42 +475,12 @@ export default function Root(): JSX.Element {
420475
}
421476
}
422477

423-
function formatFile(formatFileStatus: FormatFileStatus): void {
424-
const file = files.get(formatFileStatus.path)
425-
426-
if (isNotNil(file)) {
427-
file.isFormatted = formatFileStatus.status === Status.success
428-
429-
refreshFiles()
430-
}
431-
}
432-
433478
function closeModalConfirmation(confirmation?: Confirmation): void {
434479
confirmation?.cancel?.()
435480

436481
setShowConfirmation(false)
437482
}
438483

439-
function restoreEditorTabsFromSaved(files: ModelFile[]): void {
440-
if (isArrayEmpty(storedTabs)) return
441-
442-
const tabs = storedTabs.map(({ id, content }) => {
443-
const file = files.find(file => file.id === id) ?? createLocalFile(id)
444-
const storedTab = createTab(file)
445-
446-
storedTab.file.content = content ?? storedTab.file.content ?? ''
447-
448-
return storedTab
449-
})
450-
const tab = tabs.find(tab => tab.file.id === storedTabId)
451-
452-
addTabs(tabs)
453-
454-
if (isNotNil(tab) && isNil(selectedFile)) {
455-
selectTab(tab)
456-
}
457-
}
458-
459484
const confirmation = confirmations[0]
460485

461486
return (

0 commit comments

Comments
 (0)