Skip to content

DynamoDS/DYN-8957: Add tooltips describing PM is disabled in no-network mode#17142

Closed
eamiri wants to merge 5 commits into
masterfrom
8957-add-pm-disabled-tooltips
Closed

DynamoDS/DYN-8957: Add tooltips describing PM is disabled in no-network mode#17142
eamiri wants to merge 5 commits into
masterfrom
8957-add-pm-disabled-tooltips

Conversation

@eamiri

@eamiri eamiri commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Closes https://autodesk.atlassian.net/browse/DYN-8957

h1. Add “PM disabled in no-network mode” tooltips Implementation Plan

h2. Overview

Dynamo can be launched with {{--NoNetworkMode}} (a.k.a. “offline mode”). DYN-6409 hardened the Package Manager to refuse network operations under that mode by returning {{false}} from every PM-related {{CanExecute}} predicate. The side-effect is that PM menu items and certain buttons silently appear greyed-out with no hint as to why. This task adds informative tooltips, mirroring the precedent set for the Sign-In button ({{SignInOfflineButtonContentToolTip}} / {{ToolTipService.ShowOnDisabled="True"}} / {{DataTrigger}} on {{IsEnabled=False}}). It also disables the Install Specified Version button inside the Workspace References side-panel (the only PM-touching button that is not yet guarded) and gives it the same tooltip treatment.

h2. Current State Analysis

h3. Key Discoveries:

  • Offline tooltip precedent: {{src/DynamoCoreWpf/Controls/ShortcutToolbar.xaml:212-225}} swaps content via a {{Style.Triggers}} {{DataTrigger}} on {{PlacementTarget.IsEnabled}}. Pair it with {{ToolTipService.ShowOnDisabled="True"}}.
  • Resource string layout: only {{Resources.resx}} and {{Resources.en-US.resx}} need new keys; other locales are picked up by the {{master-localization}} merge. Designer stub in {{Resources.Designer.cs}} exposes the getter.
  • PM commands already return {{false}} for {{CanExecute}} in NoNetworkMode — {{PackageManagerClientViewModel.CanPublish*}} ({{...PackageManager/PackageManagerClientViewModel.cs:358,378,408,468}}) and {{DynamoViewModel.CanShowPackageManager*}} ({{...Core/DynamoViewModel.cs:2961,2966}}). No predicate logic needs to change.
  • The Workspace References install button ({{src/WorkspaceDependencyViewExtension/WorkspaceDependencyView.xaml:250-255}}) is the only PM-related control still enabled in offline mode. Its handler at {{WorkspaceDependencyView.xaml.cs:169-181}} reaches the package installer unconditionally.
  • {{ViewLoadedParams.StartupParams.NoNetworkMode}} (inherited via {{ReadyParams}}) is the reach-point for the workspace-references extension; the view sets {{DataContext = this;}}, so adding a public property on the user-control is the simplest binding path.
  • {{WorkspaceView.xaml:754-758}} has a second {{PublishCurrentWorkspaceCommand}} entry-point (custom-node workspace right-click menu); it must also receive the tooltip to stay consistent.
  • {{InstalledPackagesControl.xaml}} PM actions use {{Visibility=Collapsed}} rather than {{IsEnabled=false}}, so the items disappear rather than greying out — no tooltip work needed.

h2. Desired End State

When Dynamo launches with {{--NoNetworkMode}}:

The Packages menu items in the main menu ({{Publish Nodes to Package Manager}}, {{Publish Current Workspace as New Package}}, {{Package Manager}}) remain greyed-out and show the tooltip {{"Package Manager is disabled in no-network mode."}} when hovered.

The right-click {{Publish}} action on a custom-node workspace ({{WorkspaceView.xaml}}) shows the same tooltip when disabled.

The Install Specified Version button inside the Workspace References panel is now disabled (greyed-out) and shows the tooltip {{"Package install is disabled in no-network mode."}} when hovered.

The Keep Installed Version button and the Refresh icons in Workspace References continue to work, because they are purely local operations.

All existing tests still pass; two new NUnit tests assert the new disabled state and tooltip resource lookups.

Verification: launch {{DynamoSandbox.exe --NoNetworkMode}}, open a graph with a missing package dependency, hover each affected UI surface, and confirm the tooltip text appears.

h2. What We're NOT Doing

  • Not changing any {{CanExecute}} predicate (they already return {{false}} in NoNetworkMode).
  • Not touching {{InstalledPackagesControl.xaml}} (items are collapsed, not disabled).
  • Not modifying other locale {{.resx}} files — the {{master-localization}} pipeline picks those up.
  • Not adding visual styling beyond the standard greyed {{IsEnabled=false}} appearance — the existing toolbar disabled appearance is the reference.
  • Not adding new PublicAPI members — the new {{WorkspaceDependencyView.NoNetworkMode}} property is on a {{partial class UserControl}} whose surface is already non-public-API (only {{internal}} collaborators consume it).
  • Not disabling the Keep Installed Version button, Refresh icons, or any local-only operation.
  • Not refactoring the existing {{IsLoginMenuEnabled}} code in {{ShortcutToolbar.xaml.cs}} — it already works.

h2. Implementation Approach

Replicate the proven {{ShortcutToolbar}} Sign-In offline tooltip pattern in every PM-related UI surface that becomes disabled in NoNetworkMode, and extend the Workspace References extension with a {{NoNetworkMode}} bindable property so its {{DownloadPackageButton}} can be gated identically. All changes are XAML + resource strings + one bindable property; no PM business logic changes.


h3. TASK 1: Add new English resource strings [HIGH PRIORITY]

Status: DONE
Milestone: Resource strings exist and resolve correctly through both {{Resources.Designer.cs}} accessors at compile time.

  • Add {{PackageManagerNoNetworkModeToolTip}} to {{src/DynamoCoreWpf/Properties/Resources.resx}} (value: {{"Package Manager is disabled in no-network mode."}}).
  • Add the same key+value to {{src/DynamoCoreWpf/Properties/Resources.en-US.resx}}.
  • Regenerate (or manually update) {{src/DynamoCoreWpf/Properties/Resources.Designer.cs}} so the strongly-typed accessor exists.
  • Add {{InstallButtonNoNetworkModeToolTip}} to {{src/WorkspaceDependencyViewExtension/Properties/Resources.resx}} (value: {{"Package install is disabled in no-network mode."}}).
  • Add the same key+value to {{src/WorkspaceDependencyViewExtension/Properties/Resources.en-US.resx}}.
  • Regenerate (or manually update) {{src/WorkspaceDependencyViewExtension/Properties/Resources.Designer.cs}}.

Validation: {{dotnet build src/DynamoCore.sln -c Release}} succeeds; {{Dynamo.Wpf.Properties.Resources.PackageManagerNoNetworkModeToolTip}} and {{Dynamo.WorkspaceDependency.Properties.Resources.InstallButtonNoNetworkModeToolTip}} compile.

Requirements from spec:

  • Mirror the precise messaging tone established by {{SignInOfflineButtonContentToolTip}} (“Enable Network Mode …” wording) for consistency with DYN-6409.

Files to Modify:

  • {{src/DynamoCoreWpf/Properties/Resources.resx}}
  • {{src/DynamoCoreWpf/Properties/Resources.en-US.resx}}
  • {{src/DynamoCoreWpf/Properties/Resources.Designer.cs}}
  • {{src/WorkspaceDependencyViewExtension/Properties/Resources.resx}}
  • {{src/WorkspaceDependencyViewExtension/Properties/Resources.en-US.resx}}
  • {{src/WorkspaceDependencyViewExtension/Properties/Resources.Designer.cs}}

Implementation Details:
Use the same {{...}} format as adjacent keys. Place the new keys alphabetically near {{SignInOfflineButtonContentToolTip}} and {{InstallButtonText}} respectively to match existing ordering hygiene.


h3. TASK 2: Attach offline tooltips to PM menu items in {{DynamoView.xaml}} [HIGH PRIORITY]

Status: DONE
Milestone: The three menu children of {{PackageManagerMenu}} (and optionally the parent) show the new tooltip when their hosting commands are disabled.

  • On each of {{publishSelected}}, {{publishCurrent}}, {{showPM}} (lines 616-624), add {{ToolTipService.ShowOnDisabled="True"}}.
  • Attach a {{MenuItem.ToolTip}} containing a {{}} whose {{Style}} has a {{DataTrigger Binding="{Binding PlacementTarget.IsEnabled, RelativeSource={RelativeSource Self}}" Value="False"}} setter for {{Content = {x:Static p:Resources.PackageManagerNoNetworkModeToolTip}}}. When enabled, no tooltip text (or the existing header text).
  • Confirm {{xmlns:p="clr-namespace:Dynamo.Wpf.Properties"}} is already imported at the file root (it is; same prefix as the existing {{Resources.DynamoViewPackageMenu*}} references).

Validation: Launch {{DynamoSandbox.exe --NoNetworkMode}}; open {{Packages}} menu; hover each item; observe the tooltip. Re-launch without {{--NoNetworkMode}}; confirm tooltips do not appear (or show only when the item is genuinely disabled for another reason such as missing auth).

Requirements from spec:

  • “Add tooltips describing PM is disabled in no-network mode” (ticket title).
  • Use the messaging precedent established in DYN-6409.

Files to Modify:

  • {{src/DynamoCoreWpf/Views/Core/DynamoView.xaml}} — {{PackageManagerMenu}} block at lines 612-625.

Implementation Details:
XAML snippet shape (per child):

{code:xml}
<MenuItem.ToolTip>

<ToolTip.Style>
<Style TargetType="ToolTip" BasedOn="{StaticResource GenericToolTipLight}">

<Style.Triggers>




</Style.Triggers>
</Style>
</ToolTip.Style>

</MenuItem.ToolTip>

{code}

Flipping {{Visibility}} rather than {{Content}} keeps the menu visually clean when the command is enabled.


h3. TASK 3: Attach offline tooltip to the right-click {{Publish}} MenuItem in {{WorkspaceView.xaml}} [MEDIUM PRIORITY]

Status: DONE
Milestone: When right-clicking on a custom-node workspace in offline mode, the {{Publish}} context-menu item shows the new tooltip.

  • Apply the same {{ToolTipService.ShowOnDisabled="True"}} + conditional {{ToolTip}} pattern from Task 2 to the {{Publish}} MenuItem at {{src/DynamoCoreWpf/Views/Core/WorkspaceView.xaml:754-758}}.
  • Verify the {{xmlns:p}} prefix is already in scope at the top of {{WorkspaceView.xaml}} (it is, used elsewhere in the file).

Validation: Open a custom-node workspace under {{--NoNetworkMode}}, right-click empty canvas, hover {{Publish}}, see the tooltip.

Requirements from spec:

  • Same as Task 2 — the user must understand why PM is disabled wherever PM is reachable.

Files to Modify:

  • {{src/DynamoCoreWpf/Views/Core/WorkspaceView.xaml}}

Implementation Details:
Reuse the snippet from Task 2 with the existing {{Visibility="{Binding Path=IsHomeSpace, Converter={StaticResource InverseBoolToVisibilityCollapsedConverter}}"}} left intact.


h3. TASK 4: Disable Install button and add tooltip in Workspace References extension [HIGH PRIORITY]

Status: DONE
Milestone: Opening a graph with a missing package dependency in offline mode shows a greyed-out Install Specified Version button whose hover tooltip explains the disablement.

  • Add a new public read-only {{NoNetworkMode}} property to {{WorkspaceDependencyView}} (the partial class in {{WorkspaceDependencyView.xaml.cs}}). Property type: {{bool}}. Wire it through {{INotifyPropertyChanged}} if needed (the class is a {{UserControl}}; {{DependencyProperty}} is unnecessary because the value is set once at construction).
  • In the constructor ({{WorkspaceDependencyView.xaml.cs:140-154}}), assign {{NoNetworkMode = p.StartupParams.NoNetworkMode;}} once.
  • In {{WorkspaceDependencyView.xaml}}, modify the {{DownloadPackageButton}} (lines 250-255):
    ** Add {{IsEnabled="{Binding NoNetworkMode, Converter={StaticResource InverseBooleanConverter}}"}}.
    ** Add {{ToolTipService.ShowOnDisabled="True"}}.
    ** Add a conditional {{<Button.ToolTip>}} using the same {{Style.Triggers}} shape as Task 2 but referencing {{{x:Static w:Resources.InstallButtonNoNetworkModeToolTip}}} (the {{w:}} prefix already maps to {{Dynamo.WorkspaceDependency.Properties}}).
  • Ensure an {{InverseBooleanConverter}} is reachable in the resource scope of {{WorkspaceDependencyView.xaml}}. The file already merges {{DynamoModernDictionaryUri}}; if {{InverseBooleanConverter}} is not exposed there, add a {{}} to {{UserControl.Resources}} (mirror the existing {{BoolToVis}} declaration at line 21). Confirm by grepping {{InverseBooleanConverter}} definition; if absent, prefer two-state {{Style.Triggers}} on the {{Button}} itself (set {{IsEnabled=False}} via {{DataTrigger Binding="{Binding NoNetworkMode}" Value="True"}}).
  • Leave {{KeepLocalPackageButton}}, {{Refresh}}, {{RefreshReferences}}, and {{RefreshExternalReferences}} icons untouched — they are local operations.

Validation: Launch {{DynamoSandbox.exe --NoNetworkMode}}; open {{test/core/packageDependencyTests/PackageDependencyStates.dyn}}; expand a missing-package row; observe the Install button greyed out and the tooltip appearing on hover.

Requirements from spec:

  • “We alse need to disable install package button in workspace references extension and add tooltip.” (ticket body, verbatim, typo preserved.)

Files to Modify:

  • {{src/WorkspaceDependencyViewExtension/WorkspaceDependencyView.xaml.cs}}
  • {{src/WorkspaceDependencyViewExtension/WorkspaceDependencyView.xaml}}

Implementation Details:
Property stub (in {{WorkspaceDependencyView.xaml.cs}}, near the existing {{currentWorkspace}} field):

{noformat}///


/// True when Dynamo started in no-network mode. Bound to the Install button's IsEnabled.
///

public bool NoNetworkMode { get; private set; }{noformat}

Constructor change:

{noformat}NoNetworkMode = p.StartupParams.NoNetworkMode;{noformat}

Because {{DataContext = this;}} is already set (line 143), the binding works without further wiring.

XAML for the button:

{code:xml}
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource SmallTextButton}">
<Style.Triggers>



</Style.Triggers>
</Style>
</Button.Style>
<Button.ToolTip>

<ToolTip.Style>
<Style TargetType="ToolTip" BasedOn="{StaticResource GenericToolTipLight}">

<Style.Triggers>




</Style.Triggers>
</Style>
</ToolTip.Style>

</Button.ToolTip>
{code}

Using a {{RelativeSource AncestorType=UserControl}} binding avoids depending on the row’s {{DataContext}} (which is {{PackageDependencyRow}}) and reaches the {{WorkspaceDependencyView}} where {{NoNetworkMode}} lives.


h3. TASK 5: Add NUnit tests [MEDIUM PRIORITY]

Status: DONE
Milestone: New regression tests pass and would fail if the install button regressed to always-enabled or the resource strings disappeared.

  • In {{test/DynamoCoreWpf2Tests/ViewExtensions/WorkspaceDependencyViewExtensionTests.cs}}, add {{WhenNoNetworkModeThenWorkspaceReferencesInstallButtonIsDisabled}} (NUnit {{[Test]}}). Use the existing test scaffold, pass {{NoNetworkMode = true}} through the model start config, open a graph with a missing dependency, and assert {{viewExtension.DependencyView.FindName("DownloadPackageButton")}} (or a typed accessor) has {{IsEnabled == false}} for the rendered row. If the existing test infrastructure cannot easily restart the model in no-network mode within the same fixture, add a focused unit test that constructs {{WorkspaceDependencyView}} with a stubbed {{ViewLoadedParams}} whose {{StartupParams.NoNetworkMode == true}} and asserts the property propagates.
  • In {{test/DynamoCoreWpfTests/PackageManagerCommandsTests.cs}} (or the closest existing PM commands suite — confirm exact file at implementation time via {{grep -rn CanPublishCurrentWorkspace test/}}), add {{WhenNoNetworkModeThenPmMenuTooltipResourceResolves}} asserting {{Resources.PackageManagerNoNetworkModeToolTip}} returns a non-empty string (cheap guard against the resource being deleted later).
  • Both tests follow the {{WhenConditionThenExpectedBehavior}} naming standard and the Arrange-Act-Assert structure.

Validation: {{dotnet test test/DynamoCoreWpf2Tests/DynamoCoreWpf2Tests.csproj --filter "Name~WhenNoNetworkMode"}} succeeds.

Requirements from spec:

  • Quality gate: every new behavior gets a focused regression test ({{AGENTS.md}} testing rules).

Files to Modify:

  • {{test/DynamoCoreWpf2Tests/ViewExtensions/WorkspaceDependencyViewExtensionTests.cs}}
  • {{test/DynamoCoreWpfTests/...}} (a PM-related test file under {{DynamoCoreWpfTests}})

Implementation Details:
For the workspace-dependency test, the cleanest path is to instantiate {{WorkspaceDependencyView}} directly with a stubbed {{ViewLoadedParams}}. The view's constructor only consumes {{CurrentWorkspaceModel}}, {{PackageInstaller}}, and {{StartupParams.NoNetworkMode}}, so a small mock satisfies the surface. If the existing fixture starts a real {{DynamoModel}}, a second {{[TestFixture]}} derived from {{DynamoModelTestBase}} with {{NoNetworkMode = true}} in the start config is also acceptable; see {{test/System/IntegrationTests/DynamoApplicationTests.cs:71-83}} for the pattern.


h2. Testing Strategy

h3. Unit Tests:

  • New property {{WorkspaceDependencyView.NoNetworkMode}} returns the value passed in via {{StartupParams.NoNetworkMode}}.
  • {{Dynamo.Wpf.Properties.Resources.PackageManagerNoNetworkModeToolTip}} and {{Dynamo.WorkspaceDependency.Properties.Resources.InstallButtonNoNetworkModeToolTip}} resolve to non-empty strings.
  • Existing {{CanPublish*}} / {{CanShowPackageManager*}} predicates continue to return {{false}} under NoNetworkMode (no change expected; spot-check existing coverage).

h3. Integration Tests:

  • Smoke: {{WhenNoNetworkModeThenWorkspaceReferencesInstallButtonIsDisabled}} builds a real {{WorkspaceDependencyView}}, loads {{PackageDependencyStates.dyn}}, and asserts the rendered Install button is {{IsEnabled = false}}.
  • Optional: a Wpf3 visual smoke test asserting {{MenuItem.ToolTip}} is non-null for the three PM menu items when the host model has {{NoNetworkMode = true}}.

h3. Manual Testing Steps:

Build full UI: {{msbuild src/Dynamo.All.sln /p:Configuration=Release}}.

Launch {{DynamoSandbox.exe --NoNetworkMode}}.

Open the {{Packages}} menu — confirm all three children are greyed out; hover each; confirm the new tooltip appears.

Open a custom-node workspace (e.g. open any {{.dyf}} from {{test/core/CustomNodes/}}); right-click the canvas; confirm {{Publish}} is greyed and the tooltip appears.

Open a graph with a known-missing package dependency (e.g. {{test/core/packageDependencyTests/PackageDependencyStates.dyn}}); open the Workspace References panel; expand a missing-package row; confirm the Install Specified Version button is greyed and the new tooltip appears. Click should be a no-op.

Confirm Keep Installed Version and the Refresh icons still work.

Relaunch without {{--NoNetworkMode}}; confirm every affected control is functional, the new tooltips do not appear, and existing tooltips (e.g. on the Sign-In button) still behave as before.

h2. Performance Considerations

None. The change is XAML data binding + a single boolean property assigned once at construction; no per-frame allocations and no impact on graph evaluation paths.

h2. Migration Notes

None. No public API additions; no preference-settings migrations; no on-disk format changes. The {{master-localization}} merge will pick up the new English resource keys on the next pass and translators will fill in the locale {{.resx}} files automatically.

@eamiri eamiri added the kiln Created by kiln label Jun 8, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

See the ticket for this pull request: https://jira.autodesk.com/browse/DYN-8957

eamiri and others added 4 commits June 8, 2026 14:17
Adds PackageManagerNoNetworkModeToolTip to DynamoCoreWpf resources and
InstallButtonNoNetworkModeToolTip to WorkspaceDependencyViewExtension
resources, mirroring the SignInOfflineButtonContentToolTip precedent.
…-8957)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds a NoNetworkMode property to WorkspaceDependencyView wired from
StartupParams, and uses it to disable the Install Specified Version
button with the no-network tooltip when Dynamo runs with --NoNetworkMode.
Adds NUnit regression tests for the disabled state and tooltip resource
strings.
@eamiri eamiri marked this pull request as ready for review June 8, 2026 18:26
@eamiri eamiri added the pr_ready PR is ready for review label Jun 8, 2026
@sonarqubecloud

sonarqubecloud Bot commented Jun 8, 2026

Copy link
Copy Markdown

[TestFixture]
public class WorkspaceDependencyViewExtensionNoNetworkModeTests : DynamoTestUIBase
{
private WorkspaceDependencyViewExtension viewExtension = new WorkspaceDependencyViewExtension();
@eamiri eamiri closed this Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kiln Created by kiln pr_ready PR is ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant