From ffbcf83b9505b5dd43698024abf25d89d62c213f Mon Sep 17 00:00:00 2001 From: Matt Blenkinsop Date: Thu, 15 Jun 2023 11:43:53 +0000 Subject: [PATCH] Bug 34587: Add default report capability to reports viewer Signed-off-by: Jessica Zairo Signed-off-by: Michaela Sieber Signed-off-by: Nick Clemens Signed-off-by: Tomas Cohen Arazi --- Koha/ERM/DefaultUsageReport.pm | 42 +++ Koha/ERM/DefaultUsageReports.pm | 52 ++++ Koha/REST/V1/ERM/DefaultUsageReports.pm | 225 +++++++++++++++ Koha/Schema/Result/ErmDefaultUsageReport.pm | 78 +++++ .../definitions/erm_default_usage_report.yaml | 18 ++ .../paths/erm_default_usage_reports.yaml | 266 ++++++++++++++++++ api/v1/swagger/swagger.yaml | 8 + .../erm_usage_statistics_tables.pl | 17 ++ installer/data/mysql/kohastructure.sql | 15 + .../ERM/UsageStatisticsReportBuilder.vue | 180 +++++++----- .../ERM/UsageStatisticsReportsHome.vue | 63 +---- .../ERM/UsageStatisticsSavedReports.vue | 82 ++++++ .../prog/js/vue/fetch/erm-api-client.js | 77 +++-- 13 files changed, 985 insertions(+), 138 deletions(-) create mode 100644 Koha/ERM/DefaultUsageReport.pm create mode 100644 Koha/ERM/DefaultUsageReports.pm create mode 100644 Koha/REST/V1/ERM/DefaultUsageReports.pm create mode 100644 Koha/Schema/Result/ErmDefaultUsageReport.pm create mode 100644 api/v1/swagger/definitions/erm_default_usage_report.yaml create mode 100644 api/v1/swagger/paths/erm_default_usage_reports.yaml create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/UsageStatisticsSavedReports.vue diff --git a/Koha/ERM/DefaultUsageReport.pm b/Koha/ERM/DefaultUsageReport.pm new file mode 100644 index 0000000000..2203e87cfa --- /dev/null +++ b/Koha/ERM/DefaultUsageReport.pm @@ -0,0 +1,42 @@ +package Koha::ERM::DefaultUsageReport; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use base qw(Koha::Object); + +=head1 NAME + +Koha::ERM::DefaultUsageReport - Koha ErmDefaultUsageReport Object class + +=head1 API + +=head2 Class Methods + +=cut + +=head2 Internal methods + +=head3 _type + +=cut + +sub _type { + return 'ErmDefaultUsageReport'; +} + +1; \ No newline at end of file diff --git a/Koha/ERM/DefaultUsageReports.pm b/Koha/ERM/DefaultUsageReports.pm new file mode 100644 index 0000000000..4dbab9156d --- /dev/null +++ b/Koha/ERM/DefaultUsageReports.pm @@ -0,0 +1,52 @@ +package Koha::ERM::DefaultUsageReports; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Koha::Database; + +use Koha::ERM::DefaultUsageReport; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::ERM::DefaultUsageReports- Koha ErmDefaultUsageReport Object set class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 type + +=cut + +sub _type { + return 'ErmDefaultUsageReport'; +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::ERM::DefaultUsageReport'; +} + +1; \ No newline at end of file diff --git a/Koha/REST/V1/ERM/DefaultUsageReports.pm b/Koha/REST/V1/ERM/DefaultUsageReports.pm new file mode 100644 index 0000000000..50554b9c60 --- /dev/null +++ b/Koha/REST/V1/ERM/DefaultUsageReports.pm @@ -0,0 +1,225 @@ +package Koha::REST::V1::ERM::DefaultUsageReports; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; + +use Koha::ERM::DefaultUsageReports; + +use Scalar::Util qw( blessed ); +use Try::Tiny qw( catch try ); + +=head1 API + +=head2 Methods + +=head3 list + +=cut + +sub list { + my $c = shift->openapi->valid_input or return; + + return try { + my $default_usage_report_set = Koha::ERM::DefaultUsageReports->new; + my $default_usage_report = + $c->objects->search($default_usage_report_set); + return $c->render( status => 200, openapi => $default_usage_report ); + } + catch { + $c->unhandled_exception($_); + }; + +} + +=head3 add + +Controller function that handles adding a new Koha::ERM::DefaultUsageReport object + +=cut + +sub add { + my $c = shift->openapi->valid_input or return; + + return try { + Koha::Database->new->schema->txn_do( + sub { + + my $body = $c->validation->param('body'); + + my $default_report = + Koha::ERM::DefaultUsageReport->new_from_api($body)->store; + + $c->res->headers->location( $c->req->url->to_string . '/' + . $default_report->erm_default_usage_report_id ); + return $c->render( + status => 201, + openapi => $default_report->to_api + ); + } + ); + } + catch { + + my $to_api_mapping = Koha::ERM::DefaultUsageReport->new->to_api_mapping; + + if ( blessed $_ ) { + if ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) { + return $c->render( + status => 409, + openapi => + { error => $_->error, conflict => $_->duplicate_id } + ); + } + elsif ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->broken_fk } + . " does not exist" + } + ); + } + elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->parameter } + . " does not exist" + } + ); + } + elsif ( $_->isa('Koha::Exceptions::PayloadTooLarge') ) { + return $c->render( + status => 413, + openapi => { error => $_->error } + ); + } + } + + $c->unhandled_exception($_); + }; +} + +=head3 update + +Controller function that handles updating a Koha::ERM::DefaultUsageReport object + +=cut + +sub update { + my $c = shift->openapi->valid_input or return; + + my $default_report_id = + $c->validation->param('erm_default_usage_report_id'); + my $default_report = + Koha::ERM::DefaultUsageReports->find($default_report_id); + + unless ($default_report) { + return $c->render( + status => 404, + openapi => { error => "Default report not found" } + ); + } + + return try { + Koha::Database->new->schema->txn_do( + sub { + + my $body = $c->validation->param('body'); + + $default_report->set_from_api($body)->store; + + $c->res->headers->location( $c->req->url->to_string . '/' + . $default_report->erm_default_usage_report_id ); + return $c->render( + status => 200, + openapi => $default_report->to_api + ); + } + ); + } + catch { + my $to_api_mapping = Koha::ERM::DefaultUsageReport->new->to_api_mapping; + + if ( blessed $_ ) { + if ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->broken_fk } + . " does not exist" + } + ); + } + elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->parameter } + . " does not exist" + } + ); + } + elsif ( $_->isa('Koha::Exceptions::PayloadTooLarge') ) { + return $c->render( + status => 413, + openapi => { error => $_->error } + ); + } + } + + $c->unhandled_exception($_); + }; +} + +=head3 delete + +=cut + +sub delete { + my $c = shift->openapi->valid_input or return; + + my $default_report_id = + $c->validation->param('erm_default_usage_report_id'); + my $default_report = + Koha::ERM::DefaultUsageReports->find($default_report_id); + unless ($default_report) { + return $c->render( + status => 404, + openapi => { error => "Default report not found" } + ); + } + + return try { + $default_report->delete; + return $c->render( + status => 204, + openapi => q{} + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +1; diff --git a/Koha/Schema/Result/ErmDefaultUsageReport.pm b/Koha/Schema/Result/ErmDefaultUsageReport.pm new file mode 100644 index 0000000000..df82587491 --- /dev/null +++ b/Koha/Schema/Result/ErmDefaultUsageReport.pm @@ -0,0 +1,78 @@ +use utf8; +package Koha::Schema::Result::ErmDefaultUsageReport; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +=head1 NAME + +Koha::Schema::Result::ErmDefaultUsageReport + +=cut + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +=head1 TABLE: C + +=cut + +__PACKAGE__->table("erm_default_usage_reports"); + +=head1 ACCESSORS + +=head2 erm_default_usage_report_id + + data_type: 'integer' + is_auto_increment: 1 + is_nullable: 0 + +primary key + +=head2 report_name + + data_type: 'varchar' + is_nullable: 1 + size: 50 + +name of the default report + +=head2 report_url_params + + data_type: 'longtext' + is_nullable: 1 + +url params for the default report + +=cut + +__PACKAGE__->add_columns( + "erm_default_usage_report_id", + { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, + "report_name", + { data_type => "varchar", is_nullable => 1, size => 50 }, + "report_url_params", + { data_type => "longtext", is_nullable => 1 }, +); + +=head1 PRIMARY KEY + +=over 4 + +=item * L + +=back + +=cut + +__PACKAGE__->set_primary_key("erm_default_usage_report_id"); + + +# Created by DBIx::Class::Schema::Loader v0.07049 @ 2023-06-15 10:27:53 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:rA1k44Zr273CfmPirG8RMA + + +# You can replace this text with custom code or comments, and it will be preserved on regeneration +1; diff --git a/api/v1/swagger/definitions/erm_default_usage_report.yaml b/api/v1/swagger/definitions/erm_default_usage_report.yaml new file mode 100644 index 0000000000..657421e827 --- /dev/null +++ b/api/v1/swagger/definitions/erm_default_usage_report.yaml @@ -0,0 +1,18 @@ +--- +type: object +properties: + erm_default_usage_report_id: + type: integer + description: internally assigned default_usage_report identifier + readOnly: true + report_name: + description: report_name + type: string + report_url_params: + description: report_url_params + type: string + +additionalProperties: false +required: + - report_name + - report_url_params \ No newline at end of file diff --git a/api/v1/swagger/paths/erm_default_usage_reports.yaml b/api/v1/swagger/paths/erm_default_usage_reports.yaml new file mode 100644 index 0000000000..ec8bd366e9 --- /dev/null +++ b/api/v1/swagger/paths/erm_default_usage_reports.yaml @@ -0,0 +1,266 @@ +--- +/erm/default_usage_reports: + get: + x-mojo-to: ERM::DefaultUsageReports#list + operationId: listErmDefaultUsageReports + tags: + - default_usage_report + summary: List default_usage_reports + produces: + - application/json + parameters: + - description: Case insensitive search on erm_default_usage_report_id + in: query + name: erm_default_usage_report_id + required: false + type: integer + - description: Case insensitive search on default_usage_report report_name + in: query + name: report_name + required: false + type: integer + - description: Case insensitive search on default_usage_report report_url_params + in: query + name: report_url_params + required: false + type: integer + - $ref: "../swagger.yaml#/parameters/match" + - $ref: "../swagger.yaml#/parameters/order_by" + - $ref: "../swagger.yaml#/parameters/page" + - $ref: "../swagger.yaml#/parameters/per_page" + - $ref: "../swagger.yaml#/parameters/q_param" + - $ref: "../swagger.yaml#/parameters/q_body" + - $ref: "../swagger.yaml#/parameters/q_header" + responses: + 200: + description: A list of default_usage_reports + schema: + items: + $ref: "../swagger.yaml#/definitions/erm_default_usage_report" + type: array + 400: + description: Bad request + schema: + $ref: "../swagger.yaml#/definitions/error" + 403: + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + 500: + description: |- + Internal server error. Possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + 503: + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + erm: 1 + post: + x-mojo-to: ERM::DefaultUsageReports#add + operationId: addErmDefaultUsageReports + tags: + - default_usage_report + summary: Add default_usage_report + consumes: + - application/json + produces: + - application/json + parameters: + - description: A JSON object containing information about the new default_usage_report + in: body + name: body + required: true + schema: + $ref: "../swagger.yaml#/definitions/erm_default_usage_report" + responses: + 201: + description: A successfully created default_usage_report + schema: + items: + $ref: "../swagger.yaml#/definitions/erm_default_usage_report" + 400: + description: Bad parameter + schema: + $ref: "../swagger.yaml#/definitions/error" + 401: + description: Authentication required + schema: + $ref: "../swagger.yaml#/definitions/error" + 403: + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + 404: + description: Ressource not found + schema: + $ref: "../swagger.yaml#/definitions/error" + 409: + description: Conflict in creating resource + schema: + $ref: "../swagger.yaml#/definitions/error" + 413: + description: Payload too large + schema: + $ref: "../swagger.yaml#/definitions/error" + 500: + description: |- + Internal server error. Possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + 503: + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + erm: 1 +"/erm/default_usage_reports/{erm_default_usage_report_id}": + get: + x-mojo-to: ERM::DefaultUsageReports#get + operationId: getERMDefaultUsageReport + tags: + - default_usage_report + summary: get default_usage_report + produces: + - application/json + parameters: + - $ref: "../swagger.yaml#/parameters/erm_default_usage_report_id_pp" + responses: + 200: + description: default_usage_report + schema: + items: + $ref: "../swagger.yaml#/definitions/erm_default_usage_report" + 401: + description: authentication required + schema: + $ref: "../swagger.yaml#/definitions/error" + 403: + description: access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + 404: + description: ressource not found + schema: + $ref: "../swagger.yaml#/definitions/error" + 500: + description: |- + internal server error. possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + 503: + description: under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + erm: 1 + put: + x-mojo-to: ERM::DefaultUsageReports#update + operationId: updateERMDefaultUsageReports + tags: + - default_usage_report + summary: update default_usage_report + consumes: + - application/json + produces: + - application/json + parameters: + - $ref: "../swagger.yaml#/parameters/erm_default_usage_report_id_pp" + - name: body + in: body + description: a json object containing new information about existing default_usage_report + required: true + schema: + $ref: "../swagger.yaml#/definitions/erm_default_usage_report" + responses: + 200: + description: a successfully updated default_usage_report + schema: + items: + $ref: "../swagger.yaml#/definitions/erm_default_usage_report" + 400: + description: bad parameter + schema: + $ref: "../swagger.yaml#/definitions/error" + 403: + description: access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + 404: + description: ressource not found + schema: + $ref: "../swagger.yaml#/definitions/error" + 409: + description: conflict in updating resource + schema: + $ref: "../swagger.yaml#/definitions/error" + 413: + description: Payload too large + schema: + $ref: "../swagger.yaml#/definitions/error" + 500: + description: |- + internal server error. possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + 503: + description: under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + erm: 1 + delete: + x-mojo-to: ERM::DefaultUsageReports#delete + operationId: deleteERMDefaultUsageReports + tags: + - default_usage_report + summary: Delete default_usage_report + produces: + - application/json + parameters: + - $ref: "../swagger.yaml#/parameters/erm_default_usage_report_id_pp" + responses: + 204: + description: default_usage_report deleted + 400: + description: default_usage_report deletion failed + schema: + $ref: "../swagger.yaml#/definitions/error" + 401: + description: authentication required + schema: + $ref: "../swagger.yaml#/definitions/error" + 403: + description: access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + 404: + description: ressource not found + schema: + $ref: "../swagger.yaml#/definitions/error" + 409: + description: conflict in deleting resource + schema: + $ref: "../swagger.yaml#/definitions/error" + 500: + description: |- + internal server error. possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + 503: + description: under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + erm: 1 \ No newline at end of file diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml index 7b88e50f8b..8625f1e8a6 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -44,6 +44,8 @@ definitions: $ref: ./definitions/erm_counter_file.yaml erm_counter_log: $ref: ./definitions/erm_counter_log.yaml + erm_default_usage_report: + $ref: ./definitions/erm_default_usage_report.yaml erm_eholdings_title: $ref: ./definitions/erm_eholdings_title.yaml erm_eholdings_package: @@ -599,6 +601,12 @@ parameters: name: erm_counter_log_id required: true type: integer + erm_default_usage_report_id_pp: + description: ERM default_usage_report internal identifier + in: path + name: erm_default_usage_report_id + required: true + type: integer erm_usage_data_provider_id_pp: description: ERM usage_data_provider internal identifier in: path diff --git a/installer/data/mysql/atomicupdate/erm_usage_statistics_tables.pl b/installer/data/mysql/atomicupdate/erm_usage_statistics_tables.pl index 255294249d..325931ed63 100644 --- a/installer/data/mysql/atomicupdate/erm_usage_statistics_tables.pl +++ b/installer/data/mysql/atomicupdate/erm_usage_statistics_tables.pl @@ -226,6 +226,23 @@ return { } else { say $out "erm_usage_yus table already exists - skipping to next table"; } + + unless( TableExists( 'erm_default_usage_reports')) { + $dbh->do( + q{ + CREATE TABLE `erm_default_usage_reports` ( + `erm_default_usage_report_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key', + `report_name` varchar(50) DEFAULT NULL COMMENT 'name of the default report', + `report_url_params` longtext DEFAULT NULL COMMENT 'url params for the default report', + PRIMARY KEY (`erm_default_usage_report_id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + } + ); + + say $out "Added new table erm_default_usage_reports"; + } else { + say $out "erm_default_usage_reports table already exists - skipping to next table"; + } $dbh->do(q{ INSERT IGNORE INTO authorised_value_categories (category_name, is_system) diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 83cb89387a..d834bd8408 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -3181,6 +3181,21 @@ CREATE TABLE `erm_usage_mus` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `erm_default_usage_reports` +-- + +DROP TABLE IF EXISTS `erm_default_usage_reports`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `erm_default_usage_reports` ( + `erm_default_usage_report_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key', + `report_name` varchar(50) DEFAULT NULL COMMENT 'name of the default report', + `report_url_params` longtext DEFAULT NULL COMMENT 'url params for the default report', + PRIMARY KEY (`erm_default_usage_report_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `erm_usage_titles` -- diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/UsageStatisticsReportBuilder.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/UsageStatisticsReportBuilder.vue index 8c972c8551..7495f3b0f8 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/UsageStatisticsReportBuilder.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/UsageStatisticsReportBuilder.vue @@ -268,13 +268,24 @@
-
+
+ + +
@@ -468,6 +479,7 @@ export default { usage_data_provider_list: [...this.usage_data_providers], time_period_columns_builder: null, request_url: null, + report_name: "", } }, methods: { @@ -525,68 +537,7 @@ export default { buildCustomReport(e) { e.preventDefault() - const queryObject = this.query - const { - start_year, - end_year, - data_display, - report_type, - metric_types, - } = queryObject - - if (!report_type || !start_year || !end_year) { - alert( - "You have not filled in all the required fields, please try again" - ) - return - } - - // validate if the year is a valid string - const valid_start_year = this.validateYear(start_year) - const valid_end_year = this.validateYear(end_year) - - if (!valid_start_year || !valid_end_year) { - this.setError( - this.$__("Please enter a year with the format YYYY") - ) - return - } - - // If no metric types are selected then all possible values should be included for backend data filtering - if (!metric_types || (metric_types && metric_types.length === 0)) { - const final_metric_types = this.metric_types_options.map( - metric => { - return metric.value - } - ) - queryObject.metric_types = final_metric_types - } - - const metric_report_type = - data_display === "metric_type" ? true : false - const url = !data_display.includes("yearly") - ? this.buildMonthlyUrlQuery( - queryObject, - this.time_period_columns_builder, - metric_report_type - ) - : this.buildYearlyUrlQuery(queryObject) - const type = data_display - const columns = this.defineColumns( - this.title_property_column_options - ) - const yearly_filter = data_display.includes("monthly") - ? this.yearly_filter_required - : false - - const urlParams = { - url, - columns, - queryObject, - yearly_filter, - type, - tp_columns: this.time_period_columns_builder, - } + const urlParams = this.validateFormAndCreateUrlParams() this.$router.push({ name: "UsageStatisticsReportsViewer", @@ -879,6 +830,93 @@ export default { return columns }, + async saveToDefaultReports(e) { + e.preventDefault() + + if (!this.report_name) { + alert("Please provide a report name") + return + } + const params = this.validateFormAndCreateUrlParams() + const report = { + report_name: this.report_name, + report_url_params: JSON.stringify(params), + } + + const client = APIClient.erm + await client.default_usage_reports.create(report).then( + success => { + this.setMessage(this.$__("Report saved successfully")) + }, + error => {} + ) + }, + validateFormAndCreateUrlParams() { + const queryObject = { ...this.query } + const { + start_year, + end_year, + data_display, + report_type, + metric_types, + } = queryObject + + if (!report_type || !start_year || !end_year) { + alert( + "You have not filled in all the required fields, please try again" + ) + return + } + + // validate if the year is a valid string + const valid_start_year = this.validateYear(start_year) + const valid_end_year = this.validateYear(end_year) + + if (!valid_start_year || !valid_end_year) { + this.setError( + this.$__("Please enter a year with the format YYYY") + ) + return + } + + // If no metric types are selected then all possible values should be included for backend data filtering + if (!metric_types || (metric_types && metric_types.length === 0)) { + const final_metric_types = this.metric_types_options.map( + metric => { + return metric.value + } + ) + queryObject.metric_types = final_metric_types + } + + const metric_report_type = + data_display === "metric_type" ? true : false + const url = !data_display.includes("yearly") + ? this.buildMonthlyUrlQuery( + queryObject, + this.time_period_columns_builder, + metric_report_type + ) + : this.buildYearlyUrlQuery(queryObject) + const type = data_display + const columns = this.defineColumns( + this.title_property_column_options + ) + const yearly_filter = data_display.includes("monthly") + ? this.yearly_filter_required + : false + + const urlParams = { + url, + columns, + queryObject, + yearly_filter, + type, + tp_columns: this.time_period_columns_builder, + } + + return urlParams + }, }, props: ["usage_data_providers"], components: { @@ -939,5 +977,15 @@ input:not([type="submit"]):not([type="search"]):not([type="button"]):not([type=" } .year_input { width: 30%; + min-height: 2em; +} +.button_format { + padding: 0.5em 1em; + margin-left: 0.5em; +} +.save_report { + display: flex; + gap: 0.5em; + margin-top: 1em; } diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/UsageStatisticsReportsHome.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/UsageStatisticsReportsHome.vue index e205ddb743..0939a36be9 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/UsageStatisticsReportsHome.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/UsageStatisticsReportsHome.vue @@ -15,7 +15,7 @@ role="tab" data-content="default" @click="changeCustomOrDefault" - >DefaultSaved reports
  • CustomCreate report
  • -
    -

    {{ $__("Select default report") }}

    -
    -
      -
    1. - - -
    2. -
    -
    -
    - -
    -
    +
    +
    {{ $__("Loading") }}
    +
    +
    + {{ + $__( + "You have not saved any reports yet, please create a report." + ) + }} +
    +
    +

    {{ $__("Select saved report") }}

    +
    +
      +
    1. + + +
    2. +
    +
    +
    + +
    +
    +
    + + + + + diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm-api-client.js index d0ec02ce42..6fec7cbf71 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm-api-client.js +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm-api-client.js @@ -253,20 +253,20 @@ export class ERMAPIClient extends HttpClient { get usage_data_providers() { return { - get: (id) => + get: id => this.get({ endpoint: "usage_data_providers/" + id, }), - getAll: (query) => + getAll: query => this.get({ endpoint: "usage_data_providers", - query + query, }), - delete: (id) => + delete: id => this.delete({ endpoint: "usage_data_providers/" + id, }), - create: (usage_data_provider) => + create: usage_data_provider => this.post({ endpoint: "usage_data_providers", body: usage_data_provider, @@ -278,38 +278,51 @@ export class ERMAPIClient extends HttpClient { }), run: (id, begin_date, end_date) => this.get({ - endpoint: "usage_data_providers/" + id + "/run?begin_date="+ begin_date + "&end_date=" + end_date, + endpoint: + "usage_data_providers/" + + id + + "/run?begin_date=" + + begin_date + + "&end_date=" + + end_date, }), - test: (id) => + test: id => this.get({ endpoint: "usage_data_providers/" + id + "/test_connection", }), - //count: () => this.count("usage_data_providers"), //TODO: Implement count method + count: (query = {}) => + this.count({ + endpoint: + "usage_data_providers?" + + new URLSearchParams({ + _page: 1, + _per_page: 1, + ...(query && { q: JSON.stringify(query) }), + }), + }), }; } get usage_titles() { return { - get: (id) => + get: id => this.get({ endpoint: "usage_titles/" + id, headers: { - "x-koha-embed": - "usage_mus", + "x-koha-embed": "usage_mus", }, }), - getAll: (query) => + getAll: query => this.getAll({ endpoint: "usage_titles", - query + query, }), getReport: (query, embed) => this.get({ endpoint: "usage_titles/report", query, headers: { - "x-koha-embed": - `${embed}`, + "x-koha-embed": `${embed}`, }, }), count: (query = {}) => @@ -327,19 +340,43 @@ export class ERMAPIClient extends HttpClient { get counter_files() { return { - getAll: (query) => + getAll: query => this.get({ endpoint: "counter_files", query, headers: { - "x-koha-embed": - "counter_logs", - } + "x-koha-embed": "counter_logs", + }, }), - delete: (id) => + delete: id => this.delete({ endpoint: "counter_files/" + id, }), + count: (query = {}) => + this.count({ + endpoint: + "counter_files?" + + new URLSearchParams({ + _page: 1, + _per_page: 1, + ...(query && { q: JSON.stringify(query) }), + }), + }), + }; + } + + get default_usage_reports() { + return { + getAll: query => + this.get({ + endpoint: "default_usage_reports", + query, + }), + create: default_usage_report => + this.post({ + endpoint: "default_usage_reports", + body: default_usage_report, + }), }; } }