Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
### v1.8.0 | 2018 - Week 10

#### Adds
- [IMPAC-793] Load dynamic generic layout templates for Bolt widgets
- [IMPAC-791] Add generic table layout template

#### Fixes

Expand Down
2 changes: 1 addition & 1 deletion src/components/dashboard/dashboard.directive.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ module.controller('ImpacDashboardCtrl', ($scope, $http, $q, $filter, $uibModal,
return []

$scope.addWidget = (widgetTemplate) ->
params = _.pick(widgetTemplate, ['endpoint', 'name', 'width', 'metadata'])
params = _.pick(widgetTemplate, ['endpoint', 'name', 'width', 'metadata', 'layouts'])

angular.element('#widget-selector').css('cursor', 'progress')
angular.element('#widget-selector .section-lines .line-item').css('cursor', 'progress')
Expand Down
30 changes: 22 additions & 8 deletions src/components/widget/widget.directive.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ module.controller('ImpacWidgetCtrl', ($scope, $log, $q, $timeout, ImpacWidgetsSv
ImpacDashboardsSvc.tick()
)

module.directive('impacWidget', ($templateCache, ImpacUtilities, ImpacWidgetsSvc) ->
module.directive('impacWidget', ($log, $templateCache, ImpacUtilities, ImpacWidgetsSvc, ImpacWidgetsTemplates, toastr) ->
return {
restrict: 'A',
scope: {
Expand All @@ -75,16 +75,22 @@ module.directive('impacWidget', ($templateCache, ImpacUtilities, ImpacWidgetsSvc
},
controller: 'ImpacWidgetCtrl',
link: (scope, element) ->

# initialize scope attributes
# --------------------------------------
scope.widget.isLoading = true
scope.widget.settings = []
scope.pdfMode = false
scope.cssClass = ImpacUtilities.fetchWidgetCssClass(scope.widget)
scope.templatePath = ImpacUtilities.fetchWidgetTemplatePath(scope.widget)
onInit = ->
scope.showInfoPanel = false
scope.pdfMode = false
scope.widget.isLoading = true
scope.widget.settings = []
# Unused so far -->
scope.widget.hasEditAbility = true
scope.widget.hasDeleteAbility = true
# <--

scope.cssClass = ImpacWidgetsTemplates.filename(scope.widget)
scope.templatePath = ImpacWidgetsTemplates.templatePath(scope.widget)
_handleNoTemplateFound() unless scope.templatePath

scope.showInfoPanel = false
scope.isInfoPanelDisplayed = ->
scope.showInfoPanel

Expand All @@ -106,6 +112,14 @@ module.directive('impacWidget', ($templateCache, ImpacUtilities, ImpacWidgetsSvc
ImpacWidgetsSvc.delete(scope.widget)
.then(null, (e) -> scope.widget.errors = ImpacUtilities.processRailsError(e))

_handleNoTemplateFound = ->
toastr.warning('See browser console for more details', "No template found for #{scope.widget.name}")
$log.error("No template or generic layout template found for #{scope.widget.name}, either add a custom template or blacklist the widget via the ImpacTheming service.")
scope.deleteWidget()

onInit()

return
,template: $templateCache.get('widget/widget.tmpl.html')
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.component('chartThreshold', {
kpiCreateLabel: '<?'
thresholdColor: '@'
onComplete: '&?'
controller: ($timeout, $log, ImpacKpisSvc, ImpacUtilities, toastr)->
controller: ($timeout, $log, ImpacKpisSvc, toastr)->
ctrl = this

ctrl.$onInit = ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
module = angular.module('impac.components.widgets-common.info-panel',[])

module.directive('commonInfoPanel', ($templateCache, ImpacUtilities) ->
module.directive('commonInfoPanel', ($templateCache, ImpacWidgetsTemplates) ->
return {
restrict: 'A'
scope: {
parentWidget: '='
onClose: '&'
}
template: $templateCache.get('widgets-common/info-panel.tmpl.html')

link: (scope) ->

w = scope.parentWidget
Expand All @@ -19,7 +19,7 @@ module.directive('commonInfoPanel', ($templateCache, ImpacUtilities) ->
scope.onClose()

scope.getWidgetTemplateName = ->
cssClass = ImpacUtilities.fetchWidgetCssClass(w)
cssClass = ImpacWidgetsTemplates.filename(w)
return "" unless cssClass

cssClassArray = cssClass.split('-')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module = angular.module('impac.components.widgets-common.top-buttons', [])
module.controller('CommonTopButtonsCtrl', ($scope, $rootScope, $log, ImpacWidgetsSvc, ImpacAssets, ImpacUtilities) ->
module.controller('CommonTopButtonsCtrl', ($scope, $rootScope, $log, ImpacWidgetsSvc, ImpacAssets) ->

w = $scope.parentWidget
w.isEditMode = false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module = angular.module('impac.components.widgets.accounts-cash-balance', [])
module = angular.module('impac.components.widgets-layouts.accounts-cash-balance', [])
module.controller('WidgetAccountsCashBalanceCtrl', ($scope, $q, $timeout, $filter, ImpacTheming, ImpacAssets, ImpacWidgetsSvc, HighchartsFactory) ->

w = $scope.widget
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module = angular.module('impac.components.widgets.accounts-cash-projection', [])
module = angular.module('impac.components.widgets-layouts.accounts-cash-projection', [])
module.controller('WidgetAccountsCashProjectionCtrl', ($scope, $q, $filter, $timeout , ImpacKpisSvc, ImpacWidgetsSvc, ImpacAssets, HighchartsFactory, BoltResources) ->

# == Context and Helpers ========================================================================
Expand Down
120 changes: 120 additions & 0 deletions src/components/widgets-layouts/table/table.directive.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#
# Component generated by Impac! Widget Generator!
#
module = angular.module('impac.components.widgets-layouts.table', [])
module.controller('WidgetTableCtrl', ($scope, $q, $filter, ImpacWidgetsSvc) ->

w = $scope.widget

# Define settings
# --------------------------------------
$scope.orgDeferred = $q.defer();
$scope.timePeriodDeferred = $q.defer()

settingsPromises = [
$scope.orgDeferred.promise,
$scope.timePeriodDeferred.promise
]

# Configure the commonTimePeriodInfo directive
$scope.timePeriodInfoParams = {
accountingBehaviour: 'pnl'
histParams: {}
}

# Widget specific methods
# --------------------------------------
w.initContext = ->
$scope.table = _.get(w, 'content.table', {})
return if _.isEmpty($scope.table.rows)
$scope.currency = _.get(w, 'metadata.currency')
$scope.timePeriodInfoParams.histParams = _.get(w, 'metadata.hist_parameters', {})
$scope.unCollapsed = _.get(w, 'metadata.unCollapsed') || []
$scope.ascending = true
$scope.sortedColumn = $scope.table.headers.cells[0]
$scope.colSize = $scope.table.headers.cells.length
$scope.colWidth = "#{100 / $scope.colSize}%"
return

$scope.cellValue = (v)->
num = parseFloat(v)
if _.isNumber(num) && !_.isNaN(num) then $filter('mnoCurrency')(v, $scope.currency) else v

$scope.toggleCollapsed = (table, $event) ->
$event.stopPropagation()
id = table.headers.id
return unless id?
if _.find($scope.unCollapsed, ((name) -> id == name))
$scope.unCollapsed = _.reject($scope.unCollapsed, (name) -> name == id)
else
$scope.unCollapsed.push(id)
ImpacWidgetsSvc.updateWidgetSettings(w,false)

$scope.isCollapsed = (table) ->
id = table.headers.id
return unless id?
if _.find($scope.unCollapsed, ((name) -> id == name))
return false
else
return true

$scope.sort = (col, $index) ->
if $scope.sortedColumn == col
$scope.ascending = !$scope.ascending
else
$scope.ascending = true
$scope.sortedColumn = col
sortData($scope.table.rows, $index)

sortData = (rows, colIndex)->
rows.single = sortSingleRows(rows.single, colIndex) if rows.single
if rows.grouped
for table in rows.grouped
sortData(table.rows, colIndex)
return

sortSingleRows = (rows, colIndex) ->
_.sortByOrder(rows, ((r)-> r.cells[colIndex]), [$scope.ascending])

# Mini-settings objects
# handles the saving of collapsed / uncollapsed list groups.
# --------------------------------------
unCollapsedSetting = {}
unCollapsedSetting.initialized = false

unCollapsedSetting.initialize = ->
unCollapsedSetting.initialized = true

unCollapsedSetting.toMetadata = ->
{unCollapsed: $scope.unCollapsed}

w.settings.push(unCollapsedSetting)

# Widget is ready: can trigger the "wait for settings to be ready"
# --------------------------------------
$scope.widgetDeferred.resolve(settingsPromises)
)
module.directive('widgetTable', ->
return {
restrict: 'A',
controller: 'WidgetTableCtrl'
}
)
module.directive('indentTableRow', ->
return {
restrict: 'A',
link: (_$scope, $element) ->
if $element.is(':first-child')
# Get list of ancestor tables up until the root table
ancestorTables = $element.closest('table').parentsUntil('#table-layout', 'table')
# Indent <th> equal to the length of ancestors
nestLevel = ancestorTables.get().length
# Indent <td> equal to the length of ancestors plus 1
nestLevel++ if $element.is('td')

$element.css({ 'padding-left': "#{nestLevel * 20}px" })

return
}
)

35 changes: 35 additions & 0 deletions src/components/widgets-layouts/table/table.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.analytics .widget-item .content .table-layout {

table {
width: 100%;
max-width: 100%;

th,
td:not(.nested-table) {
color: @mediumblue;
border-bottom: solid 1px @lightgray;
padding: 5px 0;

&:not(:first-child) {
text-align: right;
}
}

th[ng-click] {
cursor: pointer;
}
}

#table-layout {
& > thead tr:first-child {
.font(12px,500,@impac-widget-text-color-medium);
text-transform: uppercase;
border-bottom: 2px solid @lightgray;
padding: 5px 0;
}

.nested-table {
i.fa { padding-right: 5px; }
}
}
}
74 changes: 74 additions & 0 deletions src/components/widgets-layouts/table/table.tmpl.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<!--
Component generated by Impac! Widget Generator!
-->
<div widget-table class="table-layout">
<!-- Settings Panel -->
<div ng-show="widget.isEditMode" class="edit">
<h4>Widget settings</h4>

<div setting-organizations parent-widget="widget" class="part" deferred="::orgDeferred" />
<div setting-time-period parent-widget="widget" class="part" deferred="::timePeriodDeferred" hist-params="widget.metadata.hist_parameters" />

<!-- Buttons displayed on the lower -->
<div class="bottom-buttons" align="right">
<button class="btn btn-default" ng-click="initSettings()">Cancel</button>
<button class="btn btn-warning" ng-click="updateSettings()">Save</button>
</div>
</div>

<!-- Content Panel -->
<div ng-hide="widget.isEditMode">
<div ng-hide="widget.demoData" class="widget-lines-container">
<!-- Widget Header -->
<div class="row header widget-line">
<div class="col-md-6 text-left"></div>
<div class="col-md-6 text-right">
<div common-time-period-info context="timePeriodInfoParams" />
</div>
</div>

<!-- Table Layout -->
<table id="table-layout">
<thead>
<tr>
<th width="{{colWidth}}" ng-repeat="cell in table.headers.cells" ng-click="sort(cell, $index)">
<span ng-bind="cellValue(cell)"></span>
<i ng-show="sortedColumn == cell" class="fa" ng-class="ascending ? 'fa-sort-alpha-asc' : 'fa-sort-alpha-desc'" />
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="groupedTable in table.rows.grouped">
<td class="nested-table" colspan="{{colSize}}" ng-include="'grouped-table.tmpl.html'"></td>
</tr>
<tr ng-repeat="row in table.rows.single">
<td ng-repeat="cell in row.cells" ng-bind="cellValue(cell)"></td>
</tr>
</tbody>
</table>
</div>

<div ng-show="widget.demoData" common-data-not-found />
</div>
</div>

<script type="text/ng-template" id="grouped-table.tmpl.html">
<table>
<thead>
<tr>
<th width="{{colWidth}}" ng-repeat="cell in groupedTable.headers.cells" ng-click="toggleCollapsed(groupedTable, $event)" indent-table-row>
<i class="fa" ng-if="$first" ng-class="isCollapsed(groupedTable) ? 'fa-plus-square-o' : 'fa-minus-square-o'" />
<strong ng-bind="cellValue(cell)"></strong>
</th>
</tr>
</thead>
<tbody uib-collapse="isCollapsed(groupedTable)">
<tr ng-repeat="groupedTable in groupedTable.rows.grouped">
<td class="nested-table" colspan="{{colSize}}" ng-include="'grouped-table.tmpl.html'"></td>
</tr>
<tr ng-repeat="row in groupedTable.rows.single">
<td ng-repeat="cell in row.cells" indent-table-row ng-bind="cellValue(cell)"></td>
</tr>
</tbody>
</table>
</script>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module = angular.module('impac.components.widgets-settings.hist-mode',[])

module.controller('SettingHistModeCtrl', ($scope, $translate, $timeout, ImpacWidgetsSvc, ImpacTheming, ImpacUtilities) ->
module.controller('SettingHistModeCtrl', ($scope, $translate, $timeout, ImpacWidgetsSvc, ImpacTheming) ->

w = $scope.parentWidget
w.isHistoryMode = w.metadata && w.metadata.hist_parameters && w.metadata.hist_parameters.mode == 'history'
Expand Down
Loading