Skip to content

Commit

Permalink
statistics: add report list
Browse files Browse the repository at this point in the history
* Adds menu entry with default filters.
* Adds indicator to the stat config brief view.
* Replaces the organisation by library.
* Adds facets to the stat config search view.
* Adds updated and created date.
* Adds filter by libraries.
* Adds live values.
* Adds report list.
* Exposes settings service into the route tools service.
* Fixes delete messsages by adding missing resources in the record permission service.

Co-Authored-by: Johnny Mariéthoz <[email protected]>
  • Loading branch information
jma committed Nov 21, 2023
1 parent e53ecd1 commit aaf3d9a
Show file tree
Hide file tree
Showing 12 changed files with 795 additions and 367 deletions.
481 changes: 244 additions & 237 deletions projects/admin/src/app/app.module.ts

Large diffs are not rendered by default.

22 changes: 13 additions & 9 deletions projects/admin/src/app/menu/menu-definition/menu-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,19 @@ export const MENU_APP: IMenuParent[] = [
access: {
permissions: [PERMISSIONS.PTTR_ACCESS]
}
},
{
name: "Report Configuration",
router_link: ["/", "records", "stats_cfg"],
attributes: { id: "stats-cfg-menu" },
extras: { iconClass: "fa fa-cog" },
query_params: {
library: "$currentLibrary",
active: "true",
},
access: {
permissions: [PERMISSIONS.STAT_CFG_ACCESS],
},
}
]
},
Expand Down Expand Up @@ -287,15 +300,6 @@ export const MENU_APP: IMenuParent[] = [
permissions: [PERMISSIONS.TMPL_ACCESS]
}
},
{
name: 'Statistics configuration',
router_link: ['/', 'records', 'stats_cfg'],
attributes: { id: 'stats-cfg-menu' },
extras: { iconClass: 'fa fa-cog' },
access: {
permissions: [PERMISSIONS.STAT_CFG_ACCESS]
}
},
{
name: 'Permissions matrix',
router_link: ['/', 'permissions', 'matrix'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ import { ResultItem } from '@rero/ng-core';
<div>
<b translate>Category</b>: {{ record.metadata.category.type | translate }}
</div>
<div>
<b translate>Indicator</b>: {{ record.metadata.category.indicator.type | translate }}
</div>
</div>
`
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!--
RERO ILS UI
Copyright (C) 2023 RERO
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->

<p-table *ngIf="data && data.length > 0; else noResult" [value]="data" [tableStyle]="{ 'min-width': '50rem' }">
<ng-template pTemplate="body" let-line>
<tr>
<td *ngFor="let value of line">{{ value }}</td>
</tr>
</ng-template>
</p-table>

<ng-template #noResult>
<p class="m-0 px-4 py-2 text-muted" translate>No result</p>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* RERO ILS UI
* Copyright (C) 2023 RERO
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { Component, Input } from "@angular/core";

@Component({
selector: "admin-report-data",
templateUrl: "./report-data.component.html",
})
export class ReportDataComponent {

// the report data to display
@Input() data: any;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!--
RERO ILS UI
Copyright (C) 2023 RERO
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->

<table *ngIf="reports?.length; else noResult" class="mt-4 table table-striped">
<tbody>
<tr *ngFor="let report of reports">
<th>
<a class="pl-2" target="_blank" [href]="getReportUrl(report.metadata.pid)">
{{ report.created | dateTranslate: 'longDate' }}
<i class="pl-1 fa fa-external-link"></i>
</a>
</th>
<td class="text-right">
<a class="btn btn-link btn-outline-primary" [href]="getReportUrl(report.metadata.pid)+'?format=csv'">
<i class="fa fa-download"></i>
</a>
</td>
</tr>
</tbody>
</table>
<ng-template #noResult>
<p class="m-0 px-4 py-2 text-muted" translate>No result</p>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* RERO ILS UI
* Copyright (C) 2023 RERO
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { Component, Input, OnInit } from "@angular/core";
import { ApiService, Record, RecordService } from "@rero/ng-core";
import { map } from "rxjs/operators";

@Component({
selector: "admin-reports-list",
templateUrl: "./reports-list.component.html",
})
export class ReportsListComponent implements OnInit {
// persistent identifier of the current stat report configuration
@Input() pid: any;

// list of the corresponding reports from elasticsearch
reports: Array<any>;

/**
* Constructor
* @param _recordService - RecordService
* @param _apiService - ApiService
*/
constructor(
private _recordService: RecordService,
private _apiService: ApiService
) {}

/**
* Get the report item URL
*
* @param pid - Persistent Identifier value.
* @returns the URL as string.
*/
getReportUrl(pid: string): string {
return `${this._apiService.getEndpointByType("stats")}/${pid}`;
}

/** OnInit hook */
ngOnInit(): void {
this._recordService
.getRecords("stats", `config.pid:${this.pid}`, 1, 100)
.pipe(
map((result: Record) =>
this._recordService.totalHits(result.hits.total) === 0
? []
: result.hits.hits
)
).subscribe((res: any) => (this.reports = res));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->

<ng-container *ngIf="record$ | async as record">
<ng-container *ngIf="record">
<header class="mb-2">
<h1>{{ record.metadata.name }}</h1>
<span [innerHTML]="record.metadata.description | nl2br"></span>
</header>
<section class="my-4">
<dl class="row mb-0">
<dt class="col-3 label-title" translate>Library</dt>
<dd class="col-9">{{ record.metadata.library.$ref | getRecord: 'libraries' : 'field' : 'name' | async }}</dd>

<dt class="col-3 label-title" translate>Is active</dt>
<dd class="col-9">
<i
Expand All @@ -31,12 +34,21 @@ <h1>{{ record.metadata.name }}</h1>
</dd>
<dt class="col-3 label-title" translate>Frequency</dt>
<dd class="col-9">{{ record.metadata.frequency | translate }}</dd>
<ng-container *ngIf="record.metadata.filter_by_libraries?.length > 0">
<dt class="col-3 label-title" translate>Filter numbers by libraries</dt>
<dd class="col-9">
<div *ngFor="let lib of record.metadata.filter_by_libraries">
{{ lib.$ref| getRecord: 'libraries' : 'field' : 'name' | async }}
</div>
</dd>
</ng-container>
</dl>

<div class="card mt-3">
<h5 class="card-header" translate>Configuration</h5>
<div class="card-body container">
<dl class="row mb-0">

<dt class="col-3 label-title" translate>Category</dt>
<dd class="col-9">{{ record.metadata.category.type | translate }}</dd>

Expand Down Expand Up @@ -64,8 +76,31 @@ <h5 class="card-header" translate>Configuration</h5>
<dt class="col-3 label-title" translate>Filter</dt>
<dd class="col-9">{{ record.metadata.category.indicator.filter }}</dd>
</ng-container>
<ng-container *ngIf="record.created">
<dt class="col-3 label-title" translate>Created at</dt>
<dd class="col-9">{{ record.created | dateTranslate: 'medium' }}</dd>
</ng-container>
<ng-container *ngIf="record.updated">
<dt class="col-3 label-title" translate>Updated at</dt>
<dd class="col-9">{{ record.updated | dateTranslate: 'medium' }}</dd>
</ng-container>
</dl>
</div>
</div>
</section>
<tabset>
<tab>
<ng-template tabHeading>
<span translate>Reports</span>
</ng-template>
<admin-reports-list [pid]="record.metadata.pid"></admin-reports-list>
</tab>
<tab (selectTab)="getLiveValues()">
<ng-template tabHeading>
{{ 'Live Values' | translate }}
</ng-template>
<admin-report-data *ngIf="liveData" [data]="liveData"></admin-report-data>
</tab>
</tabset>

</ng-container>
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,65 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component } from '@angular/core';
import { HttpClient } from "@angular/common/http";
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ApiService } from "@rero/ng-core";
import { DetailRecord } from '@rero/ng-core/lib/record/detail/view/detail-record';
import { Observable } from 'rxjs';
import { Observable, Subscription } from 'rxjs';

@Component({
selector: 'admin-statitics-cfg-view',
templateUrl: './statistics-cfg-detail-view.component.html'
selector: "admin-statitics-cfg-view",
templateUrl: "./statistics-cfg-detail-view.component.html",
})
export class StatisticsCfgDetailViewComponent implements DetailRecord {
export class StatisticsCfgDetailViewComponent
implements DetailRecord, OnInit, OnDestroy
{

/** Observable resolving record data */
record$: Observable<any>;

/** Resource type */
type: string;

/** the api response record */
record: any;

// the current preview values
liveData: any = null;

/** Subscription to (un)follow the record$ Observable */
private _subscriptions = new Subscription();

/**
* Constructor
*
* @param _http - HttpClient
* @param _apiService = ApiService
*/
constructor(private _http: HttpClient, private _apiService: ApiService) {}

/** OnInit hook */
ngOnInit() {
this._subscriptions = this.record$.subscribe((record) => {
this.record = record;
});
}

/** onDestroy hook */
ngOnDestroy(): void {
this._subscriptions.unsubscribe();
}

/** Preview values corresponding to the current configuration. */
getLiveValues(): void {
// only once
if (this.liveData != null) {
return;
}
const pid = this.record.metadata.pid;
const baseUrl = this._apiService.endpointPrefix;
this._http
.get(`${baseUrl}/stats_cfg/live/${pid}`)
.subscribe((res) => (this.liveData = res));
}
}
Loading

0 comments on commit aaf3d9a

Please sign in to comment.