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

Support for inline actions #865

Closed
6 tasks
dclaux opened this issue Oct 30, 2017 · 9 comments
Closed
6 tasks

Support for inline actions #865

dclaux opened this issue Oct 30, 2017 · 9 comments

Comments

@dclaux
Copy link
Member

dclaux commented Oct 30, 2017

Implementation status

  • TypeScript (host apps can handle the onAnchorClicked event)
  • UWP
  • .NET
  • iOS
  • Android
  • Documentation

Problem

There are quite a few scenarios where it makes sense to have an action displayed as a link on a part of the text in a TextBlock. As an example, GitHub is showing this as I write this issue:

image

In that screenshot, contributing is just a link, but in the context of Adaptive, card authors may want to hook it to a Submit or ShowCard action (or even Http action in Outlook.)

Asks

  • Microsoft Teams
  • Outlook

Solution

To support this, the proposal is to use standard markdown markup to make the text a link and use a special "protocol" name (namely action) in the URL part. The host would be responsible for handling the "action" protocol and fall back to system processing if the protocol isn't "action". This capability would be exposed by renderers through, for example, an event.

ALT: [aleader] Shouldn't the renderer handle the "action" protocol itself? With the option for the host to override it? This should work by default when installing the SDK, rather than requiring the host to add code to support this.

By using markdown as the solution, any markdown-enabled string in Adaptive can now embed actions.

Of course this requires that the action referenced in markup be defined as a card-wide resource, as it would not really practical to fully specify an action within a string. The proposal is to add a resources property to the AdaptiveCard type, and in that resources property add an actions collection. We can add more resource types in the future.

Example

So let's say the above screen grab is done with Adaptive and clicking "contributing" triggers a Submit action. The payload for such a card would be this:

{
	"type": "AdaptiveCard",
	"body": [
		{
			"type": "TextBlock",
			"text": "Before you open an issue please review the [contributing](action:contributeAction) guidelines for this repository."
		}
	],
	"resources": {
		"actions": [
			{
				"type": "Action.Submit",
				"id": "contributeAction",
				...
			}
		]
	}
}

Alternate solution 2

[Andrew Leader] Mimick what XAML does with RichTextBlock... This wouldn't require the addition of a resources array of actions to be referenced.

{
  "type": "RichTextBlock",
  "wrap": 2,
  "paragraphs": [
    {
      "inlines": [
        {
          "type": "TextRun",
          "text": "Before you open an issue please review the "
        },
        {
          "type": "TextRun",
          "text": "contributing",
          "selectAction": {
            "type": "Action.Submit",
            
          }
        },
        {
          "type": "TextRun",
          "text": " guidelines for this repository."
        }
      ]
    }
  ]
}

This could also be our solution for inline colors, #1079, and inline advanced emojis #1645, and inline text highlighting #1885

@ignacionr
Copy link
Contributor

Please allow actions in resources to be included, even if not explicitly tied to a link. I.e. please don't check if they're referenced inside the card, because that allows for a number of scenarios where actions are to be handled by the host and triggered outside the immediate card UI.

@andrewleader
Copy link
Contributor

Hey @ignacionr can you give an example of the scenario you're worried about? As the proposed spec was written, the author is explicitly choosing whether to use an inline action, or the standard actions.

@andrewleader
Copy link
Contributor

I like this, just a few things I think should be changed...

Right now, the spec says it's the host's responsibility to handle the clicks? Shouldn't we instead have the renderer handle these clicks by default, and then if the host wants to override it, they can? Providing the default implementation is the only way this will be supported by all hosts.

For the resources section, I assume the actions section is an array instead of a isn't a key-value pair based on ID, since in the future we're thinking that actions themselves will gain an id property?

As it stands today, it seems to make more sense if it was key-value pair, like...

	"resources": {
		"actions": {
			"contributeAction": {
				"type": "Action.Submit",
				...
			}
	         }
    }

But if actions will gain an id property in the future for other purposes, then it probably makes sense to go with the array that you had.

@dclaux
Copy link
Member Author

dclaux commented Jul 22, 2018

@andrewleader yes we can totally have the renderer automatically handle the action, there is indeed no need to require that the host implements the logic.

As to the actions collection being keyed by Id, that is definitely a possibility but the reason I am proposing the other model is because actions already have an Id property, as per #493

@andrewleader
Copy link
Contributor

Oh I missed that, seems like the documentation was never updated, the schema explorer is still missing the id property.

In that case, I agree with the proposal (the array)!

@ignacionr
Copy link
Contributor

@andrewleader hey! My only concern is, since our implementations go past parsing (e.g. they purposely remove values that are not defined in enumerations), I worried that if a certain resource isn't used it may get removed from the model. But I don't think anybody needs to go to those extents. As soon as we get this into the models I'll probably propose a unit test.

@andrewleader
Copy link
Contributor

I don't think we'd remove resources that aren't used (as that'd require extra work to implement).

In parsing an object, we only parse known properties, but this is an array of resources, so by definition we'd simply parse each one. Removing one if it wasn't used would require extra coding with likely very little benefit.

What's the scenario you're thinking of that would require non-consumed resources to be parsed? Just to make sure we're thinking about the end-to-end scenario.

I believe custom elements (host-defined elements) would require all resources to be parsed, wondering if you have another scenario in mind.

@andrewleader
Copy link
Contributor

Proposal needs more review time. Concerns around...

  • Making sure this is compatible with universal actions
  • The general markdown debate

@andrewleader
Copy link
Contributor

Closing in favor of using inline text runs (#1933) to achieve actions within text

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants