04 February 2019

Add background colour to your Planner Cards - now available as a Chrome extension!

UPDATE: Microsoft have changed the render model for Planner so unfortunately this approach doesn't work any more. This is no great surprise and my post was always disclaimed that this could happen at any time!
In the meantime, I've created another Chrome extension to make Planner render in Dark Mode which is really cool!

One thing that bugs me about Planner is the way the Labels are presented on the Task Board. They are so small and don't really catch the eye - wouldn't it be better if the Task Card itself was given the colour of the label?

Just like this:
Planner - with coloured tasks!
I think this makes a big Task Board much easier to visually scan, and I'm clearly not alone in wanting this based on this User Voice request, and this one, and this one, and this one!

Disclaimer time! Unfortunately Microsoft hasn't yet provided methods to customise Planner in an enterprise-ready, supportable manner. So this is a bit of a hack using client-initiated JavaScript injection. The approach is (by necessity) rather crude - it uses jQuery DOM examination to scan Task Cards to see if they any labels applied, and to force background colours accordingly. Cards can have multiple labels, but I chose in this implementation to simply use the first label applied - this will be the 'hottest' colour of the selected labels. I also chose to add a grey colour to unlabelled Cards and to give all cards a highlight colour down the left to match the Planner visual theming of labels.

The approach relies heavily on specific mark-up structures and CSS class names which are liable to change at any time, so be aware that this will stop working at some point when Microsoft update Planner. I used an ugly approach to run the code every second - this ensures that the colours can be updated quickly as you change Cards labels, without requiring a page reload.

So - without further ado, here's the code:

// Script to colour code Planner tasks based on labels!

function colourisePlannerTaskCards() {

    // Colourise task cards
    $(".taskBoardCard").each( function(i) {
        
        // Light theme works better for individual cards (otherwise we get contrast issues)
        $(this).addClass("theme-light");

        // Choose colour
        if ($(this).find(".categoryLabelColor-0").length > 0)
        {
            $(this).find(".container").css("background", 
                "linear-gradient(to right,#e000f1 0,#e000f1 2%,#f777ff 2%,#f777ff 100%)");
        }
        else if($(this).find(".categoryLabelColor-1").length > 0)
        {
            $(this).find(".container").css("background", 
                "linear-gradient(to right,#e04e27 0,#e04e27 2%,#f9a286 2%,#f9a286 100%)");
        }
        else if($(this).find(".categoryLabelColor-2").length > 0)
        {
            $(this).find(".container").css("background", 
                "linear-gradient(to right,#e39e27 0,#e39e27 2%,#fbd18e 2%,#fbd18e 100%)");
        }
        else if($(this).find(".categoryLabelColor-3").length > 0)
        {
            $(this).find(".container").css("background", 
                "linear-gradient(to right,#aee01e 0,#aee01e 2%,#ddf48a 2%,#ddf48a 100%)");
        }
        else if($(this).find(".categoryLabelColor-4").length > 0)
        {
            $(this).find(".container").css("background", 
                "linear-gradient(to right,#46a08e 0,#46a08e 2%,#9cd5c7 2%,#9cd5c7 100%)");
        }
        else if($(this).find(".categoryLabelColor-5").length > 0)
        {
            $(this).find(".container").css("background", 
                "linear-gradient(to right,#62cef0 0,#62cef0 2%,#a7eeff 2%,#a7eeff 100%)");
        }
        else
        {
            $(this).find(".container").css("background",
                "linear-gradient(to right,#a5a7a9 0,#a5a7a9 2%,#d5d7d9 2%,#d5d7d9 100%)");
        }
        $(this).find(".textContent").css("background", "none");
        $(this).find(".bottomBar").css("background", "none").css("border-top", "none");

    });

    setTimeout(colourisePlannerTaskCards, 1000);
}

window.addEventListener('load', function(){
    colourisePlannerTaskCards();
});

Try it out and let me know what you think in the comments! And of course upvote the User Voice suggestions that I linked to at the top of the post.

And as a final note, in creating this hack I noticed an interesting CSS class "theme-light" which is applied on the <body> element and heavily influences the CSS. If this is class changed (manually or through injected JavaScript) to "theme-dark" then suddenly we can see that Microsoft has a partially implemented native dark theme for Planner! It's ultra-high-contrast with bright green cards and it's clearly a work in development but I'm keen to see it fully implemented.

04 March 2018

Practical Nintex Governance

For those who asked for the slides, and for those who weren't fortunate enough to make it to San Diego for the amazing 2018 Nintex "xchange" conference, you can download the deck for my session "Practical Nintex Governance" from this page: http://nintex2018sessioncatalog.azurewebsites.net/SessionDetail.aspx?id=133432

Hope to see you next year!

10 May 2017

Office 365 Groups in the Real World

A massive shout out to all the organisers, sponsors, speakers and attendees for another very successful Office 365 Saturday Perth event over the weekend!

As promised, here are the slides I presented on the day, I hope they are useful. Thanks to everyone for the positive feedback, it's clear that some of the key messages regarding Groups implementation really hit home for a few people!


Cheers,
Marty

26 October 2015

SharePoint Capacity Planning with Nintex (Part 1)

Using Nintex Workflow to automatically manage thousands of Nintex Forms or other SharePoint List Items

SharePoint Capacity Planning

One of the great myths of SharePoint surrounds the List View Threshold. The common story goes like this: someone creates a list or library with the default configuration, then suddenly it starts getting some serious use, and once it hits 5,001 items, people start seeing strange behaviour. People then conclude that SharePoint can’t handle any more than 5,000 items, and negative impressions of SharePoint are the result.
Of course, SharePoint supports 30,000,000 items in a list or library!
Effective use of large lists generally requires just a little bit of capacity planning around your views and indexes. A simple approach is to use folders and subfolders to ensure that there is a maximum of 5,000 child nodes (items and subfolders) at any given level. The best way to ensure such a folder structure is maintained, is to completely automate it and remove any need for human intervention – Nintex Workflow to the rescue!

The Business Problem

A client came to me recently and asked about implementation strategies for a Nintex Form that was going to receive several hundred submissions every day! Clearly some capacity planning would be required, otherwise the list would become unmanageable very quickly.

So how can we construct a simple but clear Information Architecture? Ideally one that is reasonably generic so that it could be reused across multiple lists if required?

The Solution

The approach that I suggested was to build a subfolder structure that separates items based on a date. The date can be separated into year, month and day components, and the approach can use one, two or three levels of subfolders, depending on the expected capacity. Items would be stored at the leaf nodes in the structure.

The following table gives a sense of the capacities that would require second and/or third levels to be used, ensuring that we never exceed the 5,000 list view threshold.

Number of Subfolder Levels
Subfolder Levels
Expected items created per day
1
Year
Up to 12
2
Year and Month
Up to 150
3
Year, Month and Day
Up to 5000

So for my client and their hundreds of forms every day, we would need to use all three levels.

Here’s a diagram of how this folder structure would be constructed, and also a naming convention which aligns chronological ordering with alphanumeric ordering:

Subfolder structure for automated filing and capacity management

For each item to be filed into this structure, we need to nominate a specific date for the item. This date value could be the date of item creation, or in a Nintex Workflow context, it could be the date when the Workflow meets a milestone point such as process completion.

Managing Item URLs

Nintex Forms are managed within SharePoint as List Items rather than as Documents, and List Items have a very neat property whereby you can move them around the folder structure within a library, without changing their URLs! So we can move items into their subfolder structure at any time within their lifecycle, without impacting on end users or creating dead hyperlinks. Note that if you try this with documents, then you’ll see that the URL of each document will change to reflect its position within the folder structure, and this will lead to broken hyperlinks and frustrated end users!
This approach will work with any List Items, including Nintex Forms, but is not as neat for Documents because of URL changes

Implementation Considerations

This solution concept is very generic; it only requires the list items to be associated with a date. It is not coupled to the schema of a specific list or a Nintex Form schema, so we can implement the process within a User Defined Action (UDA). The UDA can then be quickly and reliably dragged and dropped into any Workflow across the SharePoint system, gaining huge reuse and management benefits. If you’re not familiar with UDAs, check out this Nintex Community article.

There is always a trade-off in software development, and in this case, the selection to use a UDA increase reusability but introduces some build complexity because list item context is not available in the Nintex Workflow designer.

Build

Stay tuned for part 2 where we build the UDA which automatically files list items into the described subfolder structure, building out folders as required.