-
Eike Cochu authoredEike Cochu authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
directives.js 14.12 KiB
/******************************************************************************
* Vipra Application
* Directives
******************************************************************************/
/* globals angular, Vipra, bootbox, $ */
(function() {
"use strict";
var app = angular.module('vipra.directives', [
'ui.router'
]);
app.directive('topicLink', [function() {
return {
scope: {
topic: '=',
badge: '@',
menu: '@'
},
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'html/directives/topic-link.html',
link: function($scope) {
$scope.showBadge = $scope.badge !== 'false';
$scope.showMenu = $scope.menu !== 'false';
}
};
}]);
app.directive('wordLink', [function() {
return {
scope: {
word: '=',
menu: '@'
},
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'html/directives/word-link.html',
link: function($scope) {
$scope.showBadge = $scope.badge !== 'false';
$scope.showMenu = $scope.menu !== 'false';
}
};
}]);
app.directive('articleLink', ['ArticleFactory', function(ArticleFactory) {
return {
scope: {
article: '=',
excerpt: '@',
badge: '@',
menu: '@'
},
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'html/directives/article-link.html',
link: function($scope) {
$scope.showExcerpt = $scope.excerpt !== 'false';
$scope.showBadge = $scope.badge !== 'false';
$scope.showMenu = $scope.menu !== 'false';
$scope.toggleExcerpt = function() {
if (!$scope.excerptShown) {
if ($scope.excerpt) {
$scope.excerptShown = true;
} else {
ArticleFactory.get({
id: $scope.article.id,
excerpt: true
}, function(data) {
$scope.excerpt = data.text;
$scope.excerptShown = true;
});
}
} else {
$scope.excerptShown = false;
}
};
}
};
}]);
app.directive('entityLink', [function() {
return {
scope: {
entity: '=',
menu: '@'
},
restrict: 'E',
replace: true,
transclude: true,
templateUrl: 'html/directives/entity-link.html',
link: function($scope) {
$scope.showMenu = $scope.menu !== 'false';
}
};
}]);
app.directive('pagination', [function() {
return {
restrict: 'E',
replace: true,
scope: {
total: '=',
page: '=',
limit: '=',
change: '&'
},
controller: 'PaginationController',
templateUrl: 'html/directives/pagination.html'
};
}]);
app.directive('highcharts', [function() {
return {
scope: {
highcharts: '='
},
link: function($scope, $element) {
$scope.$watch('highcharts', function() {
$element.highcharts($scope.highcharts);
});
}
};
}]);
app.directive('bsRadio', [function() {
return {
scope: {
bsRadio: '=',
ngModel: '='
},
restrict: 'A',
link: function($scope, $elem) {
var setActive = function() {
$elem.parent().children().removeClass("active");
$elem.addClass("active");
};
if ($scope.ngModel === $scope.bsRadio)
setActive();
$elem.click(function() {
$scope.$apply(function() {
$scope.ngModel = $scope.bsRadio;
setActive();
});
});
}
};
}]);
app.directive('bsPopover', ['$templateCache', '$compile',
function($templateCache, $compile) {
return {
restrict: 'A',
link: function($scope, $elem, $attrs) {
var content = $attrs.popoverHtml;
if ($attrs.popoverTemplate) {
var template = $templateCache.get($attrs.popoverTemplate);
content = $compile(template)($scope);
}
$scope.label = $attrs.popoverLabel;
$elem.popover({
animation: ($attrs.popoverAnimation === 'true') || true,
container: $attrs.popoverContainer || 'body',
content: content,
delay: parseInt($attrs.popoverDelay || 1000, 10),
html: $attrs.popoverHtml || true,
placement: $attrs.popoverPlacement || 'right',
title: $attrs.popoverTitle,
trigger: $attrs.popoverTrigger || 'hover'
});
}
};
}
]);
app.directive('bsTab', [function() {
return {
link: function($scope, $elem, $attrs) {
$elem.on('shown.bs.tab', function() {
if ($attrs.shown) {
$scope.$eval($attrs.shown);
}
var hc = $($elem.data('target')).find('[highcharts]');
if(hc.length) {
hc.highcharts().reflow();
}
});
}
};
}]);
app.directive('bsAlert', [function() {
return {
scope: {
ngModel: '=',
type: '@',
dismissible: '@'
},
replace: true,
restrict: 'E',
link: function($scope) {
var classes = ['alert'];
$scope.dismissible = $scope.dismissible !== 'false';
if ($scope.dismissible) {
classes.push('alert-dismissible');
}
switch ($scope.type) {
case 'success':
case 'info':
case 'warning':
classes.push('alert-' + $scope.type);
break;
case 'danger':
/* falls through */
default:
classes.push('alert-danger');
}
$scope.classes = classes.join(' ');
},
templateUrl: 'html/directives/alert.html'
};
}]);
app.directive('bsDatetimepicker', [function() {
return {
scope: {
ngModel: '='
},
link: function($scope, $elem) {
$elem.datetimepicker({
sideBySide: true,
calendarWeeks: true,
showTodayButton: true,
showClear: true,
toolbarPlacement: 'top',
useCurrent: false
});
$elem.on('dp.change', function(e) {
$scope.$apply(function() {
$scope.ngModel = e.date.toDate();
});
});
}
};
}]);
app.directive('sequenceDropdown', [function() {
return {
scope: {
ngModel: '=',
sequences: '=',
dropup: '@'
},
link: function($scope) {
$scope.showDropup = $scope.dropup === 'true';
$scope.$watch('sequences', function(newValue) {
if (newValue) {
for (var i = 0, s; i < $scope.sequences.length; i++) {
s = $scope.sequences[i];
s.label = Vipra.windowLabel(s.window.startDate, s.window.windowResolution);
}
}
});
},
templateUrl: '/html/directives/sequence-dropdown.html'
};
}]);
app.directive('windowDropdown', [function() {
return {
scope: {
ngModel: '=',
windows: '=',
dropup: '@'
},
link: function($scope) {
$scope.showDropup = $scope.dropup === 'true';
$scope.$watch('windows', function(newValue) {
if (newValue) {
for (var i = 0, w; i < $scope.windows.length; i++) {
w = $scope.windows[i];
w.label = Vipra.windowLabel(w.startDate, w.windowResolution);
}
}
});
},
templateUrl: '/html/directives/window-dropdown.html'
};
}]);
app.directive('sortBy', [function() {
return {
restrict: 'A',
scope: {
ngModel: '=',
sortBy: '@'
},
link: function($scope, $elem) {
$elem.click(function() {
$scope.$apply(function() {
$scope.reverse = false;
if ($scope.ngModel === $scope.sortBy) {
$scope.ngModel = '-' + $scope.sortBy;
$scope.reverse = true;
} else {
$scope.ngModel = $scope.sortBy;
$scope.reverse = false;
}
});
});
$scope.showCaret = function() {
return $scope.ngModel === $scope.sortBy || $scope.ngModel === '-' + $scope.sortBy;
};
$scope.$watch('ngModel', function() {
if ($scope.ngModel === $scope.sortBy)
$scope.reverse = false;
else if ($scope.ngModel === '-' + $scope.sortBy)
$scope.reverse = true;
});
},
transclude: true,
template: '<span ng-transclude></span> <i class="fa" ng-class="{\'fa-caret-down\':!reverse, \'fa-caret-up\':reverse}" ng-show="showCaret()" ng-cloak></i>'
};
}]);
app.directive('topicMenu', ['TopicFactory', function(TopicFactory) {
return {
scope: {
topic: '=',
right: '@'
},
restrict: 'E',
templateUrl: 'html/directives/topic-menu.html',
link: function($scope) {
$scope.dropdownRight = $scope.right === 'true';
$scope.renameTopic = function() {
bootbox.prompt({
title: 'Rename topic',
value: $scope.topic.name,
callback: function(name) {
if (name && name.length && name !== $scope.topic.name) {
var oldName = $scope.topic.name;
$scope.topic.name = name;
$scope.$apply(function() {
TopicFactory.update({
id: $scope.topic.id
}, $scope.topic, function(data) {
$scope.topic = data;
}, function(err) {
$scope.topic.name = oldName;
$scope.errors = err;
});
});
}
}
});
};
}
};
}]);
app.directive('wordMenu', [function() {
return {
scope: {
word: '=',
right: '@'
},
restrict: 'E',
templateUrl: 'html/directives/word-menu.html',
link: function($scope) {
$scope.dropdownRight = $scope.right === 'true';
}
};
}]);
app.directive('entityMenu', [function() {
return {
scope: {
entity: '=',
right: '@'
},
restrict: 'E',
templateUrl: 'html/directives/entity-menu.html',
link: function($scope) {
$scope.dropdownRight = $scope.right === 'true';
}
};
}]);
app.directive('articleMenu', [function() {
return {
scope: {
article: '=',
right: '@'
},
restrict: 'E',
templateUrl: 'html/directives/article-menu.html',
link: function($scope) {
$scope.dropdownRight = $scope.right === 'true';
}
};
}]);
app.directive('sortDir', [function() {
return {
scope: {
ngModel: '='
},
restrict: 'E',
replace: true,
templateUrl: 'html/directives/sort-dir.html'
};
}]);
app.directive('ngEnter', [function() {
return {
link: function($scope, $elem, $attrs) {
$elem.bind("keydown keypress", function(event) {
if (event.which === 13) {
$scope.$apply(function() {
$scope.$eval($attrs.ngEnter);
});
event.preventDefault();
}
});
}
};
}]);
app.directive('changePos', [function() {
return {
scope: {
change: '='
},
link: function($scope) {
$scope.changed = function() {
var change = parseInt($scope.change);
if (!isNaN(change)) {
$scope.changeVal = change;
if (change > 0)
$scope.change = '+' + change;
} else {
$scope.changeVal = 0;
}
};
$scope.$watch('change', $scope.changed);
},
templateUrl: 'html/directives/change-pos.html'
};
}]);
app.directive('menuAffix', [function() {
return {
transclude: true,
template: '<div class="menu-affix" ng-transclude></div><div class="affix-after"></div>',
link: function($scope, $elem) {
var elem = $elem.find('.menu-affix'),
after = $elem.find('.affix-after');
elem.affix({
offset: {
top: elem.offset().top - 50
}
});
elem.on('affix.bs.affix', function() {
after.css('height', elem.height());
});
elem.on('affix-top.bs.affix', function() {
after.css('height', 0);
});
}
};
}]);
app.directive('info', [function() {
return {
scope: {
text: '@'
},
replace: true,
template: '<i class="fa fa-info info" ng-attr-title="{{::text}}"></i>'
};
}]);
app.directive('wordEvolution', [function() {
return {
scope: {
topic: '=',
chartId: '@'
},
replace: true,
controller: 'WordEvolutionController',
templateUrl: 'html/directives/word-evolution.html'
};
}]);
app.directive('charSelector', [function() {
return {
replace: true,
scope: {
ngModel: '='
},
link: function($scope, $elem) {
$elem.on('click', 'a', function() {
var c = $(this).data('char');
$scope.$apply(function() {
$scope.ngModel = c;
});
});
},
templateUrl: 'html/directives/char-selector.html'
};
}]);
app.directive('articlePopover', ['ArticleFactory', function(ArticleFactory) {
return {
scope: {
id: '=',
article: '='
},
link: function($scope) {
$scope.$watch('id', function() {
if(!$scope.id) {
$scope.currentArticle = null;
return;
}
ArticleFactory.get({
id: $scope.id
}, function(data) {
$scope.currentArticle = data;
$scope.currentArticleDate = $scope.currentArticle ? Vipra.formatDate($scope.currentArticle.date) : null;
});
});
$scope.$watch('article', function() {
$scope.currentArticle = $scope.article;
$scope.currentArticleDate = $scope.article ? Vipra.formatDate($scope.currentArticle.date) : null;
});
},
templateUrl: 'html/directives/article-popover.html'
};
}]);
})();