DynamoDS/DYN-10516: Dynamo Home: refresh Templates and Recent Files from disk dynamically#17150
Closed
eamiri wants to merge 5 commits into
Closed
DynamoDS/DYN-10516: Dynamo Home: refresh Templates and Recent Files from disk dynamically#17150eamiri wants to merge 5 commits into
eamiri wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
See the ticket for this pull request: https://jira.autodesk.com/browse/DYN-10516
Refactor StartPageViewModel.LoadTemplates into LoadTemplatesFromDisk(bool clearFirst) and expose internal RefreshTemplates so the Home view can re-read the templates directory on demand. Add DynamoViewModel.PruneInvalidRecentFiles and TryRemoveRecentFile for removing recent-file entries whose underlying file has been deleted on disk; the existing CollectionChanged subscribers propagate the change to the WebView automatically. Add HomeFileNoLongerExistsAtPath / HomeFileNoLongerExistsAtPathTitle resources used by the Home-screen click handlers (wiring lands in follow-up tasks).
Subscribe HomePage to StartPageViewModel.TemplateFiles.CollectionChanged so that mutations to the template list flow to the WebView automatically (mirroring the existing RecentFiles wiring). Adds a templateSubscribed guard against double subscription and unsubscribes in Dispose(bool).
- HomePage.DynamoViewModel_PropertyChanged: when ShowStartPage flips to true, call StartPageViewModel.RefreshTemplates() and DynamoViewModel.PruneInvalidRecentFiles(). Track last value to skip redundant refreshes when the property fires unchanged. - HomePage.OpenFile: pre-validate the path with PathHelper.IsValidPath. On miss, drop the stale entry (template via RefreshTemplates, recent file via TryRemoveRecentFile) and show the new File Not Found dialog. Pre-validate runs before the IsTestMode short-circuit so tests can exercise it. Skips OpenCommand.CanExecute, which avoids the modal inside CanOpen that hangs the WebView2 host-object callback. - StartPage.HandleFilePath: same pre-validate for legacy-view parity. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add NUnit coverage for the Home Templates and Recent Files refresh flow added in this branch: - WorkspaceOpeningTests: Prune/TryRemove on RecentFiles and RefreshTemplates against a redirected templates directory. - HomePageTests: pre-validate branch of OpenFile and HandleMissingFile differentiating template vs recent-file paths.
|
| var homePage = new HomePage { DataContext = startPage }; | ||
| var missingPath = Path.Combine(Path.GetTempPath(), "stale-recent-" + Guid.NewGuid().ToString("N") + ".dyn"); | ||
|
|
||
| vm.RecentFiles.Clear(); |
|
|
||
| // Inject a fake template entry so the missing path is treated as a template, not a recent file. | ||
| startPage.TemplateFiles.Add(new StartPageListItem("Ghost Template") { ContextData = ghostTemplate }); | ||
| vm.RecentFiles.Clear(); |
| public void PruneInvalidRecentFilesRemovesMissingPathsWhenInvoked() | ||
| { | ||
| // Arrange | ||
| var validPath = Path.Combine(SampleDirectory, @"en-US\Basics\Basics_Basic01.dyn"); |
| { | ||
| // Arrange | ||
| var validPath = Path.Combine(SampleDirectory, @"en-US\Basics\Basics_Basic01.dyn"); | ||
| var missingPath = Path.Combine(TempFolder, "definitely-not-on-disk.dyn"); |
| public void PruneInvalidRecentFilesPreservesValidPathsWhenAllValid() | ||
| { | ||
| // Arrange | ||
| var first = Path.Combine(SampleDirectory, @"en-US\Basics\Basics_Basic01.dyn"); |
| { | ||
| // Arrange | ||
| var first = Path.Combine(SampleDirectory, @"en-US\Basics\Basics_Basic01.dyn"); | ||
| var second = Path.Combine(SampleDirectory, @"en-US\Basics\Basics_Basic02.dyn"); |
| public void TryRemoveRecentFileReturnsTrueWhenEntryExists() | ||
| { | ||
| // Arrange | ||
| var path = Path.Combine(TempFolder, "anything.dyn"); |
| ViewModel.RecentFiles.Clear(); | ||
|
|
||
| // Act | ||
| var removed = ViewModel.TryRemoveRecentFile(Path.Combine(TempFolder, "missing.dyn")); |
| public void RefreshTemplatesPicksUpNewlyAddedTemplateWhenInvokedAfterAdd() | ||
| { | ||
| // Arrange | ||
| var templatesDir = Path.Combine(TempFolder, "templates-add-" + Guid.NewGuid().ToString("N")); |
| var startPage = new StartPageViewModel(ViewModel, isFirstRun: true); | ||
| Assert.AreEqual(0, startPage.TemplateFiles.Count, "Sanity: empty templates dir starts with zero items."); | ||
|
|
||
| var newTemplate = Path.Combine(templatesDir, "NewTemplate.dyn"); |
Contributor
|
Closing in favor of #17161 (Chloe's implementation). Per discussion with Erfan — we'll continue with the community PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Closes https://autodesk.atlassian.net/browse/DYN-10516
h1. Home — Refresh Templates and Recent Files Implementation Plan
h2. Overview
Make the Dynamo Home screen's Templates and Recent Files lists refresh from disk every time the Home view becomes visible (e.g., after a user closes a workspace), and fix the misleading warning + hang triggered by clicking a tile whose file has been deleted. Pure on-show refresh — no file system watchers, per the agreed scope.
h2. Current State Analysis
h3. Key Discoveries
h2. Desired End State
h2. What We're NOT Doing
h2. Implementation Approach
Three small layered changes:
Refresh APIs + resource strings: add {{RefreshTemplates()}} on {{StartPageViewModel}}, {{PruneInvalidRecentFiles()}} + {{TryRemoveRecentFile()}} on {{DynamoViewModel}}, and new "File Not Found" resx entries.
Auto-push wiring: subscribe to {{TemplateFiles.CollectionChanged}} in {{HomePage}} (mirroring the RecentFiles wiring) so collection changes flow to the WebView automatically.
Trigger + click fix: in {{HomePage.DynamoViewModel_PropertyChanged}}, call the refresh APIs when {{ShowStartPage}} flips to true; in {{HomePage.OpenFile}} and {{StartPage.HandleFilePath}}, pre-validate the path — on miss show the new dialog, drop the stale entry, return early (avoids the {{CanOpen}} side-effect and removes the hang).
h3. TASK 1: Add refresh APIs and missing-file resource strings [HIGH PRIORITY]
Status: DONE
Milestone: Pure-logic refresh + prune methods exist, are unit-tested; new localized message strings are available.
** {{HomeFileNoLongerExistsAtPath}} = "This file no longer exists at the following location and will be removed from your list.\n{0}"
** {{HomeFileNoLongerExistsAtPathTitle}} = "File Not Found"
Validation: Tests in Task 4 pass; {{DynamoCoreWpf}} builds with the new resx entries.
Requirements from spec:
Files to Modify:
Implementation Details:
h3. TASK 2: Wire HomePage to auto-push template-collection changes [HIGH PRIORITY]
Status: DONE
Milestone: Mutating {{StartPageViewModel.TemplateFiles}} updates the WebView's templates list without an explicit caller-side {{SendTemplateData()}}.
Validation: Manual breakpoint confirms WebView receives updates on collection mutation; {{dotnet test src/DynamoCoreWpfTests/DynamoCoreWpfTests.csproj --filter "Name~HomePage"}} passes.
Requirements from spec: Required scaffolding for Task 3.
Files to Modify: {{src/DynamoCoreWpf/Views/HomePage/HomePage.xaml.cs}}
Implementation Details: Follow exact shape of {{RecentFiles_CollectionChanged}} (line 283) and its subscribe/unsubscribe sites for consistency. Handler ignores {{e.Action}}, rebuilds whole list.
h3. TASK 3: Refresh on Home-view show + fix missing-file click [HIGH PRIORITY]
Status: DONE
Milestone: Ticket repro no longer reproduces. Templates/Recent Files reflect on-disk state after returning to Home. Clicking a missing tile shows a clear message, removes the item, and does not hang Dynamo.
Validation:
Requirements from spec: All three bullets under "Scope".
Files to Modify:
Implementation Details:
h3. TASK 4: Tests [MEDIUM PRIORITY]
Status: DONE
Milestone: Test coverage protects refresh/prune/click behaviors against regression.
** {{PruneInvalidRecentFilesRemovesMissingPathsWhenInvoked}}
** {{PruneInvalidRecentFilesPreservesValidPathsWhenAllValid}}
** {{TryRemoveRecentFileReturnsTrueWhenEntryExists}}
** {{TryRemoveRecentFileReturnsFalseWhenEntryMissing}}
** {{RefreshTemplatesPicksUpNewlyAddedTemplateWhenInvokedAfterAdd}}
** {{RefreshTemplatesDropsDeletedTemplateWhenInvokedAfterDelete}}
** Template tests use {{Model.UpdatePreferenceItemLocation(PathManager.PreferenceItem.Templates, ...)}} to redirect to an isolated {{TempFolder}} subdirectory, then write/delete {{.dyn}} files there.
** {{OpenFileWithMissingPathDoesNotInvokeTestHook}} — assert {{TestHook}} (proxy for {{OpenCommand}}) is not invoked when the path is missing.
** {{OpenFileWithMissingRecentFilePathRemovesItFromRecentFiles}} — assert the stale recent-file entry is pruned via {{TryRemoveRecentFile}}.
** {{HandleMissingFileWithListedTemplateRefreshesTemplatesInsteadOfRecentFiles}} — assert the template branch refreshes templates and leaves {{RecentFiles}} untouched.
Validation:
RefreshTemplates|NamePruneInvalidRecentFiles"}} passes.Files to Modify:
Implementation Details: The pre-validate in {{HomePage.OpenFile}} runs before the {{IsTestMode}} short-circuit, so {{TestHook}} not being invoked is the observable signal of the missing-path branch. Template-branch coverage drives {{HandleMissingFile}} directly with an injected fake {{TemplateFiles}} entry. The {{DynamoViewModel_PropertyChanged}} flow is guarded by {{dynWebView?.CoreWebView2 != null}} and is therefore covered by the existing manual-test plan rather than a unit test (the underlying {{RefreshTemplates}}/{{PruneInvalidRecentFiles}} methods are independently covered in {{WorkspaceOpeningTests}}).
h2. Testing Strategy
h3. Unit Tests
h3. Integration Tests
h3. Manual Testing Steps
Build ({{msbuild src/Dynamo.All.sln /p:Configuration=Release}}), launch sandbox.
Verify Home → Templates section is populated.
With Dynamo running, drop a new {{.dyn}} into the templates folder; open a workspace; close it. New template appears on Home.
With Dynamo running, delete a template via Explorer; open a workspace; close it. Deleted template disappears.
Repeat (4) but click the tile BEFORE refresh: expect "File Not Found" dialog, tile auto-removed, no hang.
Save a graph, open it, close it; delete the file via Explorer; navigate back to Home; confirm Recent Files no longer lists it.
Repeat (6) click flow before refresh: expect "File Not Found" dialog, auto-removal, no hang.
Confirm no regression on the trust-warning path for valid template opens.
h2. Performance Considerations
h2. Migration Notes