Skip to content

Custom Styling

Florian Krönert edited this page Jul 7, 2021 · 4 revisions

Sometimes you might want to apply some custom styling to PowerKanban. There are styling callbacks where you can use functions for returning style objects, or for static styles you can load custom style sheets.

Custom Style Sheets

Until now, all fields that are rendered to D365-PowerKanban tiles have three CSS classes set: d365-powerkanban-field, d365-powerkanban-field-ENTITY and d365-powerkanban-field-ENTITY-FIELD. By supplying a CSS url inside your config with the following content, you could for example add a styling on large fields (such as description), which only shows up to 3 lines, while any pending content is hidden while three dots are shown for signalizing that content was clipped.

CSS:

.d365-powerkanban-field-task-description {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

PowerKanban Config:

{
    "primaryEntity": {
        "logicalName": "task",
        "swimLaneSource": "statuscode",
        "fitLanesToScreenWidth": true
    },
    "cachingEnabled": true,
    "customStyleUrl": "/WebResources/new_pkanban_style.css"
}

This looks like that:

image

Conditional Styling by JS Callback

Conditional styling based on the data displayed inside a tile can be implemented using a JS callback.

For using this, you can create a function that receives the data of every tile to be rendered and according to your business logic returns a JS object with the fluent ui style properties that you want to set. If you are doing stuff asynchronously, you can return a Promise that resolves to a JS object as well.

Example with synchronous JS object return:

window.boardViewExtender = {};

window.boardViewExtender.styleCallback = function(context) {
    // Initiate style object with default properties that you want to apply always. Leave empty for not modifying anything by default.
    const style = { borderTop: "3px solid green" };
    
    // oss_duedate is a date field which is included in the card form. All card form data can be found in context.data
    if (context.data.oss_duedate) {
        const hourDiff = Math.ceil((Date.parse(context.data.oss_duedate) - Date.parse(new Date().toISOString())) / (1000*60*60));

        if (hourDiff < 24) {
            style.borderTop = "3px solid red";
        } else if (hourDiff < 48) {
            style.borderTop = "3px solid yellow";
        }
    }
    
    return style;
};

Above example checks for a oss_duedate field on the card form. This is only an example, context.data will include all data that the current record contains for the current card form.

In the example, we check for how long the oss_duedate field lies in the future. If the due date is 48 hours or more in the future, the upper border of the tile will be green.

If the due date is less than 48, but 24 or more hours in the future, it will be yellow. If it is less than 24 hours, it will be red.

You need to register this callback for the entity where you want it to be activated inside the JSON config:

{
    "primaryEntity": {
        "logicalName": "incident",
        "swimLaneSource": "statuscode",
        "styleCallback": "boardViewExtender.styleCallback"
    },
    "customScriptUrl": "/WebResources/oss_/D365BoardView/js/exampleExternalScript.js"
}

This will look like this: image