How to use React Hook Form together with Fluent UI React (aka Office UI Fabric React)

Very often you need some fields in your SPFx web parts. Like text fields, dropdowns, checkboxes, etc. While you can manually perform form validation and form data collection, you can also use a helper library. React form libraries simplify a lot of things, however, they also require some time to learn the API and to adapt a library to your UI framework. 

React Hook Form (RHF) is one of such libraries. It's based solely on react hooks and gives a nicer way of managing and validating your forms, no matter which UI framework you use. In SPFx we mostly use Fluent UI React (formerly Office UI Fabric). In this post, I'm going to show how you can configure React Hook Form so that it plays nicely with Fluent UI. More...

Building Outlook addin with SPFx - save mail to OneDrive with Azure Function, MSAL.NET and MS Graph .NET

In this post, we're going to build a prototype of an outlook add-in, which saves the current email to your OneDrive. The interesting part is, that our add-in will be SPFx based, and our code, which saves emails, is hosted on Azure Functions and uses MSAL.NET for authentication and MS Graph .NET library to interact with MS Graph API.

Important! On the moment of writing (March 2021), SPFx Office add-ins support is still in preview. You can only build an add-in for outlook web. Thus I don't provide any production deployment instruction, because there is a chance, that it will change in the future.

The source code for this post is available on GitHub here. More...

Different ways of consuming organizational data (i.e. SharePoint or MS Graph API or other) from SPFx web parts

In this post, I'm going to cover different options when it comes to accessing organizational data from SPFx web parts. By organizational data I mean the most common APIs like SharePoint or MS Graph. However, it's valid for all other APIs as well. 

I'm going to cover two primary options here. The first one doesn't include any custom services or custom APIs and relies solely on SPFx OOB functionality. In the second option, we use Azure Function as a custom Web API component to access organizational data. As a bonus, we also have the third one which is a combination of the first two. More...

SharePoint Column Formatting tips: How to hide checked out documents

I had a need to hide all documents, which were checked out by users. With help of Column Formatting. When you check out documents, SharePoint sets a special field called CheckoutUser to be equal to a person, who checked out the document. The idea is to check if this field is null and hide a row in a view. 

However, the idea didn't work for some reason. The problem is, that CheckoutUser is a people field. In other words, it's a "complex" field and contains additional properties, like the user's email, id, etc. 

The trick was to use the email property of that field, to check if it's empty or not. In short:

"display": "=if([$CheckoutUser.email] != '', 'block', 'none')"  

Having below full formatting JSON:

spoiler (click to show)
{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json",
  "debugMode": true,
  "hideSelection": true,
  "hideColumnHeader": true,
  "rowFormatter": {
    "elmType": "div",
    "attributes": {
      "class": "ms-borderColor-neutralLight"
    },
    "style": {
      "box-sizing": "border-box",
      "display": "=if([$CheckoutUser.email] == '', 'block', 'none')",
      "width": "100%",
      "border-width": "1px",
      "border-style": "solid",
      "padding": "0 0 0 20px",
      "margin-bottom": "10px",
      "align-items": "stretch"
    },
    "children": [
      {
        "elmType": "div",
        "style": {
          "flex": "1 0 300px",
          "display": "flex",
          "flex-wrap": "wrap"
        },
        "children": [
          {
            "elmType": "div",
            "style": {
              "flex": "1 0 300px",
              "box-sizing": "border-box",
              "padding": "10px"
            },
            "children": [
              {
                "elmType": "button",
                "attributes": {
                  "class": "ms-fontSize-xl"
                },
                "style": {
                  "line-height": "1.5em",
                  "margin-bottom": "1em",
                  "border": "0",
                  "padding": "0px",
                  "color": "#0077ff",
                  "background-color": "transparent",
                  "cursor": "pointer"
                },
                "txtContent": "[$FileLeafRef]",
                "customRowAction": {
                  "action": "defaultClick"
                }
              },
              {
                "elmType": "div",
                "attributes": {
                  "class": "ms-fontSize-s"
                },
                "style": {
                  "line-height": "1.5em",
                  "margin-bottom": "8px"
                },
                "txtContent": "='Modified by ' + [$Editor.title] + ', ' + toLocaleString([$Modified])"
              }
            ]
          },
          {
            "elmType": "div",
            "style": {
              "flex": "0 0 170px",
              "display": "flex",
              "flex-direction": "column"
            },
            "children": [
              {
                "elmType": "button",
                "customRowAction": {
                  "action": "editProps"
                },
                "txtContent": "Edit Properties",
                "attributes": {
                  "class": "sp-row-button ms-bgColor-neutralLighter ms-fontWeight-semibold"
                },
                "style": {
                  "width": "145px",
                  "height": "32px",
                  "margin": "20px 0 10px 0"
                }
              }
            ]
          }
        ]
      }
    ]
  }
}

When applied, one checked out document was hidden:

Hope this little trick will help you build a little bit better column/view formatting experience. 

Title image credits - Solution Vectors by Vecteezy

SharePoint development state in 2020: story based on sharepoint.stackexchange analysis with Power BI

The year 2020 is over and once again it's time to perform regular analysis of data at sharepoint.stackexchange. This is the fourth edition of such an analysis. 

Tools used to collect and analyze data: 

  • Power BI with Power BI Desktop - super cool tools for data analysis. If you don't have experience with Power BI, it's worth trying to see what is possible. When I first tried it a few years ago I was sooo impressed with power yet simplicity in performing data analysis and building visualizations. It works very well for both simple and advanced scenarios. I believe that everybody will find these tools useful for any kind of data analysis. 
  • DaxStudio - an extremely useful tool to test your DAX queries. 
  • Power BI Community - Power BI has a very strong community. I found a lot of answers at their forum, I even asked some questions and community helped with valid answers. That's not a "tool" but worth mentioning. I am grateful for all the answers.
  • Stack Exchange API

The source code used to gather initial data is available at GitHub. More...

SharePoint Framework with ESLint

If you're still using tslint, I have bad news for you - it has been deprecated a long time ago. If tslint works for your old projects, then it's ok. However, for new projects use eslint. ESLint nowadays supports TypeScript with help of a plugin and parser. 

SharePoint Framework build pipeline is not as fast as the JavaScript tooling world and still uses tslint as a default linter. The good news is that we can fix it!

The source code for this post you can find on GitHub here.

More...

How to access SharePoint data from Azure Function with SPFx and PnP Core SDK

This post challenge: 

We have an SPFx solution, which performs HTTP calls to our API (protected with Azure AD authentication), hosted on Azure Functions. From Azure Function we further call SharePoint endpoints to get some data. We use PnP Core SDK to interact with SharePoint. For simplicity, the API endpoint returns all list titles in a web, where we're runnning our SPFx web part.

Why PnP Core SDK? Because it's the future of PnP Sites Core library. PnP Core SDK uses a modern .NET development stack and built from the ground up to better support different types of apps, to be cross-platform, fully tested, and maintainable. Read more on the documentation here. Also, Beta1 of the PnP Core SDK was released recently, so it's a good chance to explore it! More...

SharePoint Framework development tips: enhance your developer experience for newly created components

Sometimes, during regular SharePoint Framework development, you add new React components into your codebase. Sometimes VScode behaves very strangely and doesn't provide you with needed error highlights and import suggestions. 

The problem

For example, having below code:

import { FC } from "react";

export const MyComp: FC = () => {
  console.log(newGuid());
  return (
    <div>hello</div>
  );
};

Which problems do we have here? More...