protected $_settings = array(
'max_attachments' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
'contact_undelete' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
- 'dashboardCacheTimeout' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
'empoweredBy' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
'logging' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
'maxFileSize' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
parent::buildQuickForm();
$this->addRule('checksum_timeout', ts('Value should be a positive number'), 'positiveInteger');
- $this->addRule('dashboardCacheTimeout', ts('Value should be a positive number'), 'positiveInteger');
}
/**
'dashboard_id.label',
'dashboard_id.url',
'dashboard_id.fullscreen_url',
+ 'dashboard_id.cache_minutes',
'dashboard_id.permission',
'dashboard_id.permission_operator',
),
'name' => $item['dashboard_id.name'],
'label' => $item['dashboard_id.label'],
'url' => $item['dashboard_id.url'],
+ 'cache_minutes' => $item['dashboard_id.cache_minutes'],
'fullscreen_url' => $item['dashboard_id.fullscreen_url'],
);
}
'name' => $item['name'],
'title' => $item['label'],
'url' => self::parseUrl($item['url']),
+ 'cacheMinutes' => $item['cache_minutes'],
'fullscreenUrl' => self::parseUrl($item['fullscreen_url']),
);
}
'column_no' => $values['column_no'],
'name' => $dashlet['name'],
'label' => $dashlet['label'],
+ 'cache_minutes' => $dashlet['cache_minutes'],
'url' => $dashlet['url'],
'fullscreen_url' => $dashlet['fullscreen_url'],
);
'backtrace' => array('setting'),
'contact_default_language' => array('setting'),
'countryLimit' => array('setting'),
- 'dashboardCacheTimeout' => array('setting'),
'dateInputFormat' => array('setting'),
'dateformatDatetime' => array('setting'),
'dateformatFull' => array('setting'),
$section = 1;
$chart = "&charts=" . $params['charts'];
}
- if (!empty($params['row_count'])) {
+ if (!empty($params['row_count']) && CRM_Utils_Rule::positiveInteger($params['row_count'])) {
$limitResult = '&rowCount=' . $params['row_count'];
}
+ if (!empty($params['cache_minutes']) && CRM_Utils_Rule::positiveInteger($params['cache_minutes'])) {
+ $dashletParams['cache_minutes'] = $params['cache_minutes'];
+ }
$dashletParams['name'] = "report/{$instance->id}";
$dashletParams['url'] = "civicrm/report/instance/{$instance->id}?reset=1§ion={$section}{$chart}&context=dashlet" . $limitResult;
$dashletParams['fullscreen_url'] = "civicrm/report/instance/{$instance->id}?reset=1§ion={$section}{$chart}&context=dashletFullscreen" . $limitResult;
$attributes['email_subject']
);
- $form->add('text',
+ $form->add('number',
'row_count',
ts('Limit Dashboard Results'),
- array(
- 'maxlength' => 64,
- 'size' => 5,
- )
+ array('class' => 'four', 'min' => 1)
);
$form->add('textarea',
'criteria' => ts('Show Criteria'),
));
- $form->addElement('checkbox', 'addToDashboard', ts('Available for Dashboard?'), NULL,
- array('onclick' => "return showHideByValue('addToDashboard','','limit_result','table-row','radio',false);"));
+ $form->addElement('checkbox', 'addToDashboard', ts('Available for Dashboard?'));
+ $form->add('number', 'cache_minutes', ts('Cache dashlet for'), array('class' => 'four', 'min' => 1));
$form->addElement('checkbox', 'add_to_my_reports', ts('Add to My Reports?'), NULL);
$form->addElement('checkbox', 'is_reserved', ts('Reserved Report?'));
$defaults['view_mode'] = 'criteria';
}
+ if (empty($defaults['cache_minutes'])) {
+ $defaults['cache_minutes'] = '60';
+ }
+
if ($instanceID) {
// this is already retrieved via Form.php
$defaults['description'] = CRM_Utils_Array::value('description', $defaults);
CRM_Core_BAO_SchemaHandler::dropColumn('civicrm_dashboard', 'weight');
CRM_Core_DAO::executeQuery('UPDATE civicrm_dashboard SET url = REPLACE(url, "&snippet=5", ""), fullscreen_url = REPLACE(fullscreen_url, "&snippet=5", "")');
+
+ if (!CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_dashboard', 'cache_minutes')) {
+ CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_dashboard ADD COLUMN cache_minutes int unsigned NOT NULL DEFAULT 60 COMMENT "Number of minutes to cache dashlet content in browser localStorage."');
+ }
+
+ CRM_Core_DAO::executeQuery('UPDATE civicrm_dashboard SET cache_minutes = 1440 WHERE name = "blog"');
+ CRM_Core_DAO::executeQuery('UPDATE civicrm_dashboard SET cache_minutes = 7200 WHERE name IN ("activity","getting-started")');
return TRUE;
}
'description' => '',
'help_text' => '',
),
- 'dashboardCacheTimeout' => array(
- 'group_name' => 'CiviCRM Preferences',
- 'group' => 'core',
- 'name' => 'dashboardCacheTimeout',
- 'prefetch' => 1,
- 'config_only' => 1,
- 'type' => 'Integer',
- 'quick_form_type' => 'Element',
- 'html_attributes' => array(
- 'size' => 3,
- 'maxlength' => 5,
- ),
- 'html_type' => 'Text',
- 'default' => '',
- 'add' => '4.3',
- 'title' => 'Dashboard cache timeout',
- 'is_domain' => 1,
- 'is_contact' => 0,
- 'description' => '',
- 'help_text' => '',
- ),
'checksumTimeout' => array(
'group_name' => 'CiviCRM Preferences',
'group' => 'core',
$("#empty-message").show( );
}
+ // Cache dashlet info in localStorage
function saveLocalCache() {
localCache = {};
$.each(dashboard.widgets, function(id, widget) {
localCache[id] = {
content: widget.content,
- expires: widget.expires,
+ lastLoaded: widget.lastLoaded,
minimized: widget.minimized
};
});
dashboard.saveColumns();
dashboard.ready = true;
invokeCallback(opts.callbacks.ready, dashboard);
+
+ // Auto-refresh widgets when content is stale
+ window.setInterval(function() {
+ if (!document.hasFocus || document.hasFocus()) {
+ $.each(dashboard.widgets, function (i, widget) {
+ if (!widget.cacheIsFresh()) {
+ widget.reloadContent();
+ }
+ });
+ }
+ }, 5000);
}
// Callback for when any list has changed (and the user has finished resorting).
// If minimized, we'll reload later
if (widget.minimized) {
widget.contentLoaded = false;
- widget.expires = 0;
+ widget.lastLoaded = 0;
} else {
CRM.loadPage(widget.url, {target: widget.contentElement});
}
);
};
+ widget.cacheIsFresh = function() {
+ return (((widget.cacheMinutes * 60000 + widget.lastLoaded) > $.now()) && widget.content);
+ };
+
/**
* Public properties of widget.
*/
*/
function loadContent() {
- var loadFromCache = (widget.expires > $.now() && widget.content);
+ var loadFromCache = widget.cacheIsFresh();
if (loadFromCache) {
widget.contentElement.html(widget.content).trigger('crmLoad', widget);
}
if ($(event.target).is(widget.contentElement)) {
widget.content = data.content;
// Cache for one day
- widget.expires = $.now() + 86400000;
+ widget.lastLoaded = $.now();
saveLocalCache();
invokeCallback(opts.widgetCallbacks.get, widget);
}
// Public static properties of dashboard. Default settings.
$.fn.dashboard.defaults = {
columns: 2,
- emptyPlaceholderInner: ts('There are no dashlets in this column of your dashboard.'),
+ emptyPlaceholderInner: '',
throbberMarkup: '',
animationSpeed: 200,
callbacks: {},
defaults: {
minimized: false,
content: null,
- expires: 0,
+ lastLoaded: 0,
settings: false
- // url, fullscreenUrl, title, name
+ // id, url, fullscreenUrl, title, name, cacheMinutes
}
};
})(jQuery);
'description' => NULL,
'help_text' => NULL,
),
- 'dashboardCacheTimeout' => array(
- 'group_name' => 'CiviCRM Preferences',
- 'group' => 'core',
- 'name' => 'dashboardCacheTimeout',
- 'type' => 'Integer',
- 'quick_form_type' => 'Element',
- 'html_attributes' => array(
- 'size' => 3,
- 'maxlength' => 5,
- ),
- 'html_type' => 'Text',
- 'default' => NULL,
- 'add' => '4.3',
- 'title' => 'Dashboard cache timeout',
- 'is_domain' => 1,
- 'is_contact' => 0,
- 'description' => NULL,
- 'help_text' => NULL,
- ),
'checksum_timeout' => array(
'group_name' => 'CiviCRM Preferences',
'group' => 'core',
*}
<div class="crm-block crm-form-block crm-miscellaneous-form-block">
<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top"}</div>
- <table class="form-layout">
- <tr class="crm-miscellaneous-form-block-dashboardCacheTimeout">
- <td class="label">{$form.dashboardCacheTimeout.label}</td>
- <td>{$form.dashboardCacheTimeout.html}<br />
- <span class="description">{ts}The number of minutes to cache dashlet content on dashboard.{/ts}</span></td>
- </tr>
- </table>
<table class="form-layout">
<tr class="crm-miscellaneous-form-block-checksum_timeout">
<span class="description">{ts}Users with appropriate permissions can add this report to their dashboard.{/ts}</span>
</td>
</tr>
- <tr id ="limit_result" class="crm-report-instanceForm-form-block-limitUser">
+ <tr class="crm-report-instanceForm-form-block-limitUser">
<td class="report-label">{$form.row_count.label} {help id="id-dash_limit" file="CRM/Report/Form/Tabs/Settings.hlp"}</td>
- <td>{$form.row_count.html}</td>
+ <td>{$form.row_count.html} {ts}rows{/ts}</td>
+ </tr>
+ <tr class="crm-report-instanceForm-form-block-cache_minutes">
+ <td class="report-label">{$form.cache_minutes.label} {help id="cache_minutes" file="CRM/Report/Form/Tabs/Settings.hlp"}</td>
+ <td>{$form.cache_minutes.html} {ts}minutes{/ts}</td>
</tr>
</table>
</div>
field_type ="radio"
invert = 0
}
-{include file="CRM/common/showHideByFieldValue.tpl"
- trigger_field_id ="addToDashboard"
- trigger_value =""
- target_element_id ="limit_result"
- target_element_type ="table-row"
- field_type ="radio"
- invert = 0
-}
-
+{literal}
+<script type="text/javascript">
+ CRM.$(function($) {
+ function showHideDashletControls() {
+ $('.crm-report-instanceForm-form-block-limitUser, .crm-report-instanceForm-form-block-cache_minutes').toggle($(this).is(':checked'));
+ }
+ $('#addToDashboard').each(showHideDashletControls).change(showHideDashletControls);
+ });
+</script>
+{/literal}
{if $is_navigation}
<script type="text/javascript">
document.getElementById('is_navigation').checked = true;
{ts}The default number of rows per page for most reports is 50. However, this may be too many for a report which is included in the 'Home Dashboard'. You can reduce the number of rows included in each page when the report is part of the Dashboard by entering the desired row count here. Users will still be able to navigate through the full report using a pager.{/ts}
{/htxt}
+{htxt id="cache_minutes-title"}
+ {ts}Dashboard Caching{/ts}
+{/htxt}
+{htxt id="cache_minutes"}
+ {ts}How often should the contents of this dashlet be automatically refreshed? Users can manually reload by clicking the refresh button on their dashboards.{/ts}
+{/htxt}
+
{htxt id="id-is_reserved-title"}
{ts}Reserved{/ts}
{/htxt}
CRM.$(function($) {
// The set of options we can use to initialize jQuery.dashboard().
var options = {
- // Optional. Defaults to 3. You'll need to change the width of columns in CSS too.
- columns: 2,
-
- // Set this to a link to your server-side script that adds widgets to the dashboard.
- // The server will need to choose a column to add it to, and change the user's settings
- // stored server-side.
- // Required.
- emptyPlaceholderInner: '',
widgetsByColumn: {/literal}{$contactDashlets|@json_encode}{literal},
<add>3.1</add>
<drop>4.7</drop>
</field>
+ <field>
+ <name>cache_minutes</name>
+ <type>int unsigned</type>
+ <title>Cache Minutes</title>
+ <comment>Number of minutes to cache dashlet content in browser localStorage.</comment>
+ <default>60</default>
+ <required>true</required>
+ <add>4.7</add>
+ </field>
<field>
<name>created_date</name>
<type>datetime</type>
-- activity and case dashlets
INSERT INTO `civicrm_dashboard`
- ( `domain_id`, `name`, `label`, `url`, `permission`, `permission_operator`, `is_active`, `fullscreen_url`, `is_reserved`)
+ ( `domain_id`, `name`, `label`, `url`, `permission`, `permission_operator`, `is_active`, `fullscreen_url`, `is_reserved`, `cache_minutes`)
VALUES
- ( @domainID, 'blog', '{ts escape="sql"}CiviCRM News{/ts}', 'civicrm/dashlet/blog?reset=1', 'access CiviCRM', NULL, 1, 'civicrm/dashlet/blog?reset=1&context=dashletFullscreen', 1),
- ( @domainID, 'getting-started', '{ts escape="sql"}CiviCRM Resources{/ts}', 'civicrm/dashlet/getting-started?reset=1', 'access CiviCRM', NULL, 1, 'civicrm/dashlet/getting-started?reset=1&context=dashletFullscreen', 1),
+ ( @domainID, 'blog', '{ts escape="sql"}CiviCRM News{/ts}', 'civicrm/dashlet/blog?reset=1', 'access CiviCRM', NULL, 1, 'civicrm/dashlet/blog?reset=1&context=dashletFullscreen', 1, 1440),
+ ( @domainID, 'getting-started', '{ts escape="sql"}CiviCRM Resources{/ts}', 'civicrm/dashlet/getting-started?reset=1', 'access CiviCRM', NULL, 1, 'civicrm/dashlet/getting-started?reset=1&context=dashletFullscreen', 1, 7200),
- ( @domainID, 'activity', '{ts escape="sql"}Activities{/ts}', 'civicrm/dashlet/activity?reset=1', 'access CiviCRM', NULL, 1, 'civicrm/dashlet/activity?reset=1&context=dashletFullscreen', 1),
- ( @domainID, 'myCases', '{ts escape="sql"}My Cases{/ts}', 'civicrm/dashlet/myCases?reset=1', 'access my cases and activities', NULL, 1, 'civicrm/dashlet/myCases?reset=1&context=dashletFullscreen', 1),
- ( @domainID, 'allCases', '{ts escape="sql"}All Cases{/ts}', 'civicrm/dashlet/allCases?reset=1', 'access all cases and activities', NULL, 1, 'civicrm/dashlet/allCases?reset=1&context=dashletFullscreen', 1),
- ( @domainID, 'casedashboard', '{ts escape="sql"}Case Dashboard Dashlet{/ts}', 'civicrm/dashlet/casedashboard?reset=1', 'access my cases and activities,access all cases and activities', 'OR', 1, 'civicrm/dashlet/casedashboard?reset=1&context=dashletFullscreen', 1);
+ ( @domainID, 'activity', '{ts escape="sql"}Activities{/ts}', 'civicrm/dashlet/activity?reset=1', 'access CiviCRM', NULL, 1, 'civicrm/dashlet/activity?reset=1&context=dashletFullscreen', 1, 7200),
+ ( @domainID, 'myCases', '{ts escape="sql"}My Cases{/ts}', 'civicrm/dashlet/myCases?reset=1', 'access my cases and activities', NULL, 1, 'civicrm/dashlet/myCases?reset=1&context=dashletFullscreen', 1, 60),
+ ( @domainID, 'allCases', '{ts escape="sql"}All Cases{/ts}', 'civicrm/dashlet/allCases?reset=1', 'access all cases and activities', NULL, 1, 'civicrm/dashlet/allCases?reset=1&context=dashletFullscreen', 1, 60),
+ ( @domainID, 'casedashboard', '{ts escape="sql"}Case Dashboard Dashlet{/ts}', 'civicrm/dashlet/casedashboard?reset=1', 'access my cases and activities,access all cases and activities', 'OR', 1, 'civicrm/dashlet/casedashboard?reset=1&context=dashletFullscreen', 1, 60);
-- event badge
INSERT INTO civicrm_print_label (title, name, description, label_format_name, label_type_id, is_default, is_reserved, is_active, data)