Skip to content

Commit

Permalink
Merge branch 'release-3.0.0' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
DominicWatson committed Nov 5, 2021
2 parents 95f10c0 + 74a30a7 commit 9f1549e
Show file tree
Hide file tree
Showing 44 changed files with 1,564 additions and 74 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## v3.0.0

Experimental release giving two new features

* User configurable and sharable dashboards
* New widget to share a user configurable datatable in a dashboard

Further notes and documentation on these super cool features to come in a stable point release.

## v2.0.7

* Add interception point for rendering dashboard widgets
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ This is an extension for PresideCMS that provides APIs and a methodolgy for crea

Install with:

```box install preside-ext-admin-dashboards```
```
box install preside-ext-admin-dashboards
```

## User stories

Expand All @@ -16,6 +18,13 @@ The following user stories describe the functionality of this extension:
* 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

### 3.0.0 Experimental

Version 3.0.0 release introduces some new undocumented features that will be fully released in a point release soon. The stories are:

* As an admin user, I want to be able to create and share my own dashboards in order to create user and business specific dashboard views
* As an admin user, I want to be able to insert a datatable widget into dashboards, configuring the source object, fields shown and optional filters on the data

## 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):
Expand Down
6 changes: 5 additions & 1 deletion assets/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
node_modules
/node_modules
/css/**/*.less.css
/css/**/*.min.css
/js/**/*.min.js
/js/**/*.min.map

This file was deleted.

This file was deleted.

58 changes: 57 additions & 1 deletion assets/css/admin/specific/admindashboards/dashboards.less
Original file line number Diff line number Diff line change
@@ -1,4 +1,60 @@
.widget-dynamic-content {
position : relative;
min-height : 20px;
}
}

.dashboard-column-content {
margin-bottom : 3em;
min-height : 3em;
}

.dashboard-column-add {
text-align : center;
}

.widget-placeholder {
margin-bottom : 20px;
}

.admin-dashboard-widget.fullscreen {

.chart-canvas {
max-height : ~"calc(100vh - 85px)";
max-width : ~"calc(100vw - 46px)";
}

}

.admin-dashboard-widget-picker {

a {
padding : 10px 10px 10px 35px;
position : relative;
display : block;
margin-bottom : .5em;
border : 1px solid #eee;
border-radius : 5px;

&:hover {
text-decoration : none;
background-color : #f9f9f9;
border-color : #ddd;
}

.fa {
position : absolute;
left : 10px;
top : 14px;
}

h4 {
margin : 0;
}

p {
color : #393939;
margin : .5em 0 0;
}
}

}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

25 changes: 25 additions & 0 deletions assets/js/admin/specific/admindashboards/editing/editing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
( function( $ ){

$( ".dashboard-column-content" ).sortable( {
connectWith : ".dashboard-column-content"
, handle : ".widget-header"
, placeholder : "widget-placeholder"
, forcePlaceholderSize : true
, tolerance : "pointer"
, update : function( event, ui ) {
if ( ui.sender ) return;
var element = ui.sender || ui.item
, dashboardId = element.closest( ".admin-dashboard-container" ).data( "dashboardId" )
, column = element.closest( ".dashboard-column" ).data( "column" )
, widgets = element.closest( ".ui-sortable" ).sortable( "toArray", { attribute: "data-config-instance-id" } );

if ( widgets.length ) {
$.ajax( buildAdminLink( "admindashboards", "updateWidgetOrder" ), {
data : { dashboardId:dashboardId, column:column, widgets:widgets }
, method : "POST"
} );
}
}
} );

} )( presideJQuery );
22 changes: 22 additions & 0 deletions assets/js/admin/specific/admindashboards/sharing/sharingForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
( function( $ ){

var $viewAccess = $( "[name=view_access]" )
, $editAccess = $( "[name=edit_access]" );

if ( $viewAccess.length ) {
var $viewAccessRelated = $viewAccess.closest( ".form-group" ).siblings( ".form-group" );

$viewAccess.on( "change", function(){
$viewAccessRelated.toggle( $viewAccess.filter( ":checked" ).val() == "specific" );
} ).trigger( "change" );
}

if ( $editAccess.length ) {
var $editAccessRelated = $editAccess.closest( ".form-group" ).siblings( ".form-group" );

$editAccess.on( "change", function(){
$editAccessRelated.toggle( $editAccess.filter( ":checked" ).val() == "specific" );
} ).trigger( "change" );
}

} )( presideJQuery );
57 changes: 56 additions & 1 deletion assets/js/admin/specific/admindashboards/widgetBehaviour.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@

$.ajax( buildAdminLink( "admindashboards", "saveWidgetConfig" ), {
data : config
, complete : function() { loadContent( $widgetEl, true ); }
, method : "POST"
, complete : function() {
loadContent( $widgetEl, true );
if ( config.widget_title ) {
$( ".widget-title span", $widgetEl ).text( config.widget_title );
}
}
} );
}
}
Expand All @@ -46,6 +52,11 @@

onWidgetContentFetchSuccess = function( $widgetEl, data ){
$widgetEl.find( ".widget-dynamic-content" ).html( data );

var callback = $widgetEl.data( "ajaxCallback" );
if ( callback.length ) {
window[ callback ]();
}
};

onWidgetContentFetchError = function( $widgetEl ){
Expand Down Expand Up @@ -74,6 +85,50 @@
return false;
} );

$dashBoardContainer.on( "click", ".admin-dashboard-widget .widget-fullscreen-link", function(){
$( this ).closest( ".widget-box" ).toggleClass( "fullscreen" );

return false;
} );

$dashBoardContainer.on( "click", ".admin-dashboard-widget .widget-delete-link", function( e ){
e.preventDefault();

var $link = $( this )
, title = ""
, $widgetEl = $link.closest( ".admin-dashboard-widget" );

if ( !$link.data( "confirmationPrompt" ) ) {
title = $link.data( "title" ) || $link.attr( "title" );
title = title.charAt( 0 ).toLowerCase() + title.slice( 1 );
$link.data( "confirmationPrompt", i18n.translateResource( "cms:confirmation.prompt", { data:[ title ] } ) );
}

var $message = $( "<div class=\"form-group\"><label>" + $link.data( "confirmationPrompt" ) + "</label></div>" )
, $input = $( "<input class=\"bootbox-input form-control\" autocomplete=\"off\" type=\"text\" />" );

var confirmationDialog = presideBootbox.dialog( {
title : "Confirmation"
, message : $message
, buttons : {
cancel : {
label: i18n.translateResource( "cms:confirmation.prompt.cancel.button" )
}
, confirm : {
label: i18n.translateResource( "cms:confirmation.prompt.confirm.button" )
, callback: function() {
$widgetEl.find( ".widget-dynamic-content" ).presideLoadingSheen( true );
$.ajax( $link.attr( "href" ), {
success : function() { $widgetEl.remove(); }
, error : function() { $widgetEl.find( ".widget-dynamic-content" ).presideLoadingSheen( false ); }
, complete : function() { confirmationDialog.modal( "hide" ); }
} );
}
}
}
} );
} );

$widgets.each( function(){ loadContent( $( this ), false ); } );

} )( presideJQuery );
10 changes: 9 additions & 1 deletion box.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,13 @@
".gitignore",
".twgit_features_subject",
"jmimemagic.log"
]
],
"preside":{
"dependencies":{
"preside-ext-chart-js":{
"installVersion":"^0.2.2",
"minVersion":"0.2.2"
}
}
}
}
26 changes: 25 additions & 1 deletion config/Config.cfc
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
component {

public void function configure( required struct config ) {
var conf = arguments.config;
var conf = arguments.config;
var settings = conf.settings ?: {};

_setupEnums( settings );
_setupPermissionsAndRoles( settings );
_setupInterceptors( conf );

settings.adminConfigurationMenuItems.append( "adminDashboards" );
}

private void function _setupEnums( settings ) {
settings.enum.adminDashboardViewAccess = [ "private", "public", "specific" ];
settings.enum.adminDashboardEditAccess = [ "private", "specific" ];
}

private void function _setupPermissionsAndRoles( required struct settings ) {
settings.adminPermissions.adminDashboards = [ "navigate", "read", "add", "edit", "clone", "delete" ];

if ( IsArray( settings.adminRoles.sysadmin ?: "" ) ) {
ArrayAppend( settings.adminRoles.sysadmin, "adminDashboards.*" );
}
if ( IsArray( settings.adminRoles.contentadmin ?: "" ) ) {
ArrayAppend( settings.adminRoles.contentadmin, "adminDashboards.*" );
}
if ( IsArray( settings.adminRoles.contenteditor ?: "" ) ) {
ArrayAppend( settings.adminRoles.contenteditor, "adminDashboards.*" );
}
}

// PRIVATE HELPERS
Expand Down
8 changes: 8 additions & 0 deletions forms/admin/admindashboards/config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<form>
<tab id="default">
<fieldset id="widget_config" sortorder="1">
<field name="widget_title" control="textinput" required="true" label="admindashboards:configform.widget_title.label" />
</fieldset>
</tab>
</form>
10 changes: 10 additions & 0 deletions forms/admin/admindashboards/widget/DashboardDataFilter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<form i18nBaseUri="admin.admindashboards.widget.dashboardDataFilter:">
<tab id="default">
<fieldset id="default" sortorder="10">
<field name="applies_to" sortorder="10" control="filterWidgetObjectPicker" required="true" />
<field name="filter" sortorder="20" control="filterWidgetFilterPicker" quickadd="true" quickedit="true" filterBy="applies_to,applies_to" filterByField="filterObject,filter_object" />
<field name="grid_fields" sortorder="30" control="filterWidgetObjectFieldPicker" filterBy="applies_to" filterByField="object" sortable="true" />
</fieldset>
</tab>
</form>
10 changes: 10 additions & 0 deletions forms/preside-objects/admin_dashboard.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<form i18nBaseUri="preside-objects.admin_dashboard:">
<tab id="main">
<fieldset id="main">
<field binding="admin_dashboard.name" sortOrder="10" />
<field binding="admin_dashboard.description" sortOrder="20" />
<field binding="admin_dashboard.column_count" sortOrder="30" minValue="1" maxValue="4" />
</fieldset>
</tab>
</form>
15 changes: 15 additions & 0 deletions forms/preside-objects/admin_dashboard/sharing.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<form i18nBaseUri="preside-objects.admin_dashboard:">
<tab id="main">
<fieldset id="view_permissions">
<field binding="admin_dashboard.view_access" sortOrder="10" control="enumRadioList" />
<field binding="admin_dashboard.view_groups" sortOrder="20" />
<field binding="admin_dashboard.view_users" sortOrder="30" />
</fieldset>
<fieldset id="edit_permissions">
<field binding="admin_dashboard.edit_access" sortOrder="10" control="enumRadioList" />
<field binding="admin_dashboard.edit_groups" sortOrder="20" />
<field binding="admin_dashboard.edit_users" sortOrder="30" />
</fieldset>
</tab>
</form>
Loading

0 comments on commit 9f1549e

Please sign in to comment.