Skip to content

Commit bc4b032

Browse files
committed
1.33.0 release
1 parent db8b70a commit bc4b032

18 files changed

+311
-72
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# 1.33.0 (06/23/2016)
2+
3+
## Features
4+
5+
- JavaScript API for hiding/showing Widgets: Added API for changing the visibility of Widgets at runtime. Changes to Widget visibility is remembered across sessions by the user's browser.
6+
17
# 1.32.0 (06/09/2016)
28

39
## Features

cyclotron-site/app/partials/dashboard.jade

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ div.dashboard
1212
i.fa.fa-chevron-right(ng-click='moveForward()', ng-class='{ disabled: !canMoveForward() }', title='Go to the next page')
1313

1414
.dashboard-pages
15-
div(dashboard-page, dashboard='dashboard', page='page', page-number='{{ currentPageIndex }}',
15+
div(dashboard-page, dashboard='dashboard',
16+
page='page', page-number='{{ currentPageIndex }}', page-overrides='dashboardOverrides.pages[currentPageIndex]',
1617
ng-repeat='page in currentPage')
1718

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
h3 JavaScript API
2+
3+
p.
4+
Cyclotron provides a JavaScript API that Dashboards can leverage. They make it easier to extend Cyclotron with custom functionality and add additional interactivity to a Dashboard. Basically, it exposes various actions in the Dashboard (e.g. execute a Data Source, show/hide a Widget), or to provide information about the Dashboard.
5+
6+
p
7+
| In addition to the Cyclotron API, there are a handful of 3rd party JavaScript libraries which are bundled with Cyclotron. Theese are the libraries that Cyclotron itself is built on, making them available for use by Dashboards as well. More information about these libraries can be found at
8+
a(ng-click='findItem("3rd Party Libraries")', href='?q=3rd Party Libraries') 3rd Party Libraries
9+
10+
h4 Dashboard Information
11+
12+
table
13+
tr
14+
th Method/Property
15+
th Description
16+
tr
17+
td Cyclotron.version
18+
td Property that returns the current version of Cyclotron
19+
tr
20+
td Cyclotron.dashboard
21+
td Property that returns the current Dashboard as an object
22+
tr
23+
td Cyclotron.dashboardOverrides
24+
td Property that returns an object of user-specific overrides for the current Dashboard
25+
tr
26+
td Cyclotron.dashboardName
27+
td Property that returns the name of the current Dashboard
28+
tr
29+
td Cyclotron.pageName
30+
td Property that returns the name of the currently-displayed Page
31+
tr
32+
td Cyclotron.goToPage(pageNumber)
33+
td Navigates to a specific page in the Dashboard (starting with page 1)
34+
tr
35+
td Cyclotron.getDeeplink()
36+
td Returns a deeplink URL to the current Dashboard, including the values of all Parameters
37+
38+
h4 Built-In Parameters
39+
40+
p These Parameters are built-in to every Dashboard, and appear in the URL when set. They don't have to be configured manually in the Parameters section of the Dashboard, but they can be added there in order to change the default value.
41+
42+
table
43+
tr
44+
th Parameter
45+
th Description
46+
tr
47+
td Cyclotron.parameters.page
48+
td Set to the current page number (as an integer)
49+
tr
50+
td Cyclotron.parameters.rev
51+
td Set to the Dashboard's revision number (as a string); this will be undefined when viewing the latest revision
52+
tr
53+
td Cyclotron.parameters.live
54+
td If true, causes the Dashboard to check for new Revisions more frequently. This Parameter can be set via URL only, when the Dashboard is loaded.
55+
tr
56+
td Cyclotron.parameters.autoRotate
57+
td True/false value that enables/disables rotation in the Dashboard, overriding the Dashboard's setting. This Parameter can be set via URL only, when the Dashboard is loaded.
58+
59+
h4 Data Sources
60+
61+
p These functions allow interaction with the Data Sources in the Dashboard. The
62+
em Cyclotron.dataSource
63+
| object contains each Data Source name as a key, with an object of functions as the value.
64+
65+
table
66+
tr
67+
th Method
68+
th Description
69+
tr
70+
td Cyclotron.dataSources['dataSourceName'].execute([showSpinners])
71+
td Manually executes a Data Source. If showSpinners is true, it will triggers Widgets to show a loading spinner while the Data Source is executing
72+
tr
73+
td Cyclotron.dataSources['dataSourceName'].getPromise()
74+
td Returns the latest execution promise (may be completed). The returned promise has two functions, promise.then(function) and promise.catch(function). If the Data Source has already completed, then() will execute the given function immediately. This function returns an object of resultsets, each containing columns (optional) and data.
75+
tr
76+
td Cyclotron.dataSources['dataSourceName'].getCachedDataSet([resultSetName])
77+
td Returns the latest resultset for the Data Source if it exists, else null. If no resultSet argument is provided, the default resultset name of '0' will be used. This function returns the result set data directly.
78+
tr
79+
td Cyclotron.dataSources['dataSourceName'].getData()
80+
td Deprecated; do not use
81+
tr
82+
td Cyclotron.dataSources['dataSourceName'].init()
83+
td Initializes the Data Source and starts automatic refresh if configured. This method is used internally by Widgets; execute() is probably better suited to custom JavaScript scripting.
84+
85+
h4 Widgets
86+
87+
p These functions apply overrides to Widgets in the Dashboard. In order to use these functions, the Widget needs to have the
88+
em name
89+
| property configured; the
90+
em Cyclotron.currentPage.widgets
91+
| object contains each Widget name as a key, with an object of functions as the value.
92+
93+
table
94+
tr
95+
th Method
96+
th Description
97+
tr
98+
td Cyclotron.currentPage.widgets['widgetName'].show()
99+
td Shows a Widget; overrides the Widget's
100+
em hidden
101+
| property
102+
tr
103+
td Cyclotron.currentPage.widgets['widgetName'].hide()
104+
td Hides a Widget; overrides the Widget's
105+
em hidden
106+
| property
107+
tr
108+
td Cyclotron.currentPage.widgets['widgetName'].toggleVisibility()
109+
td Toggles the visibility of a Widget; overrides the Widget's
110+
em hidden
111+
| property
112+
113+
h4 CyclotronData
114+
115+
p CyclotronData has a JavaScript API for reading/writing data. This is documented separately on the
116+
a(ng-click='findItem("CyclotronData")', href='?q=CyclotronData') CyclotronData
117+
| page.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

22
.widget-error-container
3-
.fa.fa-exclamation(title='{{ dataSourceErrorMessage }}')
3+
.fa.fa-exclamation(title='{{ errorMessage }}')
44
.widget-reload(ng-click='reload()')
55
i.fa.fa-refresh
66
| Reload
7-
.widget-error-message(title='{{ dataSourceErrorMessage }}')
7+
.widget-error-message(title='{{ errorMessage }}')
88
| {{ shortErrorMessage }}

cyclotron-site/app/scripts/common/app.coffee

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ cyclotronServices = angular.module 'cyclotronApp.services', ['ngResource']
5959

6060
cyclotronApp.config ($stateProvider, $urlRouterProvider, $locationProvider, $controllerProvider, $compileProvider, $provide, uiSelectConfig) ->
6161

62+
# Improve performance
63+
$compileProvider.debugInfoEnabled false
64+
6265
uiSelectConfig.theme = 'select2'
6366

6467
# Save some providers for later

cyclotron-site/app/scripts/common/services/services.commonConfigService.coffee

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ cyclotronServices.factory 'commonConfigService', ->
2626

2727
exports = {
2828

29-
version: '1.32.0'
29+
version: '1.33.0'
3030

3131
logging:
3232
enableDebug: false
@@ -1088,6 +1088,11 @@ cyclotronServices.factory 'commonConfigService', ->
10881088
path: '/partials/help/examples.html'
10891089
tags: ['examples', 'cyclotron-examples']
10901090
}
1091+
{
1092+
name: 'Browser Compatibility'
1093+
path: '/partials/help/browserCompat.html'
1094+
tags: ['browser', 'compatibility', 'firefox', 'chrome', 'internet explorer', 'ie', 'safari', 'browsercheck']
1095+
}
10911096
{
10921097
name: 'Permissions'
10931098
path: '/partials/help/permissions.html'
@@ -1098,16 +1103,16 @@ cyclotronServices.factory 'commonConfigService', ->
10981103
path: '/partials/help/encryptedStrings.html'
10991104
tags: ['encryption', 'encrypted', '!{', 'decrypt', 'encrypt']
11001105
}
1106+
{
1107+
name: 'JavaScript API'
1108+
path: '/partials/help/javascriptApi.html'
1109+
tags: ['javascript', 'api', 'scripting']
1110+
}
11011111
{
11021112
name: 'CyclotronData'
11031113
path: '/partials/help/cyclotrondata.html'
11041114
tags: ['cyclotrondata', 'data', 'storage', 'bucket', 'api']
11051115
}
1106-
{
1107-
name: 'Browser Compatibility'
1108-
path: '/partials/help/browserCompat.html'
1109-
tags: ['browser', 'compatibility', 'firefox', 'chrome', 'internet explorer', 'ie', 'safari', 'browsercheck']
1110-
}
11111116
{
11121117
name: '3rd Party Libraries'
11131118
path: '/partials/help/3rdparty.html'

cyclotron-site/app/scripts/dashboards/controller.dashboard.coffee

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#
1818
# Home controller.
1919
#
20-
cyclotronApp.controller 'DashboardController', ($scope, $stateParams, $location, $timeout, $window, $q, $uibModal, analyticsService, configService, cyclotronDataService, dashboardService, dataService, loadService, logService, parameterService, userService) ->
20+
cyclotronApp.controller 'DashboardController', ($scope, $stateParams, $localForage, $location, $timeout, $window, $q, $uibModal, analyticsService, configService, cyclotronDataService, dashboardService, dataService, loadService, logService, parameterService, userService) ->
2121

2222
preloadTimer = null
2323
rotateTimer = null
@@ -101,6 +101,9 @@ cyclotronApp.controller 'DashboardController', ($scope, $stateParams, $location,
101101

102102
$scope.updateUrl()
103103

104+
$window.Cyclotron.currentPage =
105+
widgets: {}
106+
104107
# Track analytics
105108
analyticsService.recordPageView $scope.dashboardWrapper, $scope.currentPageIndex, $scope.firstLoad
106109

@@ -285,18 +288,32 @@ cyclotronApp.controller 'DashboardController', ($scope, $stateParams, $location,
285288
dashboardService.setDashboardDefaults(dashboard)
286289
$scope.dashboard = dashboard
287290

291+
# Initialize dashboard overrides
292+
$scope.dashboardOverrides.pages ?= []
293+
_.each dashboard.pages, (page, index) ->
294+
if !$scope.dashboardOverrides.pages[index]?
295+
$scope.dashboardOverrides.pages.push { widgets: [] }
296+
$scope.dashboardOverrides.pages[index].widgets ?= []
297+
_.each page.widgets, (widget, widgetIndex) ->
298+
if !$scope.dashboardOverrides.pages[index].widgets[widgetIndex]?
299+
$scope.dashboardOverrides.pages[index].widgets.push {}
300+
288301
# Optionally disable analytics
289302
if dashboard.disableAnalytics == true
290303
configService.enableAnalytics = false
291304

292305
dependenciesLoaded = ->
293-
# Update current page if needed
294-
if $scope.currentPage?
306+
# Check if a new revision of the Dashboard has been loaded
307+
if $scope.latestRevision and $scope.latestRevision < $scope.dashboardWrapper.rev
308+
# Update current page if needed
295309
originalPage = $scope.currentPage[$scope.currentPage.length-1]
296310
newPage = $scope.dashboard.pages[$scope.currentPageIndex]
297311
if !angular.equals(originalPage, newPage)
312+
logService.debug 'Replacing the current page with a new revision'
298313
$scope.currentPage[$scope.currentPage.length-1] = newPage
299314

315+
$scope.latestRevision = $scope.dashboardWrapper.rev
316+
300317
# Resolve promise
301318
deferred.resolve()
302319

@@ -389,7 +406,7 @@ cyclotronApp.controller 'DashboardController', ($scope, $stateParams, $location,
389406
_.each themes, (theme) ->
390407
loadService.loadCssUrl('/css/app.themes.' + theme + '.css', true)
391408

392-
# Intialize parameters
409+
# Initialize parameters
393410
parameterService.initializeParameters($scope.dashboard).then ->
394411

395412
# Watch querystring for changes
@@ -449,7 +466,14 @@ cyclotronApp.controller 'DashboardController', ($scope, $stateParams, $location,
449466
.search $scope.deeplinkOptions
450467
.toString()
451468

452-
$scope.loadDashboard().then $scope.initialLoad
469+
# Load Overrides, then the dashboard
470+
$localForage.bind($scope, {
471+
key: 'dashboardOverrides'
472+
defaultValue: { pages: [] }
473+
}).then ->
474+
$window.Cyclotron.dashboardOverrides = $scope.dashboardOverrides
475+
logService.debug 'Dashboard Overrides: ' + JSON.stringify($scope.dashboardOverrides)
476+
$scope.loadDashboard().then $scope.initialLoad
453477

454478
#
455479
# Hot Key Bindings

cyclotron-site/app/scripts/dashboards/directives/directives.dashboardPage.coffee

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
###
2-
# Copyright (c) 2013-2015 the original author or authors.
2+
# Copyright (c) 2013-2016 the original author or authors.
33
#
44
# Licensed under the MIT License (the "License");
55
# you may not use this file except in compliance with the License.
@@ -14,18 +14,31 @@
1414
# language governing permissions and limitations under the License.
1515
###
1616

17+
#
18+
# Top-level Page directive
19+
#
20+
# Renders a series of Widgets and manages page-level interactivity. Expects the following
21+
# scope variables:
22+
# page: Page to render
23+
# pageOverrides: Overrides for the current page
24+
# pageNumber: Index of the Page in the Dashboard (zero-indexed)
25+
# dashboard: Entire Dashboard object
26+
#
1727
cyclotronDirectives.directive 'dashboardPage', ($compile, $window, $timeout, configService, layoutService, logService) ->
1828
{
1929
replace: true
2030
restrict: 'A'
2131

2232
scope:
2333
page: '='
34+
pageOverrides: '='
35+
pageNumber: '@'
2436
dashboard: '='
2537

2638
template: '<div class="dashboard-page dashboard-{{page.theme}} {{page.style}}">' +
2739
'<div class="dashboard-page-inner">' +
28-
'<div widget="widget" class="dashboard-widgetwrapper dashboard-{{widget.theme}}" ng-repeat="widget in page.widgets"></div>' +
40+
'<div class="dashboard-widgetwrapper dashboard-{{widget.theme}}" ng-repeat="widget in page.widgets"' +
41+
' widget="widget" page-overrides="pageOverrides" widget-index="$index" layout="layout" dashboard="dashboard" post-layout="postLayout()"></div>' +
2942
'</div></div>'
3043

3144
link: (scope, element, attrs) ->
@@ -107,21 +120,18 @@ cyclotronDirectives.directive 'dashboardPage', ($compile, $window, $timeout, con
107120
scope.postLayout = _.after newValue.widgets.length, ->
108121
if (newValue.enableMasonry != false)
109122
masonry(element, scope.layout)
123+
return
110124

111-
newLayout = layoutService.getLayout(newValue, $($window).width(), $($window).height())
112-
113-
# Optional persistent widget area of layout
114-
newLayout.widget = scope.layout?.widget || {}
115-
scope.layout = newLayout
125+
scope.layout = layoutService.getLayout(newValue, $($window).width(), $($window).height())
116126

117127
# Set page margin if defined
118128
if !_.isNullOrUndefined(scope.layout.margin)
119-
$element.css('padding', scope.layout.margin + 'px')
129+
$element.css 'padding', scope.layout.margin + 'px'
120130

121-
$dashboardPageInner.css({
131+
$dashboardPageInner.css {
122132
marginRight: '-' + scope.layout.gutter + 'px'
123133
marginBottom: '-' + scope.layout.gutter + 'px'
124-
})
134+
}
125135

126136
# Enable/disable scrolling of the dashboard page
127137
if !scope.layout.scrolling
@@ -172,4 +182,5 @@ cyclotronDirectives.directive 'dashboardPage', ($compile, $window, $timeout, con
172182
$dashboardPageInner.masonry('destroy')
173183

174184
return
185+
175186
}

cyclotron-site/app/scripts/dashboards/directives/directives.dashboardWidget.coffee

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ cyclotronDirectives.directive 'dashboardWidget', (layoutService) ->
2424

2525
scope.$watch 'widget', (widget) ->
2626

27-
# Ignore the widget if hidden is set
28-
return if widget.hidden == true
29-
3027
# Wire-up fullscreen button if available
3128
if widget.allowFullscreen
3229
$parent.find('.widget-fullscreen').click ->

0 commit comments

Comments
 (0)