}
}q|,
reduce => q| function(keys,values,rereduce) { return sum(values); } |,
- }
+ },
+ authors => {
+ map => q|
+function(doc) {
+ if ( doc.work.persons ) {
+ doc.work.persons.forEach( function(person) {
+ emit(person.surname+person.firstname ,
+ person
+ );
+ });
+ }
+ if ( doc.work.symposium_works ) {
+ doc.work.symposium_works.forEach( function(work) {
+ work.persons.forEach( function(person) {
+ emit(person.surname+person.firstname ,
+ person
+ );
+ });
+ });
+ }
+}
+ |,
+ },
}
};
$json = _couchdb_get($url)
if ( $format eq 'key_array' ) { # array of keys sorted by value
$json->{rows} = [ map { $_->{key} } sort { $b->{value} <=> $a->{value} } @{ $json->{rows} } ];
+ } elsif ( $format eq 'key_distinct' ) {
+
+ my $found;
+ $json->{rows} = [ grep { $found->{ $_->{key} }++ == 1 } @{ $json->{rows} } ];
+ $json->{distinct_rows} = scalar @{ $json->{rows} };
+ warn "## distinct stats ", dump( $found );
+
+ } elsif ( $format ) {
+
+ die "unknown format: $format";
+
}
$view_cache->{$url}->{time} = time();
<ul class="nav">
<li data-match-route="/registration"><a href="#/registration">registation</a></li>
<li data-match-route="/list"><a href="#/list">list</a></li>
+ <li data-match-route="/authors"><a href="#/authors">authors</a></li>
<li class="divider-vertical"></li>
</ul>
<div class="brand"><span app-version></span></div>
$routeProvider.when('/verified/:registrationId', {templateUrl: 'partials/verified.html', controller: RegistrationCtrl});
$routeProvider.when('/review/:registrationId', {templateUrl: 'partials/review.html', controller: RegistrationCtrl});
$routeProvider.when('/list', {templateUrl: 'partials/list.html', controller: ListCtrl});
+ $routeProvider.when('/authors', {templateUrl: 'partials/authors.html', controller: AuthorsCtrl});
$routeProvider.otherwise({redirectTo: '/registration/'});
}]);
$scope.$routeParams = $routeParams;
$scope.$location = $location;
$scope.organizations = [];
- View.getArrayPromise('organizations?group=true;format=key_array').then(function(data) {
- $scope.organizations = data;
- $log.info('organizations promise ', $scope.organizations);
+ View.getPromise('organizations?group=true;format=key_array').then(function(data) {
+ if ( angular.isArray(data.rows) ) {
+ $scope.organizations = data.rows;
+ $log.info('organizations promise ', $scope.organizations);
+ } else {
+ $log.info('no rows in', data);
+ }
});
$scope.ValidStates = ValidStates();
ListCtrl.$inject = [ '$scope', '$log', 'Registration', 'RegistrationTypes', '$filter', 'ValidStates' ];
+
+function AuthorsCtrl($scope, $log, View ) {
+ $scope.message = 'Loading data...';
+ $scope.ready = false;
+ View.getPromise('authors?format=key_distinct').then(function(data) {
+ if ( angular.isArray(data.rows) ) {
+ $scope.data = data;
+ $scope.authors = $scope.data.rows;
+ $scope.ready = true;
+ $log.info('authors promise ', data);
+ } else {
+ $log.info('no rows in', data);
+ $scope.message = 'No rows found';
+ }
+ });
+}
+
+AuthorsCtrl.$inject = [ '$scope', '$log', 'View' ];
+
+
/* http://jsfiddle.net/asgoth/7bNAd/ */
factory('View', function($q, $http, $log) {
+
+ var deferred = $q.defer();
+
return {
- getArrayPromise: function(view_url) {
+ getPromise: function(view_url) {
var url = '/<%= $couchdb_database %>/_design/registration/_view/'+view_url+';callback=JSON_CALLBACK';
- var deferred = $q.defer();
-
$log.info('defer', url);
$http.jsonp(url).success(function(json) {
$log.info('success', url);
- deferred.resolve(json.rows);
+ deferred.resolve(json);
}).error(function(error) {
$log.error('error', url, error );
deferred.reject(error);
--- /dev/null
+
+<div ng-show="! ready" class="alert alert-important">
+{{message}}
+</div>
+
+<form ng-controller="AuthorsCtrl" class="form-search" ng-show="ready">
+
+<fieldset>
+<legend>
+Authors
+</legend>
+
+<input class="my-lebel-input search-query" ng-model="search.$" label="Search">
+
+<a class="btn btn-invert" href="" ng-click="reset()">
+<i class="icon-remove"></i></a>
+
+<tt>{{search}}</tt>
+
+{{data.total_rows}} authors
+{{data.distinct_rows}} distinct
+
+</fieldset>
+
+<table ng-show="authors.length" class="table">
+<tr ng-repeat="author in authors | filter:search">
+<td>{{author.value.surname}}</td>
+<td>{{author.value.firstname}}</td>
+<td>{{author.value.organization}}</td>
+<td>{{author.value.email}}</td>
+</tr>
+</table>
+
+% if ( $lang =~ m/x-dev/ ) {
+<pre class="controls-row">
+{{authors}}
+</pre>
+% }
+
+</form>
+
expect( scope.ValidStates ).toBeTruthy();
});
});
+
+
+describe('AuthorsCtrl', function(){
+ var scope, $httpBackend;
+
+ beforeEach(module('myApp'));
+
+ beforeEach(inject(function($injector) {
+ $httpBackend = $injector.get('$httpBackend');
+ $httpBackend.whenJSONP(/authors/).passThrough();
+ }));
+ afterEach(function() {
+ $httpBackend.verifyNoOutstandingExpectation();
+ $httpBackend.verifyNoOutstandingRequest();
+ });
+
+ beforeEach(inject(function($rootScope, $controller){
+ scope = $rootScope.$new();
+ var ctrl = $controller(AuthorsCtrl, { $scope: scope } );
+ }));
+
+
+ it('ready', function() {
+ $httpBackend.flush();
+ expect( scope.ready ).toBe( true );
+ });
+
+ it('data', function() {
+ $httpBackend.flush();
+ expect( scope.data ).toBeTruthy();
+ });
+});