I am trying to find a way to disable the Action.Submit action type and all inputs of adaptive cards that are not the most recent message in the conversation. I found this option of using the attachmentMiddleware
of the BotFramework-Webchat used in React.
const attachmentMiddleware = () => next => ({ activity, attachment, ...others }) => {
if (attachment.contentType === "application/vnd.microsoft.card.custom") {
attachment.contentType = "application/vnd.microsoft.card.adaptive"
}
const { activities } = store.getState()
const messageActivities = activities.filter(
activity =>
activity.type === "message" &&
typeof activity.suggestedActions === "undefined" // to filter out suggested actions
)
const recentBotMessage = messageActivities.pop() === activity
const AdaptiveCardContent = Components.AdaptiveCardContent
switch (attachment.contentType) {
case "application/vnd.microsoft.card.adaptive":
return (
<AdaptiveCardContent
actionPerformedClassName="card__action--performed"
content={
attachment.content
}
disabled={!recentBotMessage}
/>
)
default:
return next({ activity, attachment, ...others })
}
}
This solution sets the disabled property in the AdaptiveCardContent Component for not recent messages by the bot and works really well except for Action.OpenUrl actions on containers. Any Action.OpenUrl will have no functionality, but will look like it is still an enabled button. Example Screenshot:
As seen in the screenshot, the "primary" actions at the bottom of type Action.Submit are disabled correctly. Now the Action.ToggleVisibility ("Toggle", which changes the visibility of an text) and the Action.OpenUrl ("Open in new tab") are not disabled. The Action.ToggleVisibility ("Toggle") works as it did before, which is our intended behavior and fine. But the Action.OpenUrl which looks like it is still clickable, is in fact not.
I think it is because of the following line #107 and #108 in botframework-webchat\src\adaptiveCards\Attachment\AdaptiveCardRenderer.tsx
:
// Only listen to event if it is not disabled and have "tapAction" prop.
const handleClickAndKeyPressForTapAction = !disabled && tapAction ? handleClickAndKeyPress : undefined;
But I do not understand why the Action.ToggleVisibility actions work just fine and the Action.OpenUrl actions, which html elements are not disabled and have no aria-disabled="true"
properties, have no handling for clicking them.
I tried a completely different way of achieving this behavior by modifying the card, that is given to the AdaptiveCardContent
, but this way leads to not wanted effects like loosing the inputted values of users after disabling the inputs, since it seems the usePersistValuesModEffect
is overwritten or something, or like some unwanted effects from re-rendering the changed adaptive card.
Does anybody know if this is a bug or intended behavior of the disabled property and if so if there is a good working solution to disable inputs and only Action.Submit actions of adaptive cards?
EDIT:
This is the attachment.content
value, meaning the adaptive card that is given to the <AdaptiveCardContent>
component:
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"version": "1.3",
"speak": "",
"body": [
{
"type": "Container",
"id": "content",
"items": [
{
"type": "TextBlock",
"weight": "bolder",
"text": "A title",
"wrap": true
},
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"id": "descriptionPreview",
"text": "Some Content",
"wrap": true
}
],
"spacing": "medium",
"separator": true
},
{
"type": "Container",
"items": [
{
"type": "Container",
"items": [
{
"type": "ColumnSet",
"id": "nonBlocking3",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"id": "toggleKCostDown",
"weight": "bolder",
"text": "Cost",
"wrap": true
},
{
"type": "TextBlock",
"id": "toggleCostUp",
"weight": "bolder",
"text": "Cost",
"wrap": true,
"isVisible": false
}
],
"verticalContentAlignment": "center"
}
],
"style": "accent",
"selectAction": {
"type": "Action.ToggleVisibility",
"targetElements": [
"toggleCostDown",
"toggleCostDownChevron",
"toggleCostUp",
"toggleCostUpChevron",
"contentCost"
]
},
"bleed": true
},
{
"type": "TextBlock",
"id": "contentCost",
"text": "Some info about costs.",
"wrap": true,
"isVisible": false
}
]
}
],
"bleed": true
},
{
"type": "Container",
"id": "nonBlocking4",
"items": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "50px",
"items": [
{
"type": "Column",
"width": "70",
"items": [
{
"type": "TextBlock",
"weight": "bolder",
"text": "Open in new tab",
"wrap": true
}
]
}
]
}
]
}
],
"style": "accent",
"selectAction": {
"type": "Action.OpenUrl",
"url": "https://google.com",
"title": "Open in new tab"
},
"spacing": "medium"
}
]
},
{
"type": "TextBlock",
"weight": "bolder",
"text": "Have you found what you are looking for?",
"wrap": true
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"data": "No",
"title": "No",
"style": "destructive"
}
]
}
]
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"data": "Yes",
"title": "Yes",
"style": "positive"
}
]
}
]
}
],
"spacing": "medium",
"separator": true
}
]
}
}