-
Notifications
You must be signed in to change notification settings - Fork 359
/
Copy pathDevHomeActionSet.cs
136 lines (112 loc) · 4.75 KB
/
DevHomeActionSet.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Collections.Generic;
using AdaptiveCards.ObjectModel.WinUI3;
using AdaptiveCards.Rendering.WinUI3;
using DevHome.Common.Contracts;
using Microsoft.UI.Xaml;
namespace DevHome.Common.Renderers;
/// <summary>
/// Represents whether the adaptive card button in an action set should be visible or hidden in Dev Home's UI.
/// Although adaptive cards can natively hide elements, this is used on the Dev Home side to hide the action set
/// in cases where a page in Dev Home wants its own button to invoke the action in the adaptive card.
/// </summary>
public enum TopLevelCardActionSetVisibility
{
Visible,
Hidden,
}
/// <summary>
/// Allows Dev Home to attach an action to a button in the Dev Home UI.
/// Dev Home can use this to invoke an action from an adaptive card when
/// a button within Dev Home is clicked. It allows Dev Home to link buttons from
/// within its own UI the to top level action set in the adaptive card.
/// </summary>
/// <remarks>
/// It is expected that the adaptive card will have a top level action set with buttons that Dev Home can link to.
/// </remarks>
public class DevHomeActionSet : IDevHomeActionSetRender
{
/// <summary>
/// Gets the visibility of the action in Dev Home's UI.
/// </summary>
private readonly TopLevelCardActionSetVisibility _actionSetVisibility;
private const string TopLevelCardActionId = "DevHomeTopLevelActionSet";
/// <summary>
/// Gets the adaptive card object that will invoke an action within the action set.
/// </summary>
public AdaptiveActionInvoker? ActionButtonInvoker { get; private set; }
public AdaptiveCard? OriginalAdaptiveCard { get; private set; }
private Dictionary<string, IAdaptiveActionElement> ActionButtonMap { get; } = new();
public DevHomeActionSet(TopLevelCardActionSetVisibility cardActionSetVisibility)
{
_actionSetVisibility = cardActionSetVisibility;
}
public UIElement? Render(IAdaptiveCardElement element, AdaptiveRenderContext context, AdaptiveRenderArgs renderArgs)
{
ActionButtonMap.Clear();
if (element is AdaptiveActionSet actionSet)
{
foreach (var action in actionSet.Actions)
{
if (action is AdaptiveExecuteAction executeAction)
{
context.LinkSubmitActionToCard(executeAction, renderArgs);
}
else if (action is AdaptiveSubmitAction submitAction)
{
context.LinkSubmitActionToCard(submitAction, renderArgs);
}
ActionButtonMap.TryAdd(action.Id, action);
}
ActionButtonInvoker = context.ActionInvoker;
OriginalAdaptiveCard = renderArgs.ParentCard;
if (_actionSetVisibility == TopLevelCardActionSetVisibility.Hidden &&
actionSet.Id.Equals(TopLevelCardActionId, System.StringComparison.OrdinalIgnoreCase))
{
// the page in Dev Home does not want to show the action set in the card.
// So we return null to prevent the adaptive card buttons from appearing.
// Invoking the button from Dev Home will then trigger the action in the adaptive card.
return null;
}
}
var renderer = new AdaptiveActionSetRenderer();
return renderer.Render(element, context, renderArgs);
}
/// <summary>
/// Invokes an adaptive card action from anywhere within Dev Home, like a method in a view Model for example.
/// A boolean is returned with the validation result of the card. We still send the action event so the adaptive
/// cards UI updates with error information.
/// </summary>
/// <returns>
/// A boolean indicating whether validation for the card passed or failed.
/// </returns>
public bool TryValidateAndInitiateAction(string buttonId, AdaptiveInputs userInputs)
{
ActionButtonMap.TryGetValue(buttonId, out var actionElement);
if ((actionElement == null) || (userInputs == null))
{
return false;
}
var result = userInputs.ValidateInputs(actionElement);
ActionButtonInvoker?.SendActionEvent(actionElement);
return result;
}
public void InitiateAction(string buttonId)
{
ActionButtonMap.TryGetValue(buttonId, out var actionElement);
if (actionElement == null)
{
return;
}
ActionButtonInvoker?.SendActionEvent(actionElement);
}
public string GetActionTitle(string buttonId)
{
if (!ActionButtonMap.TryGetValue(buttonId, out var action))
{
return string.Empty;
}
return action.Title;
}
}