FORGEBOX Enterprise 🚀 - Take your ColdFusion (CFML) Development to Modern Times! Learn More...

PresideCMS Extension: Admin dashboards

v2.0.2 Public

PresideCMS Extension: Admin Dashboards

This is an extension for PresideCMS that provides APIs and a methodolgy for creating user customizable dashboard interfaces in Preside admin.

Installation

Install with:

box install preside-ext-admin-dashboards

User stories

The following user stories describe the functionality of this extension:

  • As an admin user, I want to be able to view a dashboard with multiple widgets so that I can get an overview of a particular data scenario(s)
  • As an admin administrator, I want to be able to limit access to particular dashboard widgets so that I can protect sensitive data and functionality
  • As an admin user, I want to be able to configure widgets and have my configuration persisted so that I can customize my view of a dashboard

Rendering a dashboard

Admin dashboards are made up of "widgets" that a user can configure to show stats, summaries, etc. To render a dashboard, you can use the renderAdminDashboard() helper, providing an arbitrary but unique dashboard ID that identifies a unique dashboard, an array of widget IDs and an optional column count (default 2, valid options are 1, 2, 3 or 4):

#renderAdminDashboard( 
      dashboardId = "mainAdminDashboard"
    , widgets     = [ "latestNews", "topStories", "yourTasks" ]
    , columnCount = 3
)#

Passing instance specific data

You may have a case where:

  1. You have multiple instances of the same dashboard, but with different instance data
  2. You have multiple instances of the same widget within your dashboard, but with different hard coded config values

For this you can use the contextData arg to renderAdminDashboard and/or individual widgets:

// example 1
#renderAdminDashboard( 
      dashboardId = "mainAdminDashboard"
    , widgets     = [ "latestNews", "topStories", "yourTasks" ]
    , columnCount = 3
    , contextData = { recordId=prc.recordId }
)#

// example 2
#renderAdminDashboard( 
      dashboardId = "mainAdminDashboard"
    , columnCount = 3
    , widgets     = [ 
    	{ id="stats", contextData={ object="event" }, ajax=false, configInstanceId="event" }, 
    	{ id="stats", contextData={ object="news"  }, ajax=false, configInstanceId="news" }
      ]
)#

Notice how, in example 2, each widget is a struct. Widgets can either be passed as a simple string to represent the widget ID, or as a struct with the following keys:

  • id: The widget ID
  • contextData: Widget specific struct of data that will be passed to the widget render
  • ajax: Whether or not to use ajax to render the widget (default true)
  • configInstanceId: String to identify, along with the dashboard ID and user ID, a unique set of configuration options for the widget

Creating dashboard widgets

An admin dashboard widget is created in three parts; a handler for rendering a widget and running any custom permissioning logic, an i18n properties file for labels and icons, and a preside form for providing any user editable config for the widget.

For example, if you had a widget called latestNews, you would have the following files:

/i18n/admin/admindashboards/widget/latestNews.properties
/forms/admin/admindashboards/widget/latestNews.xml
/handlers/admin/admindashboards/widget/LatestNews.cfc

And they might look like this:

// /i18n/admin/admindashboards/widget/latestNews.properties
title=Latest news
description=See below for latest news articles for you to read.
iconClass=fa-newspaper orange

field.category.title=Category
// /forms/admin/admindashboards/widget/latestNews.xml
<?xml version="1.0" encoding="UTF-8"?>
<form i18nBaseUri="admin.admindashboards.widget.latestNews:">
	<tab id="default">
		<fieldset id="default" sortorder="10">
			<field name="category" control="objectpicker" object="category" />
		</fieldset>
	</tab>
</form>
// /handlers/admin/admindashboards/widget/LatestNews.cfc
component {

	// You MUST implement a render() method with which to render
	// the content
	private string function render( event, rc, prc, args={} ) {
		args.latestNews = getModel( "newsService" ).getLatestNews( 
			  category = args.config.category ?: "" // args.config is the user configured config from the config form
			, featured = IsTrue( args.contextData.featured ?: "" ) // args.contextData is any data passed in renderAdminDashboard() call
		);
		return renderView( view="/admin/admindashboards/widgets/latestNews", args=args );
	}

	// An OPTIONAL permissions checking handler that returns true or false
	private boolean function hasPermission( event, rc, prc, args={} ) {
		return true;
	}

	// An OPTIONAL handler to render additional top right 'menu items' in the widget
	private string function additionalMenu( event, rc, prc, args={} ) {
		var addLink = event.buildAdminLink( objectName="news_item", operation="addRecord" );
		return '<a href="#addLink#"><i class="fa fa-fw fa-plus grey"></i></a>&nbsp; ';
	}
}

What's next

We've created this extension with what we feel is the bare minimum functionality for a first release. Obvious features that are lacking:

  • Ability for a dashboard to have optional widgets that users can add to a dashboard if they want
  • Ability for a dashboard user to drag items around and configure them the way they like
  • Ability for a dashboard user to save a dashboard configuration and share it with other users

If you're keen on helping out with ideas or code, do get in touch!

Changelog

v2.0.2

  • Fix #1: additional menu would not show unless widget had config

v2.0.1

  • Ensure config is correctly passed to render content

v2.0.0

  • Add documentation directly to the readme

v1.5.0

  • Add ajax option to widgets so that they can be rendered inline if needed (useful for things that call datatables, etc)
  • Add ability to add additional menu rendering for widgets
  • Allow developers to specify specific 'config instance' ids to define how configuration should be shared across multiple instances of a dashboard
  • Ensure that instances of widget configuration are unique to the context data passed to the dashboard/widget. Means you can have multiple instances of same widget on one dashboard but with different context input data and unique additional configuration
  • Provide a mechanism for passing contextual data to a dashboard / widget within a dashboard

v1.0.1

  • Add ability to set number of columns in a dashboard

v1.0.0

  • Initial working commit

Here are all the versions for this package. Please note that you can leverage CommandBox package versioning to install any package you like. Please refer to our managing package version guide for more information.

Version Created Last Update Published By Stable Actions
Current
2.0.2 May 22 2019 05:28 AM May 22 2019 05:28 AM
Version History
2.0.1 Feb 27 2019 09:12 AM Feb 27 2019 09:12 AM
2.0.0 Feb 25 2019 11:17 AM Feb 25 2019 11:17 AM
1.0.1 Jun 27 2018 12:05 AM Jun 27 2018 12:05 AM
1.0.0 Jun 26 2018 10:14 AM Jun 26 2018 10:14 AM

 

No collaborators yet.
  • Jun 26 2018 10:14 AM
  • May 22 2019 05:28 AM
  • 426
  • 650
  • 7382