Open productboard-ac opened 4 years ago
ProductBoard auto-generated feature.
type
property or a separate fully-qualified a name
property?
Component
only, use the name
property as a fully-qualify the identifier of a component. See examples below for more.name
property will be a string
that may optionally start with a domain and/or path qualifier. See examples below for more.Component
object or in a specific attribute called properties
name
, view
preference, potentially version
, and other pieces of metadata that are required to make the Component model work. To remove risk of conflict we will put all domain-specific properties for a given component into a properties
attribute, which will get passed along to the component to be used for binding. See examples below for more.name
, similar to many REST APIs. E.g., "name": "graph.microsoft.com/file/v2"
User
and another component to handle multiple Users
?
Some inspiration for the component name-as-path can be found from the current "Template Service Registry" which has existed for a little while now. It allows organizations to eventually "own" and have editorial control over components within their domain.
See the current template registry as an example: https://github.com/microsoft/adaptivecards-templates/tree/master/templates
{
"type": "Component",
"name": "schema.org/Thing",
"properties": {
"name": "...",
"description": "..."
}
}
{
"type": "Component",
"name": "schema.org/Book",
"properties": {
"author": "...",
"title": "..."
}
}
{
"type": "Component",
"name": "schema.org/Book/v2",
"properties": {
"author": "...",
"title": "...",
"somev2Property": "..."
}
}
{
"type": "Component",
"name": "schema.org/LocalBusiness",
"properties": {
"name": "...",
"description": "...",
"hoursOfOperation": "..."
}
}
{
"type": "Component",
"name": "schema.org/boardingPass",
"view": [ "hero", "compact" ],
"properties": {
"name": "..."
}
}
File chiclet
Component based on the Graph file/driveItem
{
"type": "Component",
"name": "graph.microsoft.com/file",
"properties": {
"createdDateTime": "2015-08-17T21:12:15Z",
"eTag": "\"{BE9DD131-A7DC-4E38-94CE-9030F0F69DBA},1\"",
"id": "01IYGFKCBR2GO35XFHHBHJJTUQGDYPNHN2",
"lastModifiedDateTime": "2015-08-17T21:12:15Z",
"name": "3604904",
"webUrl": "https://microsoft-my.sharepoint-df.com/personal/mahiding_microsoft_com/Documents/3604904",
"cTag": "\"c:{BE9DD131-A7DC-4E38-94CE-9030F0F69DBA},0\"",
"size": 278612999,
"createdBy": {
"user": {
"email": "Matt.Hidinger@microsoft.com",
"id": "f6bbdfd5-6895-46c3-a549-0bafea69e07e",
"displayName": "Matt Hidinger"
}
},
"lastModifiedBy": {
"user": {
"email": "Matt.Hidinger@microsoft.com",
"id": "f6bbdfd5-6895-46c3-a549-0bafea69e07e",
"displayName": "Matt Hidinger"
}
},
"parentReference": {
"driveId": "b!-qa0V7NugEm0-AQZERKrUXb5GGSEcANIj95SK8RTLh-1QdYdMdUNTal44w5iVLEb",
"driveType": "business",
"id": "01IYGFKCF6Y2GOVW7725BZO354PWSELRRZ",
"path": "/drive/root:"
},
"fileSystemInfo": {
"createdDateTime": "2015-08-17T21:12:15Z",
"lastModifiedDateTime": "2015-08-17T21:12:15Z"
},
"folder": {
"childCount": 3
}
}
}
Single user
Component based on the Graph User
{
"type": "Component",
"name": "graph.microsoft.com/user",
"properties": {
"displayName": "Megan Bowen",
"givenName": "Megan",
"jobTitle": "Auditor",
"mail": "MeganB@M365x214355.onmicrosoft.com",
"mobilePhone": null,
"officeLocation": "12/1110",
"preferredLanguage": "en-US",
"surname": "Bowen",
"userPrincipalName": "MeganB@M365x214355.onmicrosoft.com",
"id": "48d31887-5fad-4d73-a9f5-3c356e68a038"
}
}
Multiple users
{
"type": "Component",
"name": "graph.microsoft.com/users",
"view": "compact",
"properties": {
"users": [
{
"userPrincipalName": "MeganB@M365x214355.onmicrosoft.com",
},
{
"userPrincipalName": "User2@M365x214355.onmicrosoft.com",
}
]
}
}
Full profile component that needs data from multiple endpoints
{
"type": "Component",
"name": "graph.microsoft.com/fullProfile",
"properties": {
"user": {
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
"businessPhones": [
"+1 412 555 0109"
],
"displayName": "Megan Bowen",
"givenName": "Megan",
"jobTitle": "Auditor",
"mail": "MeganB@M365x214355.onmicrosoft.com",
"mobilePhone": null,
"officeLocation": "12/1110",
"preferredLanguage": "en-US",
"surname": "Bowen",
"userPrincipalName": "MeganB@M365x214355.onmicrosoft.com",
"id": "48d31887-5fad-4d73-a9f5-3c356e68a038"
},
"reports": {
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#directoryObjects",
"value": [
{
"@odata.type": "#microsoft.graph.user",
"id": "ec63c778-24e1-4240-bea3-d12a167d5232",
"businessPhones": [
"+20 255501070"
],
"displayName": "Pradeep Gupta",
"givenName": "Pradeep",
"jobTitle": "Accountant II",
"mail": "PradeepG@M365x214355.onmicrosoft.com",
"mobilePhone": null,
"officeLocation": "98/2202",
"preferredLanguage": "en-US",
"surname": "Gupta",
"userPrincipalName": "PradeepG@M365x214355.onmicrosoft.com"
}
]
}
}
}
Test
Is here the integration of Loop Components (Teams Loop Components) to Adaptive Cards meant?
Hello, We are trying to leverage the Multiple Users component outlined above. When posting the adaptive card to Teams group chat, none of the profiles are shown (see screenshot below). When adjusting the adaptive Card JSON to list one person, the profile is rendered correctly in Teams. Are there any limitations on using the multi-Users (persona Set) in Teams adaptive card version 1.4? I am using the JSON below. If I remove the ID or display name, the adaptive card never gets posted to Teams. Power Automates generates an error regarding inability to parse JSON.
{
"type": "Component",
"name": "graph.microsoft.com/users",
"view": "compact",
"properties": {
"users": [
{
"id": "user1AADObjectID",
"userPrincipalName": "user1UPN",
"DisplayName": "user1DisplayName"
},
{
"id": "user2AADObjectID",
"userPrincipalName": "user2UPN",
"DisplayName": "user2DisplayName"
}
]
}
}
Adaptive Components
Enabling the creation of purely declarative high-level components powered by templating and native Adaptive Card elements. You can think of them like “molecules”, built by arranging Adaptive Card elements (“atoms”) into unique and helpful ways.
Status: Draft Approved
9/25/2020: Draft approved per the changes made in the comment below from 9/25. Root spec to be updated shortly. 9/9/2020: Initial draft proposed.
Try it yourself
Interested in trying it out? You're in luck! We have an early prototype to play with, note that it is pre-alpha and will be buggy!
Objectives
Open issues
body
to aview
easierschema.org/thing
component, it can add/remove/change views, but should it be able to change the schema? I'm leaning towards no, but should we make that a policy or just strong guidance?Examples
Example: "File Chicklet" Component
The file chicklet is a way to represent basic file metadata somewhere inside the card.
Component Usage:
Component Definition:
Component.File.json
Example: "Thing" Component
"Things" are all over the web today, and represent the basic metadata for objects. They are broadly categorized by these pieces of metadata:
Component Usage:
Component Definition:
Component.Thing.json
Example: User component
Example: Composition
Components can be used alongside any native Adaptive Card elements, or other Components.
Requirements
"$when": "${$host.width > 300}"
)Renderer behavior and component registries
The renderer will loop through all elements in the body as normal. When it encounters a type of
Component
then a component lookup occurs.Example remote registry lookup
HTTP GET https://api.adaptivecards.io/components/<COMPONENT-NAME>.json
(NOTE: Hosts can configure this via host config)
Based on the
schema.org/thing
component above, the renderer would request the component at the following URL:HTTP GET https://api.adaptivecards.io/components/schema.org/thing.json
Multiple "views" for Components
In many cases, a single layout many not suffice for a given component. For example, if a Component contains an image, the desired UI may place the image above the other fields, or it may want a small thumbnail of the image to the left of the other content, or perhaps as the background image behind the content.
This becomes increasingly important in a world where a single payload roams between hosts with vastly different UI constraints or characteristics.
Imagine if the
schema.org/thing
component wanted to provide 3 different "layouts" or "views":The ultimate UI that gets rendered would be determined by multiple factors:
Card Author explicitly selecting a particular view
If we allow authors to pick a particular view for a given component, we need a standardized set of properties on the component definitions.
"Component"
Component
string
[DOMAIN]/[COMPONENT-NAME]
, e.g.,graph.microsoft.com/file
string[]
object
If we apply this to our
schema.org/thing
, it becomes:In this example, the card author is asking for a view in a specific order, where the first match will be used.
Why would a match not be found?
Great question! The reason for the array is because we will allow hosts to modify the remote component registries, which would let them define a custom version of a well-known component, or replacing the entire registry and all of its Components. If they do choose to modify a well-known component (like
schema.org/thing
), they may want to modify, add, or even remove support for particular views.Example: "Thing" component with multiple views
Let's apply this concept to our
schema.org/thing
component.HTTP GET
https://api.adaptivecards.io/components/schema.org/thing.json
Supporting multiple renderer versions in the same component
As we release new versions of Adaptive Card schema, it's important that components are compatible with multiple versions.
For example, maybe the "Thing" template wants to use new
1.6
elements if the client supports them, but still has a great experience for1.3
, or even1.0
.Thankfully, we get this support for free, thanks to the existing fallback model in 1.2! 👍
Designer Integration
We should make working with components and component registries a first-class experience.
Components can declare their expected schema and sample data
Components have a first-class way to describe the schema of the data/properties it expects, which enables the Designer to generate the Property Sheet automatically. This is also useful for tooling more advanced component resolution, and even validation.
Thing example
The
schema.org/thing
component expects data as follows:Thing declaration:
Appendix
Other component-lookup approaches
There are other ways we can explore Component-resolution.
For example, schema.org has a clear hierachy for their objects. "Thing" is the base type of everything, but maybe instead of a
Thing
I have a LocalBusiness, which includes all the properties ofThing
and some addition ones.If a
Restaurant
component doesn't exist, could we make a best-effort to find a base type the hierarchy until a match is found, such asLocalBusiness
: