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

Add ability for Dev Home to display settings cards from an adaptive card #2488

Merged
merged 13 commits into from
Apr 5, 2024

Conversation

bbonaby
Copy link
Contributor

@bbonaby bbonaby commented Mar 29, 2024

Summary of the pull request

This PR is 1 of 4 other PRs that I'll be submitting to allow creation. (I'm putting them in a feature branch first)

As part of the work to allow extensions to create environments within Dev Home, we wanted to give them the ability to use adaptive cards as the UI. This is because we won't know all the different capabilities/controls an extension wants to show in their UI, so using adaptive cards for this was the natural choice. However adaptive cards can be constraining in what it supports out of the box. With that said they give us the ability to create custom renders and custom types. To do this we also need to create a custom parser for the custom types. I also added a custom type to launch a dialog an adaptive card. This PR also allows us to invoke an adaptive cards submit button from within Dev Home.

The settings adaptive settings card will show up in the second page of the creation flow (if an extension chooses to use it)

The UI for the video below will be in a separate PR but this shows me getting the cards from the Hyper-V Extension. Alot of this code is just Parsing Json.

CreateEnvironmentFlowUpToReviewPage.mp4

Note: I'm ok with any changes that need to be reworked, as I'd like this to be a general solution we can use in Dev Home. We do plan on circling back in the future to see if we can add a listview type support to the official adaptive cards codebase. However, that is future work.

References and relevant issues

Detailed description of the pull request / Additional comments

Here is an actual example of the usage. Its what we're using in the Hyper-V extension when sending our adaptive card to Dev Home.

{
  "type": "AdaptiveCard",
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.5",
  "body": [
    {
      "type": "Input.Text",
      "id": "NewVirtualMachineName",
      "label": "${EnterNewVMNameLabel}",
      "placeholder": "${EnterNewVMNamePlaceHolder}",
      "maxLength": 100,
      "isRequired": true,
      "Spacing": "Large"
    },
    {
      "type": "DevHome.SettingsCardChoiceSet",
      "id": "SelectedImageListIndex",
      "label": "${SettingsCardLabel}",
      "isRequired": true,
      "devHomeSettingsCards": [
        {
          "type": "DevHome.SettingsCard",
          "$data": "${GalleryImages}",
          "devHomeSettingsCardDescription": "${SubDescription}",
          "devHomeSettingsCardHeader": "${Header}",
          "devHomeSettingsCardHeaderIcon": "${HeaderIcon}",
          "devHomeSettingsCardActionElement": {
            "type": "DevHome.LaunchContentDialogButton",
            "devHomeActionText": "${ButtonToLaunchContentDialogLabel}",
            "devHomeContentDialogContent": {
              "devHomeContentDialogTitle": "${Header}",
              "devHomeContentDialogBodyAdaptiveCard": {
                "type": "AdaptiveCard",
                "version": "1.5",
                "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                "body": [
                  {
                    "type": "Container",
                    "$data": "${ContentDialogInfo}",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "${ImageDescription}",
                        "isMultiline": true,
                        "Spacing": "Medium",
                        "size": "Medium",
                        "wrap": true
                      },
                      {
                        "$data": "${GalleryImageFacts}",
                        "type": "FactSet",
                        "facts": [
                          {
                            "title": "${title}",
                            "value": "${value}"
                          }
                        ]
                      }
                    ]
                  }
                ]
              },
              "devHomeContentDialogSecondaryButtonText": "${SecondaryButtonForContentDialogText}"
            }
          }
        }
      ]
    },
    {
      "type": "ActionSet",
      "actions": [
        {
          "id": "DevHomeMachineConfigurationNextButton",
          "type": "Action.Submit",
          "title": "${PrimaryButtonLabelForCreationFlow}"
        },
        {
          "id": "DevHomeMachineConfigurationPreviousButton",
          "type": "Action.Submit",
          "title": "${SecondaryButtonLabelForCreationFlow}"
        }
      ]
    }
  ]
}

Validation steps performed

PR checklist

  • Closes #xxx
  • Tests added/passed
  • Documentation updated

@bbonaby bbonaby changed the base branch from main to microsoftfeature/environments-creation March 29, 2024 19:40

namespace DevHome.Common.Contracts;

public interface IDevHomeActionRender : IAdaptiveElementRenderer
Copy link
Contributor

Choose a reason for hiding this comment

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

ACs have IAdaptiveElementRenderer and IAdaptiveActionRenderer. This seems to be an interface for elements, so it would be called IDevHomeElementRenderer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually this one is suppose to just be the custom renderer for an ActionSet but I can update the name

var parseResult = AdaptiveCard.FromJsonString(adaptiveCardString);
AdaptiveCardParseResult parseResult;

if (_actionParserRegistration != null && _elementParserRegistration != null)
Copy link
Contributor

@krschau krschau Mar 29, 2024

Choose a reason for hiding this comment

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

Maybe simpler: Have one constructor where the two *ParserRegistrations are optional, and do like

_elementParserRegistration = elementParserRegistration != null ? elementParserRegistration : new AdaptiveElementParserRegistration();

Then you don't need the if/else here or in ExtensionAdaptiveCardPanel.cs, I think. Also if in the future there was a case where we had only a custom action parser or only element parser, it would handle that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll try that out

@krschau
Copy link
Contributor

krschau commented Apr 2, 2024

I'm not sure there's a way around this (I'd hope so, but I'm a "git rebase" person not a "git merge" person), but this PR contains a lot of the changes that are already merged into main, making it difficult to review right now.

@bbonaby
Copy link
Contributor Author

bbonaby commented Apr 2, 2024

@krschau whoops, I merged main into this branch but forgot to merge main into the feature branch. After merging main into the feature branch, only my changes look to be appearing now. Sorry about that

/// <returns>
/// A boolean indicating whether validation for the card passed or failed.
/// </returns>
public bool TryValidateAndInitiateAction(string buttonId, AdaptiveInputs userInputs)
Copy link
Contributor

Choose a reason for hiding this comment

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

Co-authored-by: Kristen Schau <47155823+krschau@users.noreply.github.com>
return true;
}

if (_itemsView.SelectedItem == null || _itemsView.CurrentItemIndex < 0)
Copy link
Member

Choose a reason for hiding this comment

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

Coding guidelines: "Use parentheses to make clauses in an expression apparent".
This is in Windows C++ guidelines and in C# Common code conventions.

@sshilov7
Copy link
Member

sshilov7 commented Apr 4, 2024

I feel like a couple of screenshots with highlighted IDevHomeSettingsCardNonSubmitAction button and DevHomeSettingsCard would be more informative than the attached video where I don't really know what to look at.

@bbonaby bbonaby mentioned this pull request Apr 5, 2024
3 tasks
@bbonaby bbonaby changed the base branch from microsoftfeature/environments-creation to main April 5, 2024 18:25
@bbonaby bbonaby merged commit c92f776 into main Apr 5, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants