Tag: PnP

PnP SPFx React Carousel improvements – Dot Navigation

PnP SPFx React Carousel improvements – Dot Navigation

The PnP SPFx React Control carousel is great when it comes to display various content on limited amount of space. Recently I had to implement two improvements which I now want to share with you. While another idea would be to directly implement this into the control itself.

In this second part of the carousel improvements we want to implement a dot navigation, that is showing dots for each existing element inside the carousel control. It allows us to directly navigate to each of the elements and also shows us the current position of the active element (full vs empty circle).

For simplicity reasons we omit retrieving data and mapping to content elements but simply use pre-defined react elements as in the PnP SPFx React test webpart. I also assume you already know how to install PnP SPFx React controls.

Carousel – The basics

This is the same starting point as in part 1. We can skip the state here for the moment. But again we take a look at our pre-defined elements AND the case that the carousel uses our implemented triggerNextElement function. Also remember that the “key” attribute of the elements is mandatory in combination with TriggerNextPage.

Carousel – Dot Navigation

The first thing we note here, is the creation of the dot navigation (dotNav). We create Icon elements per each existing content element from above. The name of the Icon is either “StatusCircleRing” or in case we have the element with the current index “StatusCircleInner” which is the filled circel. Furthermore we style the Icon a bit (refer to my GitHub repository for further details) and we connect the onClick event with our triggerNextElement function.

This function is exactly the same is in part 1: It only updates the current state after it ensures the index always stays in the given range (0 to element length -1).

So although we skipped the state above: It’s essential to control the current index as well as the (dis)ability to move to prev/next element. Although there is an infinite property in the pnp carousel control it seems not to work when TriggerNextPage is implemented.

The final solution might look like this:

Carousel Dot Navigation – Final result

That’s all and nothing really complex right? Nevertheless feel free to inspect the whole solution in my public GitHub repository.

Markus is a SharePoint architect and technical consultant with focus on latest technology stack in Office 365 and SharePoint Online development. He loves the new SharePoint Framework as well as some backend stuff around Azure Automation or Azure Functions and also has a passion for Microsoft Graph.
He works for Avanade and is based in Munich.
Although if partially inspired by his daily work opinions are always personal.
PnP SPFx React Carousel improvements – Autoplay

PnP SPFx React Carousel improvements – Autoplay

The PnP SPFx React Control carousel is great when it comes to display various content on limited amount of space. Recently I had to implement two improvements which I now want to share with you. While another idea would be to directly implement this into the control itself.

In this first part of the carousel improvements we want to implement an autoplay, that is automatically moving forward through all content elements of the carousel control. For simplicity reasons we omit retrieving data and mapping to content elements but simply use pre-defined react elements as in the PnP SPFx React test webpart. I also assume you already know how to install PnP SPFx React controls.

Carousel – The basics

First we have 5 pre-defined content elements. As you would usually create them from retrieved data we also copy them to the current state where we also hold the currently displayed element and its index.

We then are going to render our carousel element with its defined properties. Pay attention that we only hand in ONE element here, the current one and that the carousel logic is driven by the triggerPageEvent method. Please also note that for working properly it’s essential that the elements hold a “key” property sor sorting purposes.

Now lets handle the autoplay logic:

Carousel – The autoplay logic

In the componentDidMount we start an interval. The delay is the given interval property in seconds but we have to multiply with 1000 to have the required milisceonds in this case. The interval starts another function, the autoplayElements. This function will be called in the given intervals (all X * 1000 miliseconds) and always load the next element (currentCarouselIndex + 1).

To load the element we have the triggerNextElement function. This one was already referenced above by our carousel control, that is because it is not only used by autoplay but also when you click the next or prev button. This function only updates the current state after it ensures the index always stays in the given range (0 to element length -1).

The final solution might look something like this:

Carousel Autoplay – Final result

That’s all and nothing really complex right? Nevertheless feel free to inspect the whole solution in my public GitHub repository.

Markus is a SharePoint architect and technical consultant with focus on latest technology stack in Office 365 and SharePoint Online development. He loves the new SharePoint Framework as well as some backend stuff around Azure Automation or Azure Functions and also has a passion for Microsoft Graph.
He works for Avanade and is based in Munich.
Although if partially inspired by his daily work opinions are always personal.
Modern SharePoint authentication in Azure Automation (Runbook) with PnP PowerShell

Modern SharePoint authentication in Azure Automation (Runbook) with PnP PowerShell

Modern authentication (not only) in SharePoint Online becomes more and more relevant as more and more organizations turn off LegacyAuthentication. In fact this means the classic Credential authentication with UserName and Password does not work anymore.

The issue is, when connecting with SharePoint Designer or PowerShell with classic credentials you will receive a “Cannot contact web site  or the web site does not support SharePoint Online credentials” error.

The setting that handles this is the following:

Connect-SPOService -Url "https://<Your-Tenant>-admin.sharepoint.com"

$tenantsettings = Get-SPOTenant

$tenantsettings.LegacyAuthProtocolsEnabled

If this setting is False you cannot login with classic credentials. To change this you could run

Set-SPOTenant -LegacyAuthProtocolsEnabled $true
But for security reasons your organization might think different.

For Microsoft.Online.SharePoint.PowerShell the story ends here for now as it does not work with modern authentication especially in an unattended mode such as Azure Automation runbooks.

Luckily the more popular PowerShell module in case of SharePoint Online is PnP-PowerShell. This module provides capabilities for an unattended authentication towards SharePoint Online. In this blogpost I will show you how to handle this inside an Azure Automation runbook.

According to Microsoft’s PnP documentation for an app only permission authentication you would need the following things to get this scenario up and running. I will show you each of them and point out the “Azure Automation specifics”.

 

Create a self-signed certificate

Here you can either use a script or (much simpler) the new New-PnPAzureCertificate cmdlet. For instance run the following:

$Password = "******"
$secPassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
$cert = New-PnPAzureCertificate -Out "AzureAutomationSPOAccess.pfx" - `
 -ValidYears 10 `
 -CertificatePassword $secPassword
 -CommonName "AzureAutomationSPOAccess" `
 -Country "DE" `
 -State "Bavaria"

This would create a self-signed certificate with the needed values and, enforced by the “-out” parameter, write it to a .pfx file in the current directory.

After that simply run the following command and keep the window open. We would need the JSON result (shortened here) a in a minute.

$cert.KeyCredentials

{
    "customKeyIdentifier": "zUFQhchR6FJ0...",
    "keyId": "4d2fe8fc-0dbb-45a7-...",
    "type": "AsymmetricX509Cert",
    "usage": "Verify",
    "value":  "MIIDJDCCAgygAwIBAgIQV9qo..."
}

Register an Application

The next thing would be to register an app in your Office 365 Azure AD. Simply go to your Office 365 Admin Center and from there down below on the left side under “Admin Centers” to the “Azure Active Directory” admin center.

Here I encourage you now to use the new “App registrations (preview)” version and register an application.

RegisterApp1

Here only the “Name” is really relevant for us. Once you have that, you would need to give permissions to that app registration.

RegisterApp2_Permissions

Assuming you want to create lots of runbooks with several admin scenarios the selected permissions would be necessary. If you only have specific needs you might reduce it to a lower level. Pay attention to check “Application permissions” as we cannot handle a delegated scenario.

RegisterApp3_GrantPermissions

Anyway, any given SharePoint permission needs an administrator consent. Simply click the button but make sure you are a tenant administrator.

RegisterApp4_Granted

Then your permissions should be granted.

Next we would need to add our “KeyCredentials”. This “relates” our app registration to the recently created certificate. So switch back to our left open PowerShell window and copy the JSON output. Then switch to the app registration’s manifest and insert it there inside the [] .
At the moment of writing there was an issue with the “Preview” version of the App registration. If you receive the error “Failed to update application SPAccess. Error details: KeyValue cannot be null or empty” you can simply re-open your app registration in the classic mode, insert it there and save. Switch back to the preview mode and there are even more parameters now:

RegisterApp5_Manifest

The final thing would be to copy the App Id. Therefore switch to the “Overview” tab. Here you can copy the ID to the clipboard once we need it in another minute.

RegisterApp6_CopyID

Automation Account settings

PnP PowerShell module

I assume you already have an Automation Account configured. If not follow the documentation from Microsoft. On top you should install the PnP PowerShell module under modules. Simply install it on your local machine and then ZIP the local folder “C:\Program Files\WindowsPowerShell\Modules\SharePointPnPPowerShellOnline” and upload it under “Modules” in your Automation Account.

Upload pfx certificate

Now under “Certificates” upload your recently created certificate (the .pfx file). Therefore you would need the given name and the password.

AzureAutomation1_AddCert

Pay attention to check “Yes” for Exportable as we later need exactly this capability!

Finally I would like to store our App ID as well as the password for the certificate inside the Azure Automation Account assets. Although both values do not exactly belong together, you can store them as a simple credential pair. We later use them independently.

AzureAutomation1_AddCredentials

The Runbook – PnP PowerShell Commands

Now we have everything in place to create our first runbook with modern app only authentication. Therefore create a new PowerShell runbook and insert the following code:

$azureSPOcreds = Get-AutomationPSCredential -Name 'AzureAutomationSPO'

$siteUrl = "https://.sharepoint.com/teams/MMTeamNo1"

$aadDomain = ".onmicrosoft.com"

$Password = $azureSPOcreds.GetNetworkCredential().Password

$secPassword = $azureSPOcreds.Password

$clientID = $azureSPOcreds.UserName

$cert = Get-AutomationCertificate -Name 'AzureAutomationSPOAccess'

$pfxCert = $cert.Export(3 ,$Password) # 3=Pfx

$certPath = Join-Path "C:\Users" "SPSiteModification.pfx"

Set-Content -Value $pfxCert -Path $certPath -Force -Encoding Byte 
    

if (Test-Path $certPath)

{

    $pnpCert = Get-PnPAzureCertificate -CertificatePassword $secPassword `
					-CertificatePath $certPath

    Write-Output "Connecting to $siteUrl"

    Connect-PnPOnline   -CertificatePath $certPath `

                        -CertificatePassword $secPassword `

                        -Tenant $aadDomain `

                        -ClientId $clientID `

                        -Url $siteUrl 

    $web = Get-PnPWeb

    Write-Output $web.Title

}

else

{

    Write-Output "No Cert"

}

For simplicity reasons I put some other values in as hardcoded which you would also put to different Automation variables (or ONE as a config XML).

The first interesting thing is getting the $azureSPOcreds. After retrieval we extract the UserName on the one hand, that is our AppID. On the other hand with two commands we extract the password, once simply as a SecureString by retrieveng the Password attribute and give it to the $secPassword variable. Then with the help of the GetNetworkCredential() method we also extract the password in PlainText (!!!) and give it to the $Password variable. We need it that way for the certificate.

But here you see a disadvantage of the Azure Automation assets. Once you have some Admin credentials in there AND access to it, you also have the clear text password! 😉 

The next trick we use is to export the certificate to the “local filesystem of the Automation account” which is only valid during runtime of a runbook execution.

This is because the Connect-PnpOnline command we use next expects it that way and cannot handle a X509Certificate2 object directly (that is what we get with the Get-AutomationCertificate cmdlet).

Once we have that exported we simply ‘Test-Path’ our export and if everything is fine we can Connect-PnPOnline to our SharePoint and execute a simple demo task to get the current web’s title.

Extend PnP SharePoint Framework React ListView Control with a context menu

Extend PnP SharePoint Framework React ListView Control with a context menu

The ListView component from the PnP SharePoint Framework React Controls is really simple in use. And it’s furthermore easily extensible. In this little post I want to simply show how you can add a context menu to the list item like it’s available in the default modern experience of lists and like the “edit control block” in the classic experience.

Assume we have a simple list view webpart like the following

01_EmployeeListView_rel1

achieved by the following code

We now need to create another component which represents our context menu. Therefore we will use a combination of an IconButton and a ContextualMenu from the Office UI Fabric components.

The code for this additional component looks like this:

One of the tricks is here to give an empty iconName for the menuIconProps. This is because once you attach a menuProps Attribute to any Kind of Office UI fabric button a ChevronDown selector on the right side of the button will occur by default. With the menuIconProps Attribute you can adjust this, that is when specifying an empty Name you can remove it. This is what we want because we only want to have our “MoreVertical” icon which are the three dots in a vertical order.
To place this a bit more centric, we have small CSS manipulation as well:

Finally we need to put the pieces together. Therefore we will insert another Viewfield in the webpart code at the position of our choice, for instance after the “Lastname”:

{
        name: "",
        sorting: false,
        maxWidth: 40,
        render: (rowitem: IListitem) => {
	 const element:React.ReactElement<IECBProps> =React.createElement(
            ECB, {
	      item:rowitem
            }
          );
          return element;
        }      
},

We use the render method of IViewField. Inside we create our ECB component and as a property we handover the rowitem which is clicked. We could also handover functions that shall be executed inside the context menu component but be able to be bound to the parent component, that is the webpart which contains the ListView.

The result will look like the following:

02_EmployeeListView_ecb

And in action it shows which function and item was clicked:03_EmployeeListView_ecb_clicked