SharePoint Adaptive Cards Extension SPFx To Extend Viva Connection

Introduction

Many people are talking about modern employee experience using Microsoft Viva. So, Viva connection is a single endpoint to a modern employee experience where developers can build and develop integrated apps to help employees.

With time, SharePoint SPFx is getting matured platform to make a modern application that is supported to the web as well as mobile applications. With SPFx Development, there are many ways to extend application through Header, Footer, Library component, and specific components which can optimize mobile experience as well.

Once again, SPFx 1.13.0 public preview comes with new component types which have the ability to extend and build mobile experiences for Microsoft Viva Connections.

Learning Objectives

  1. Features and Capabilities of Adaptive Cards Extensions
  2. Prerequisites for SPFx ACEs Project
  3. Create SPFx using Adaptive Card Extension
  4. Code structure and understanding
  5. Explore Card View component
  6. Explore Quick View component
  7. Configure Property Panel Controls
  8. Run project in Workbench and display component-wise output
  9. Conclusion

Let's Begin,

Features and Capabilities of Adaptive Cards Extensions

ACEs are the extensibility model which will be used for the upcoming Viva Connections feature.

The preview/beta version will enable you to create ACEs and test them in the hosted workbench. It provides a flexible platform where developers can build rich, native extensions to viva connections’ Dashboards and SharePoint Pages.

ACEs are built on Microsoft Adaptive Card Framework to provide modern and rich UI with the power of declarative JSON schema.SPFx ACEs components provide you the platform, where you need to focus on business logic and SPFx, will handle UI which will work across all platforms.

Types of ACEs templates

  • Basic Card Template
  • Image Card Template
  • Primary Text Template

Prerequisites for SPFx ACEs Project

Note: SPFx 1.13.0 version is in public beta for testing (at a time when writing this blog). So, it is not recommended to use in product development.

SPFx 1.13.0 developer preview has the following requirements

  1. Node.js v12 LTS
  2. Gulp v4
  3. Yeoman v3
  4. Set up SPFx Development Environment

Install latest beta release using below code,

npm install @microsoft/generator-sharepoint@next --global

Create SPFx using Adaptive Card Extension using Primary Text Template

Open node command prompt

Reach to your desire location where you want to create a solution

Run below command

yo @microsoft/sharepoint

When prompted, enter the below values to each parameter.

SharePoint Adaptive Cards Extension SPFx to extend Viva Connection

Once all required packages are downloaded then you will get a message as below.

SharePoint Adaptive Cards Extension SPFx to extend Viva Connection

Now open a solution in visual studio code or editor that you want to use.

The below command is used to open the solution in VSCode.

code .

Code structure and understanding

SharePoint Adaptive Cards Extension SPFx to extend Viva Connection

Locate and open file "\src\adaptiveCardExtensions\primaryTextFirstSample\PrimaryTextFirstSampleAdaptiveCardExtension.ts"

export default class <className>
    extends BaseAdaptiveCardExtension<IProps,IState> {
  // ...
}
// Base class for All ACEs "BaseAdaptiveCardExtension"

BaseAdaptiveCardExtenion has two parameters.

  1. TProperties- Set of properties of the component. Similar to SharePoint SPFx Webpart
  2. TStates- Set of renderable data. It is optional and uses for Conditional rendering based on the content.

Locate and open file "\src\adaptiveCardExtensions\primaryTextFirstSample\PrimaryTextFirstSampleAdaptiveCardExtension.ts" and find render().

protected renderCard(): string | undefined {
  return CARD_VIEW_REGISTRY_ID;
}

The render() method returns a string identifier that is registered as a view and it is invoking during the initial render method of cardview.

Now, the question arises that what is the view registration process?

If we want to implement a custom view in ACEs then the view must be registered for the respective Viewnevigator.

this.cardNavigator.register(CARD_VIEW_REGISTRY_ID, () => new CardView());
this.quickViewNavigator.register(QUICK_VIEW_REGISTRY_ID, () => new QuickView());

cardNavigator and quickViewNavigator, both are part of the BaseAdaptiveCardExtension class.

cardviewnaviagtor is used to register cardview component and quickViwNavigator is used to register the QuickView component.

You can register view with a navigator in the class constructor or onInit().

public onInit(): Promise < void > {
    this.state = {
        description: this.properties.description
    };
    this.cardNavigator.register(CARD_VIEW_REGISTRY_ID, () => new CardView()); // Card view component
    this.quickViewNavigator.register(QUICK_VIEW_REGISTRY_ID, () => new QuickView()); // quick view compoenent
    return Promise.resolve();
}

Explore Card View component

open "src\adaptiveCardExtensions\primaryTextFirstSample\cardView\CardView.ts". This file is responsible to handle card view components.

The card view component extends from three base classes depend on selection while creating a project and solution.

  • BasePrimaryTextCardView is responsible for Primary Text Template
  • BaseBasicCardView is responsible for Basic Card Template
  • BaseImageCardView is responsible for Image Card Template

Now, we are taking the example of BasePrimaryTextCardView. Will explore the other two in the next article.

export class CardView extends BasePrimaryTextCardView < IPrimaryTextFirstSampleAdaptiveCardExtensionProps, IPrimaryTextFirstSampleAdaptiveCardExtensionState > {
    public get cardButtons(): [ICardButton, ICardButton] | undefined {
        // Add Json to display buttons in card view.
    }
}

cardButtons() method is used to display buttons on the Primary text card view.

card button supports three types of buttons.

  • QuickView
  • ExternalLink
  • Submit

catrdButons() method returns JSON text which includes properties like Title,action,type, view,target.

return [{
    title: strings.QuickViewButton,
    action: {
        type: 'QuickView',
        parameters: {
            view: QUICK_VIEW_REGISTRY_ID // this is initialize in AdaptiveCardextension.ts file
        }
    }
}, {
    title: 'Bing',
    action: {
        type: 'ExternalLink',
        parameters: {
            target: 'https://www.bing.com'
        }
    }
}];
public get onCardSelection(): IQuickViewCardAction | IExternalLinkCardAction | undefined {
    // Responsible to handle on selection event.
    // This code run when user click on card view
}

onCardSelection() method handles click event on cardview component.

return {
    type: 'ExternalLink', // either type can be Externalink or QuickView
    parameters: {
        target: 'https://www.google.com' // if Type ExternalLink
        // View : ViewID // if Type QuickView
    }
};

Explore Quick View component

Open file "\src\adaptiveCardExtensions\primaryTextFirstSample\quickView\QuickView.ts" handle Quick View Component.

QuickView component extends from BaseAdaptiveCardView,

export class QuickView extends BaseAdaptiveCardView<
  IPrimaryTextFirstSampleAdaptiveCardExtensionProps,
  IPrimaryTextFirstSampleAdaptiveCardExtensionState,
  IQuickViewData
>
{ 
 // Add code
}

IQuickViewData will be any JSON object which we want to render in the Quick View Component.

Data() method is used to get data from the IQuickViewData and return JSON data which will be used in the JSON template to render values.

public get data(): IQuickViewData {
    return {
        subTitle: strings.SubTitle,
        title: strings.Title,
        description: this.properties.description
    };
}

template() is get adaptive card schema.

public get template(): ISPFxAdaptiveCard {
    return require('./template/QuickViewTemplate.json');
}

template() return json from the json file.

Open "\src\adaptiveCardExtensions\primaryTextFirstSample\quickView\template\QuickViewTemplate.json" file which includes JSON schema which will be render in quick view component along with IQuickViewData.

{
  "schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.2",
  "body": [
    {
      "type": "TextBlock",
      "weight": "Bolder",
      "text": "${title}" // Value replace from IQuickViewData
    },
    {
      "type": "ColumnSet",
      "columns": [
        {
          "type": "Column",
          "items": [
            {
              "type": "TextBlock",
              "weight": "Bolder",
              "text": "${subTitle}", Value replace from IQuickViewData
              "wrap": true
            }
          ]
        }
      ]
    },
    {
      "type": "TextBlock",
      "text": "${description}", Value replace from IQuickViewData
      "wrap": true
    }
  ]
}

The developer can create complex JSON using https://adaptivecards.io/samples/.

Full Component looks like as below,

import { ISPFxAdaptiveCard, BaseAdaptiveCardView } from '@microsoft/sp-adaptive-card-extension-base';
import * as strings from 'PrimaryTextFirstSampleAdaptiveCardExtensionStrings';
import { IPrimaryTextFirstSampleAdaptiveCardExtensionProps, IPrimaryTextFirstSampleAdaptiveCardExtensionState } from '../PrimaryTextFirstSampleAdaptiveCardExtension';
export interface IQuickViewData {
  subTitle: string;
  title: string;
  description: string;
}
export class QuickView extends BaseAdaptiveCardView<
  IPrimaryTextFirstSampleAdaptiveCardExtensionProps,
  IPrimaryTextFirstSampleAdaptiveCardExtensionState,
  IQuickViewData
> {
  public get data(): IQuickViewData {
    return {
      subTitle: strings.SubTitle,
      title: strings.Title,
      description: this.properties.description
    };
  }
  public get template(): ISPFxAdaptiveCard {
    return require('./template/QuickViewTemplate.json');
  }
}

Configure Property Panel Controls

property pane controls are used to provide configurations settings for custom components same as webparts.

Open "\src\adaptiveCardExtensions\primaryTextFirstSample\PrimaryTextFirstSamplePropertyPane.ts". This file handles property controls.

getPropertyPaneConfiguration() method used to render controls in the property panel to get input from the user to run the components.

public getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
        pages: [{
            header: {
                description: strings.PropertyPaneDescription
            },
            groups: [{
                groupName: strings.BasicGroupName,
                groupFields: [
                    PropertyPaneTextField('title', {
                        label: strings.TitleFieldLabel
                    }),
                    PropertyPaneTextField('iconProperty', {
                        label: strings.IconPropertyFieldLabel
                    }),
                    PropertyPaneTextField('description', {
                        label: strings.DescriptionFieldLabel,
                        multiline: true
                    })
                ]
            }]
        }]
    };
}

This Propertyconfigurations are used by "\src\adaptiveCardExtensions\primaryTextFirstSample\PrimaryTextFirstSampleAdaptiveCardExtension.ts" file inside getPropertyPaneConfiguration() method.

protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return this._deferredPropertyPane!.getPropertyPaneConfiguration();
}

Run project in Workbench and display component-wise output

Run below command to execute code in workbench.

gulp serve -l --nobrowser

Open workbench URL in SharePoint.

https://<tenantName>.sharepoint.com/_layouts/15/workbench.aspx

Let's Understand Component Wise Output.

SharePoint Adaptive Cards Extension SPFx to extend Viva Connection

Follow the below GIF to configure the full Adaptive card component and check the output.

SharePoint Adaptive Cards Extension SPFx to extend Viva Connection

Conclusion

After this article, you will be familiar with Adaptive cards extension and its different components. You will have a basic idea of the ACEs solution structure and how can we implement it and test it.

I hope, you enjoyed this article.