--- /dev/null
+[%
+ WRAPPER 'staff/base.tt2';
+ ctx.page_type = l('Statistical Popularity Badges');
+ ctx.page_app = 'egAdminRating';
+ ctx.page_ctrl = 'Badges';
+%]
+
+[% BLOCK APP_JS %]
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/grid.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/ui.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/admin/local/rating/badge.js"></script>
+<link rel="stylesheet" href="[% ctx.base_path %]/staff/css/admin.css" />
+<script>
+ angular.module('egCoreMod').run(['egStrings', function(s) {
+ s.CONFIRM_DELETE_BADGE_TITLE =
+ "[% l('Confirm badge deletion') %]";
+ s.CONFIRM_DELETE_BADGE_BODY =
+ "[% l('Delete badge {{id}} ({{name}})?') %]";
+ }]);
+</script>
+[% END %]
+
+<div class="container-fluid" style="text-align:center">
+ <div class="alert alert-info alert-less-pad strong-text-2">
+ [% l('Statistical Popularity Badges') %]
+ </div>
+</div>
+
+<!--
+<div class="row">
+ <div class="col-md-4">
+ <div class="form-group">
+ <label>[% l('Scope Library') %]</label>
+ <eg-org-selector onchange="org_changed"
+ selected="context_org"></eg-org-selector>
+ </div>
+ </div>
+</div>
+-->
+
+<eg-grid
+ id-field="id"
+ idl-class="rb"
+ grid-controls="gridControls"
+ features="-multiselect"
+ persist-key="admin.local.rating.badge">
+
+ <eg-grid-action label="[% l('Add badge') %]" handler="create_rb"></eg-grid-action>
+ <eg-grid-action label="[% l('Edit badge') %]" handler="update_rb"></eg-grid-action>
+ <eg-grid-action label="[% l('Delete badge') %]" handler="delete_rb"></eg-grid-action>
+
+ <eg-grid-field label="[% l('Name') %]" path='name'></eg-grid-field>
+ <eg-grid-field label="[% l('Description') %]" path='description'></eg-grid-field>
+ <eg-grid-field label="[% l('Scope') %]" path='scope.name'></eg-grid-field>
+ <eg-grid-field label="[% l('Popularity Parameter') %]" path='popularity_parameter.name'></eg-grid-field>
+ <eg-grid-field label="[% l('ID') %]" path='id' required hidden></eg-grid-field>
+ <eg-grid-field path='*' hidden></eg-grid-field>
+</eg-grid>
+
+[% END %]
--- /dev/null
+<form ng-submit="ok(record)" role="form" class="form-validated">
+ <div class="modal-header">
+ <button type="button" class="close" ng-click="cancel()"
+ aria-hidden="true">×</button>
+ <h4 class="modal-title">{{record_label}}</h4>
+ </div>
+ <div class="modal-body">
+ <div class="form-group row" ng-repeat="field in fields | filter:{virtual:'!true'}">
+ <div class="col-md-3">
+ <label for="rec-{{field.name}}">{{field.label}}</label>
+ </div>
+ <div class="col-md-9">
+ <span ng-if="field.datatype == 'id' || field.readonly">{{record[field.name]}}</span>
+ <eg-org-selector ng-if="field.datatype == 'org_unit'"
+ selected="record[field.name + '_ou'].org"
+ onchange="record[field.name + '_ou'].update_org">
+ </eg-org-selector>
+ <input ng-if="field.datatype == 'text'"
+ ng-required="field.is_required(record)"
+ ng-model="record[field.name]"></input>
+ <input ng-if="field.datatype == 'int'" type="number"
+ ng-required="field.is_required(record)"
+ ng-model="record[field.name]"></input>
+ <input ng-if="field.datatype == 'float'" type="number" step="0.1"
+ ng-required="field.is_required(record)"
+ ng-model="record[field.name]"></input>
+ <span ng-if="field.datatype == 'link'" class="nullable">
+ <select ng-if="field.datatype == 'link'"
+ ng-options="item.id as item.name for item in field.linked_values"
+ ng-model="record[field.name]">
+ <option value=""></option>
+ </select>
+ </span>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <input type="submit" class="btn btn-primary" value="[% l('OK') %]"/>
+ <button class="btn btn-warning" ng-click="cancel($event)">[% l('Cancel') %]</button>
+ </div>
+ </div> <!-- modal-content -->
+</form>
--- /dev/null
+angular.module('egAdminRating',
+ ['ngRoute','ui.bootstrap','egCoreMod','egUiMod','egGridMod'])
+
+.controller('Badges',
+ ['$scope','$q','$timeout','$location','$window','$modal',
+ 'egCore','egGridDataProvider','egConfirmDialog',
+function($scope , $q , $timeout , $location , $window , $modal ,
+ egCore , egGridDataProvider , egConfirmDialog) {
+
+ egCore.startup.go();
+
+ function get_record_label() {
+ return egCore.idl.classes['rb'].label;
+ }
+
+ function flatten_linked_values(cls, list) {
+ var results = [];
+ var fields = egCore.idl.classes[cls].fields;
+ var id_field;
+ var selector;
+ angular.forEach(fields, function(fld) {
+ if (fld.datatype == 'id') {
+ id_field = fld.name;
+ selector = fld.selector ? fld.selector : id_field;
+ return;
+ }
+ });
+ angular.forEach(list, function(item) {
+ var rec = egCore.idl.toHash(item);
+ results.push({
+ id : rec[id_field],
+ name : rec[selector]
+ });
+ });
+ return results;
+ }
+
+ horizon_required = {};
+ percentile_required = {};
+ function get_popularity_with_required() {
+ egCore.pcrud.retrieveAll(
+ 'rp', {}, {atomic : true}
+ ).then(function(list) {
+ angular.forEach(list, function(item) {
+ horizon_required[item.id()] = item.require_horizon();
+ percentile_required[item.id()] = item.require_percentile();
+ });
+ });
+ }
+
+ function get_field_list(rec) {
+ var fields = egCore.idl.classes['rb'].fields;
+
+ var promises = [];
+ // flesh selectors
+ angular.forEach(fields, function(fld) {
+ if (fld.datatype == 'link') {
+ egCore.pcrud.retrieveAll(
+ fld.class, {}, {atomic : true}
+ ).then(function(list) {
+ fld.linked_values = flatten_linked_values(fld.class, list);
+ });
+ }
+ if (fld.datatype == 'org_unit') {
+ rec[fld.name + '_ou'] = {};
+ rec[fld.name + '_ou']['org'] = egCore.org.get(rec[fld.name]);
+ rec[fld.name + '_ou']['update_org'] = function(org) {
+ rec[fld.name] = org.id();
+ };
+ }
+ if (fld.name == 'last_calc') {
+ fld['readonly'] = true;
+ }
+ fld.is_required = function(record) {
+ return false;
+ };
+ if (fld.name == 'name') {
+ fld.is_required = function(record) {
+ return true;
+ };
+ }
+ if (fld.name == 'horizon_age') {
+ fld.is_required = function(record) {
+ return horizon_required[record['popularity_parameter']] == 't';
+ };
+ }
+ if (fld.name == 'percentile') {
+ fld.is_required = function(record) {
+ return percentile_required[record['popularity_parameter']] == 't';
+ };
+ }
+ });
+ return fields;
+ }
+
+ function spawn_editor(rb, action) {
+ var deferred = $q.defer();
+ $modal.open({
+ templateUrl: './admin/local/rating/edit_badge',
+ controller:
+ ['$scope', '$modalInstance', function($scope, $modalInstance) {
+ $scope.focusMe = true;
+ $scope.record = egCore.idl.toHash(rb);
+ // non-integer numeric field require parseFloat
+ $scope.record.percentile = parseFloat($scope.record.percentile);
+ $scope.record_label = get_record_label();
+ $scope.fields = get_field_list($scope.record);
+ get_popularity_with_required();
+ $scope.ok = function(args) { $modalInstance.close(args) }
+ $scope.cancel = function () { $modalInstance.dismiss() }
+ }]
+ }).result.then(function(args) {
+ var rb = new egCore.idl.rb();
+ if (action == 'update') rb.id(args.id);
+ rb.name(args.name);
+ rb.description(args.description);
+ rb.scope(args.scope);
+ rb.weight(args.weight);
+ rb.horizon_age(args.horizon_age);
+ rb.importance_age(args.importance_age);
+ rb.importance_interval(args.importance_interval);
+ rb.importance_scale(args.importance_scale);
+ rb.recalc_interval(args.recalc_interval);
+ rb.attr_filter(args.attr_filter);
+ rb.src_filter(args.src_filter);
+ rb.circ_mod_filter(args.circ_mod_filter);
+ rb.loc_grp_filter(args.loc_grp_filter);
+ rb.popularity_parameter(args.popularity_parameter);
+ rb.fixed_rating(args.fixed_rating);
+ rb.percentile(args.percentile);
+ rb.discard(args.discard);
+ rb.last_calc(args.last_calc);
+ if (action == 'create') {
+ egCore.pcrud.create(rb).then(function() { deferred.resolve(); });
+ } else {
+ egCore.pcrud.update(rb).then(function() { deferred.resolve(); });
+ }
+ });
+ return deferred.promise;
+ }
+
+ $scope.create_rb = function() {
+ var rb = new egCore.idl.rb();
+
+ // make sure an OU is selected by default
+ rb.scope(egCore.auth.user().ws_ou());
+
+ spawn_editor(rb, 'create').then(function() {
+ $scope.gridControls.refresh();
+ });
+ }
+
+ $scope.update_rb = function(selected) {
+ if (!selected || !selected.length) return;
+
+ egCore.pcrud.retrieve('rb', selected[0].id).then(function(rb) {
+ spawn_editor(rb, 'update').then(function() {
+ $scope.gridControls.refresh();
+ });
+ });
+ }
+
+ $scope.delete_rb = function(selected) {
+ if (!selected || !selected.length) return;
+
+ egCore.pcrud.retrieve('rb', selected[0].id).then(function(rb) {
+ egConfirmDialog.open(
+ egCore.strings.CONFIRM_DELETE_BADGE_TITLE,
+ egCore.strings.CONFIRM_DELETE_BADGE_BODY,
+ { name : rb.name(), id : rb.id() }
+ ).result.then(function() {
+ egCore.pcrud.remove(rb).then(function() {
+ $scope.gridControls.refresh();
+ });
+ });
+ });
+ }
+
+ $scope.gridControls = {
+ activateItem : function (item) {
+ $scope.update_rb([item]);
+ },
+ setQuery : function() {
+ return {
+ 'id' : {'!=' : null}
+ }
+ }
+ }
+}])