Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Loading and Summary pages for target configuration to look similar to local device configuration flow #2527

Merged
merged 13 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ private void SendMessage(string name, string value, CancellationToken stoppingTo
string errorDescription;
if (!WmiUtility.JobCompleted(outParams, _scope, out errorCode, out errorDescription))
{
throw new System.ComponentModel.Win32Exception((int)errorCode, $"Cannot send message to '{_vmId.ToString("D")}' VM: '{errorDescription}'.");
throw new System.ComponentModel.Win32Exception((int)errorCode, $"Cannot send message to VM '{_vmId.ToString("D")}': '{errorDescription}'.");
}
}
else if ((uint)outParams["ReturnValue"] != (uint)WmiUtility.ReturnCode.Completed)
{
throw new System.ComponentModel.Win32Exception((int)outParams["ReturnValue"], $"Cannot send message to '{_vmId.ToString("D")}' VM: '{outParams["ReturnValue"]}'.");
throw new System.ComponentModel.Win32Exception((int)outParams["ReturnValue"], $"Cannot send message to VM '{_vmId.ToString("D")}': '{outParams["ReturnValue"]}'.");
}
else
{
Expand Down
5 changes: 5 additions & 0 deletions tools/SetupFlow/DevHome.SetupFlow/Models/CloneRepoTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ public string ProviderName
/// </summary>
public bool RequiresReboot => false;

/// <summary>
/// Gets target device name. Inherited via ISetupTask but unused.
/// </summary>
public string TargetName => string.Empty;

/// <summary>
/// The developer ID that is used when a repository is being cloned.
/// </summary>
Expand Down
114 changes: 77 additions & 37 deletions tools/SetupFlow/DevHome.SetupFlow/Models/ConfigureTargetTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
using DevHome.SetupFlow.Common.Exceptions;
using DevHome.SetupFlow.Exceptions;
using DevHome.SetupFlow.Models.WingetConfigure;
using DevHome.SetupFlow.Services;
using DevHome.SetupFlow.ViewModels;
using DevHome.SetupFlow.Services;
using DevHome.SetupFlow.ViewModels;
using Microsoft.UI.Xaml;
using Microsoft.Windows.DevHome.SDK;
using Projection::DevHome.SetupFlow.ElevatedComponent;
Expand Down Expand Up @@ -50,6 +50,11 @@ public class ConfigureTargetTask : ISetupTask
// Inherited via ISetupTask but unused
public bool RequiresReboot => false;

// Inherited via ISetupTask
public string TargetName => string.IsNullOrEmpty(ComputeSystemName) ?
_stringResource.GetLocalized(StringResourceKey.SetupTargetMachineName) :
ComputeSystemName;

// Inherited via ISetupTask but unused
public bool DependsOnDevDriveToBeInstalled => false;

Expand All @@ -61,7 +66,7 @@ public class ConfigureTargetTask : ISetupTask

public ActionCenterMessages ActionCenterMessages { get; set; } = new() { ExtensionAdaptiveCardPanel = new(), };

public string ComputeSystemName { get; private set; } = string.Empty;
public string ComputeSystemName => _computeSystemManager.ComputeSystemSetupItem.ComputeSystemToSetup.DisplayName ?? string.Empty;

public SDK.IExtensionAdaptiveCardSession2 ExtensionAdaptiveCardSession { get; private set; }

Expand All @@ -84,9 +89,9 @@ public class ConfigureTargetTask : ISetupTask
public SDKApplyConfigurationResult Result { get; private set; }

public IAsyncOperation<ApplyConfigurationResult> ApplyConfigurationAsyncOperation { get; private set; }

public ISummaryInformationViewModel SummaryScreenInformation { get; }

public ConfigureTargetTask(
ISetupFlowStringResource stringResource,
IComputeSystemManager computeSystemManager,
Expand Down Expand Up @@ -147,8 +152,8 @@ public void OnActionRequired(IApplyConfigurationOperation operation, SDK.ApplyCo
ExtensionAdaptiveCardSession.Stopped += OnAdaptiveCardSessionStopped;

CreateCorrectiveActionPanel(ExtensionAdaptiveCardSession).GetAwaiter().GetResult();

AddMessage(_stringResource.GetLocalized(StringResourceKey.ConfigureTargetApplyConfigurationActionNeeded, UserNumberOfAttempts++, UserMaxNumberOfAttempts), MessageSeverityKind.Warning);
AddMessage(_stringResource.GetLocalized(StringResourceKey.ConfigureTargetApplyConfigurationActionNeeded, UserNumberOfAttempts++, UserMaxNumberOfAttempts), MessageSeverityKind.Warning);
}
else
{
Expand All @@ -174,7 +179,6 @@ public void OnApplyConfigurationOperationChanged(object sender, SDK.Configuratio
var wrapper = new SDKConfigurationSetChangeWrapper(progressData, _stringResource);
var potentialErrorMsg = wrapper.GetErrorMessagesForDisplay();
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine("---- " + _stringResource.GetLocalized(StringResourceKey.SetupTargetConfigurationProgressUpdate) + " ----");
var startingLineNumber = 0u;

if (wrapper.Change == SDK.ConfigurationSetChangeEventType.SetStateChanged)
Expand All @@ -195,22 +199,46 @@ public void OnApplyConfigurationOperationChanged(object sender, SDK.Configuratio
// there is no way for us to know what the extension is doing, it may not have started configuration yet but may simply be installing prerequisites.
if (wrapper.Unit != null)
{
// We may need to change the formatting of the message in the future.
var description = BuildConfigurationUnitDescription(wrapper.Unit);
stringBuilder.AppendLine(GetSpacingForProgressMessage(startingLineNumber++) + description);
stringBuilder.AppendLine(GetSpacingForProgressMessage(startingLineNumber++) + wrapper.ConfigurationUnitState);
// Showing "pending" unit states is not useful to the user, so we'll ignore them.
if (wrapper.UnitState != ConfigurationUnitState.Pending)
{
var description = BuildConfigurationUnitDescription(wrapper.Unit);
stringBuilder.AppendLine(description.packageIdDescription);
if (!string.IsNullOrEmpty(description.packageNameDescription))
{
stringBuilder.AppendLine(description.packageNameDescription);
}

stringBuilder.AppendLine(wrapper.ConfigurationUnitState);
if ((wrapper.UnitState == ConfigurationUnitState.Completed) && !wrapper.IsErrorMessagePresent)
{
severity = MessageSeverityKind.Success;
}
}
else
{
_log.Information("Ignoring configuration unit pending state.");
}
}
else
{
_log.Information("Extension sent progress but there was no configuration unit data sent.");
}

// Example of a message that will be displayed in the UI:
// ---- Configuration progress received! ----
// There was an issue applying part of the configuration using DSC resource: 'GitClone'.Check the extension's logs
// - Assert : GitClone[Clone: wil - C:\Users\Public\Documents\source\repos\wil]
// - This part of the configuration is now complete
AddMessage(stringBuilder.ToString(), severity);
// Examples of a message that will be displayed in the UI:
// Apply: WinGetPackage [Microsoft.VisualStudioCode]
// Install: Microsoft Visual Studio Code
// Configuration applied
//
// There was an issue applying part of the configuration using DSC resource: 'WinGetPackage'.Error: WinGetPackage Failed installing Notepad++.Notepad++.
// InstallStatus 'InstallError' InstallerErrorCode '0' ExtendedError '-2147023673'
// Apply: WinGetPackage[Notepad++.Notepad++]
// Install: Notepad++
// Configuration applied
if (stringBuilder.Length > 0)
{
AddMessage(stringBuilder.ToString(), severity);
}
}
catch (Exception ex)
{
Expand Down Expand Up @@ -265,12 +293,6 @@ public void HandleCompletedOperation(SDK.ApplyConfigurationResult applyConfigura
throw new OpenConfigurationSetException(Result.OpenResult.ResultCode, Result.OpenResult.Field, Result.OpenResult.Value);
}

// Check if the WinGet apply operation was failed.
if (!Result.ApplyConfigSucceeded)
{
throw new SDKApplyConfigurationSetResultException("Unable to get the result of the apply configuration set as it was null.");
}

// Gather the configuration results. We'll display these to the user in the summary page if they are available.
if (Result.ApplyResult.AreConfigUnitsAvailable)
{
Expand All @@ -283,6 +305,19 @@ public void HandleCompletedOperation(SDK.ApplyConfigurationResult applyConfigura
}
else
{
// Check if the WinGet apply operation failed.
if (Result.ApplyResult.ResultException != null)
{
// TODO: We should propagate this error to Summery page.
throw Result.ApplyResult.ResultException;
}
else if (!Result.ApplyConfigSucceeded)
{
// Failed, but no configuration units and no result exception. Something is wrong with result reporting.
throw new SDKApplyConfigurationSetResultException("Unable to get the result of the apply configuration set as it was null.");
}

// Succeeded, but no configuration units. Something is wrong with result reporting.
throw new SDKApplyConfigurationSetResultException("No configuration units were found. This is likely due to an error within the extension.");
}
}
Expand Down Expand Up @@ -325,10 +360,9 @@ public IAsyncOperation<TaskFinishedState> Execute()
try
{
UserNumberOfAttempts = 1;
var computeSystem = _computeSystemManager.ComputeSystemSetupItem.ComputeSystemToSetup;
ComputeSystemName = computeSystem.DisplayName;
AddMessage(_stringResource.GetLocalized(StringResourceKey.SetupTargetExtensionApplyingConfiguration, ComputeSystemName), MessageSeverityKind.Info);
WingetConfigFileString = _configurationFileBuilder.BuildConfigFileStringFromTaskGroups(_setupFlowOrchestrator.TaskGroups, ConfigurationFileKind.SetupTarget);
var computeSystem = _computeSystemManager.ComputeSystemSetupItem.ComputeSystemToSetup;
var applyConfigurationOperation = computeSystem.ApplyConfiguration(WingetConfigFileString);

applyConfigurationOperation.ConfigurationSetStateChanged += OnApplyConfigurationOperationChanged;
Expand Down Expand Up @@ -381,14 +415,12 @@ public IAsyncOperation<TaskFinishedState> Execute()

TaskMessages ISetupTask.GetLoadingMessages()
{
var localizedTargetName = _stringResource.GetLocalized(StringResourceKey.SetupTargetMachineName);
var nameToUseInDisplay = string.IsNullOrEmpty(ComputeSystemName) ? localizedTargetName : ComputeSystemName;
return new()
{
Executing = _stringResource.GetLocalized(StringResourceKey.SetupTargetExtensionApplyingConfiguration, nameToUseInDisplay),
Error = _stringResource.GetLocalized(StringResourceKey.SetupTargetExtensionApplyConfigurationError, nameToUseInDisplay),
Finished = _stringResource.GetLocalized(StringResourceKey.SetupTargetExtensionApplyConfigurationSuccess, nameToUseInDisplay),
NeedsReboot = _stringResource.GetLocalized(StringResourceKey.SetupTargetExtensionApplyConfigurationRebootRequired, nameToUseInDisplay),
Executing = _stringResource.GetLocalized(StringResourceKey.SetupTargetExtensionApplyingConfiguration, TargetName),
Error = _stringResource.GetLocalized(StringResourceKey.SetupTargetExtensionApplyConfigurationError, TargetName),
Finished = _stringResource.GetLocalized(StringResourceKey.SetupTargetExtensionApplyConfigurationSuccess, TargetName),
NeedsReboot = _stringResource.GetLocalized(StringResourceKey.SetupTargetExtensionApplyConfigurationRebootRequired, TargetName),
};
}

Expand Down Expand Up @@ -433,7 +465,7 @@ await _windowEx.DispatcherQueue.EnqueueAsync(async () =>
});
}

private string BuildConfigurationUnitDescription(ConfigurationUnit unit)
private (string packageIdDescription, string packageNameDescription) BuildConfigurationUnitDescription(ConfigurationUnit unit)
{
var unitDescription = string.Empty;

Expand All @@ -444,19 +476,27 @@ private string BuildConfigurationUnitDescription(ConfigurationUnit unit)

if (string.IsNullOrEmpty(unit.Identifier) && string.IsNullOrEmpty(unitDescription))
{
return _stringResource.GetLocalized(StringResourceKey.ConfigurationUnitSummaryMinimal, unit.Intent, unit.Type);
return (_stringResource.GetLocalized(StringResourceKey.ConfigurationUnitSummaryMinimal, unit.Intent, unit.Type), string.Empty);
}

if (string.IsNullOrEmpty(unit.Identifier))
{
return _stringResource.GetLocalized(StringResourceKey.ConfigurationUnitSummaryNoId, unit.Intent, unit.Type, unitDescription);
return (_stringResource.GetLocalized(StringResourceKey.ConfigurationUnitSummaryNoId, unit.Intent, unit.Type, unitDescription), string.Empty);
}

var descriptionParts = unit.Identifier.Split(ConfigurationFileBuilder.PackageNameSeparator);
var packageId = descriptionParts[0];
var packageName = string.Empty;
if (descriptionParts.Length > 1)
{
packageName = $"Install: {descriptionParts[1]}";
}

if (string.IsNullOrEmpty(unitDescription))
{
return _stringResource.GetLocalized(StringResourceKey.ConfigurationUnitSummaryNoDescription, unit.Intent, unit.Type, unit.Identifier);
return (_stringResource.GetLocalized(StringResourceKey.ConfigurationUnitSummaryNoDescription, unit.Intent, unit.Type, packageId), packageName);
}

return _stringResource.GetLocalized(StringResourceKey.ConfigurationUnitSummaryFull, unit.Intent, unit.Type, unit.Identifier, unitDescription);
return (_stringResource.GetLocalized(StringResourceKey.ConfigurationUnitSummaryFull, unit.Intent, unit.Type, packageId, unitDescription), packageName);
}
}
5 changes: 5 additions & 0 deletions tools/SetupFlow/DevHome.SetupFlow/Models/ConfigureTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ public class ConfigureTask : ISetupTask

public bool RequiresReboot { get; private set; }

/// <summary>
/// Gets target device name. Inherited via ISetupTask but unused.
/// </summary>
public string TargetName => string.Empty;

public bool DependsOnDevDriveToBeInstalled => false;

public IList<ConfigurationUnitResult> UnitResults
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ internal sealed class CreateDevDriveTask : ISetupTask

public bool RequiresReboot => false;

/// <summary>
/// Gets target device name. Inherited via ISetupTask but unused.
/// </summary>
public string TargetName => string.Empty;

public bool DependsOnDevDriveToBeInstalled => false;

public IDevDrive DevDrive
Expand Down
8 changes: 8 additions & 0 deletions tools/SetupFlow/DevHome.SetupFlow/Models/ISetupTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ public bool RequiresReboot
get;
}

/// <summary>
/// Gets target device name.
/// </summary>
public string TargetName
{
get;
}

/// <summary>
/// Executes this setup task.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ public class InstallPackageTask : ISetupTask
// installation in the WinGet COM API, but we do get it after installation.
public bool RequiresReboot { get; set; }

/// <summary>
/// Gets target device name. Inherited via ISetupTask but unused.
/// </summary>
public string TargetName => string.Empty;

// May potentially be moved to a central list in the future.
public bool WasInstallSuccessful
{
Expand Down
Loading
Loading