From c4413195d89d5bf6b3814e0adff7b8447e562e1b Mon Sep 17 00:00:00 2001 From: Juraj Roka <95219754+jr-rk@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:50:27 +0200 Subject: [PATCH 1/4] Implemented configurable showing of component --- .../total-downloads.component.html | 4 +- .../file-section/total-downloads.component.ts | 56 ++++++++++++++++--- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/app/item-page/simple/field-components/file-section/total-downloads.component.html b/src/app/item-page/simple/field-components/file-section/total-downloads.component.html index 72db7109aa0..5b2d9bbb117 100644 --- a/src/app/item-page/simple/field-components/file-section/total-downloads.component.html +++ b/src/app/item-page/simple/field-components/file-section/total-downloads.component.html @@ -1,4 +1,6 @@ - +
{{ totalDownloads }} diff --git a/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts b/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts index d5cc17cbd08..68acac55fd5 100644 --- a/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts +++ b/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, Input } from '@angular/core'; import { UsageReportDataService } from 'src/app/core/statistics/usage-report-data.service'; +import { ConfigurationDataService } from 'src/app/core/data/configuration-data.service'; import { catchError } from 'rxjs/operators'; -import { of } from 'rxjs'; +import { BehaviorSubject, of } from 'rxjs'; /** * Component that displays the total number of downloads for all bitstreams within a DSpace item. @@ -26,7 +27,13 @@ export class TotalDownloadsComponent implements OnInit { * The total number of downloads across all bitstreams for the item. * Defaults to 0 and will show 0 if no data is available or an error occurs. */ - totalDownloads: number = 0; + totalDownloads = 0; + + /** + * Flag indicating whether the total downloads feature is enabled in the configuration. + * Defaults to false to hide downloads unless explicitly enabled in configuration. + */ + totalDownloadsEnabled = new BehaviorSubject(false); /** * The translation key for the downloadsLabel displayed alongside the download count. @@ -34,15 +41,20 @@ export class TotalDownloadsComponent implements OnInit { readonly downloadsLabel = 'item.page.files.downloads'; - constructor(private usageReportDataService: UsageReportDataService) { } + constructor( + private usageReportDataService: UsageReportDataService, + private configService: ConfigurationDataService + ) { } /** - * Fetches the total download statistics for the item specified by itemUuid. + * Fetches the configuration to check if total downloads should be shown, + * and if enabled, fetches the total download statistics for the item specified by itemUuid. * The component will: - * 1. Call the UsageReportDataService with the item UUID and 'TotalDownloads' report type - * 2. Aggregate all download counts (views) from all bitstreams in the response - * 3. Set the totalDownloads property with the sum - * 4. Handle errors gracefully by setting totalDownloads to 0 and logging the error + * 1. Check the 'item.view.total.downloads.enabled' configuration property + * 2. If enabled (or config not found - defaults to true), call the UsageReportDataService + * 3. Aggregate all download counts (views) from all bitstreams in the response + * 4. Set the totalDownloads property with the sum + * 5. Handle errors gracefully by setting totalDownloads to 0 and logging the error * * @throws Will log an error to console if the API call fails, but won't throw an exception */ @@ -51,6 +63,34 @@ export class TotalDownloadsComponent implements OnInit { return; } + // First, check if total downloads feature is enabled in configuration + this.configService.findByPropertyName('item.view.total.downloads.enabled') + .pipe( + catchError(error => { + console.error('Failed to fetch total downloads configuration:', error); + // Default to true if configuration cannot be retrieved + return of(null); + }) + ) + .subscribe(configData => { + // Extract configuration value, default to 'true' if not found + const itemViewTotalDownloadsEnabled = configData?.payload?.values?.[0]; + this.totalDownloadsEnabled.next(itemViewTotalDownloadsEnabled === 'true'); + + // Only fetch download statistics if the feature is enabled + if (this.totalDownloadsEnabled) { + this.fetchDownloadStatistics(); + } else { + this.totalDownloads = 0; // Ensure it's 0 when disabled + } + }); + } + + /** + * Private method to fetch download statistics from the usage report service. + * This method is called only when the total downloads feature is enabled. + */ + private fetchDownloadStatistics(): void { const reportType = 'TotalDownloads'; this.usageReportDataService.getStatistic(this.itemUuid, reportType) .pipe( From 7f7919b00b8989e1b027d1bf65471106de4c5071 Mon Sep 17 00:00:00 2001 From: Juraj Roka <95219754+jr-rk@users.noreply.github.com> Date: Thu, 18 Sep 2025 15:59:40 +0200 Subject: [PATCH 2/4] Refactored by Copilot's suggestions --- .../file-section/total-downloads.component.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts b/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts index 68acac55fd5..29d3bb9ac7a 100644 --- a/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts +++ b/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts @@ -51,7 +51,8 @@ export class TotalDownloadsComponent implements OnInit { * and if enabled, fetches the total download statistics for the item specified by itemUuid. * The component will: * 1. Check the 'item.view.total.downloads.enabled' configuration property - * 2. If enabled (or config not found - defaults to true), call the UsageReportDataService + * 2. If enabled (configuration value is 'true'), call the UsageReportDataService, + * if config is not found, defaults to false * 3. Aggregate all download counts (views) from all bitstreams in the response * 4. Set the totalDownloads property with the sum * 5. Handle errors gracefully by setting totalDownloads to 0 and logging the error @@ -78,7 +79,7 @@ export class TotalDownloadsComponent implements OnInit { this.totalDownloadsEnabled.next(itemViewTotalDownloadsEnabled === 'true'); // Only fetch download statistics if the feature is enabled - if (this.totalDownloadsEnabled) { + if (this.totalDownloadsEnabled.value) { this.fetchDownloadStatistics(); } else { this.totalDownloads = 0; // Ensure it's 0 when disabled From b5eb30b14e4ba22a75c94fc876d3c484d32efa90 Mon Sep 17 00:00:00 2001 From: Juraj Roka <95219754+jr-rk@users.noreply.github.com> Date: Thu, 18 Sep 2025 16:39:44 +0200 Subject: [PATCH 3/4] Refactored by Milan's suggestions --- .../file-section/total-downloads.component.ts | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts b/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts index 29d3bb9ac7a..f0797292e97 100644 --- a/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts +++ b/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts @@ -7,9 +7,12 @@ import { BehaviorSubject, of } from 'rxjs'; /** * Component that displays the total number of downloads for all bitstreams within a DSpace item. * - * This component fetches download statistics for a given item using its UUID and aggregates - * the download counts from all bitstreams associated with that item. The result is displayed - * as a single total download count. + * This component checks the 'item.view.total.downloads.enabled' configuration property + * to determine if download statistics should be displayed. If enabled, it fetches download + * statistics for a given item using its UUID and aggregates the download counts from all + * bitstreams associated with that item. The result is displayed as a single total download count. + * + * If the configuration is disabled or set to 'false', the component will not be displayed. */ @Component({ selector: 'ds-total-downloads', @@ -31,7 +34,8 @@ export class TotalDownloadsComponent implements OnInit { /** * Flag indicating whether the total downloads feature is enabled in the configuration. - * Defaults to false to hide downloads unless explicitly enabled in configuration. + * Uses BehaviorSubject to allow reactive updates. Defaults to false and will only be + * set to true if the configuration explicitly contains 'true' value. */ totalDownloadsEnabled = new BehaviorSubject(false); @@ -51,11 +55,11 @@ export class TotalDownloadsComponent implements OnInit { * and if enabled, fetches the total download statistics for the item specified by itemUuid. * The component will: * 1. Check the 'item.view.total.downloads.enabled' configuration property - * 2. If enabled (configuration value is 'true'), call the UsageReportDataService, - * if config is not found, defaults to false + * 2. If enabled (configuration value is explicitly 'true'), call the UsageReportDataService + * If configuration is not found or fails to load, defaults to false (disabled) * 3. Aggregate all download counts (views) from all bitstreams in the response * 4. Set the totalDownloads property with the sum - * 5. Handle errors gracefully by setting totalDownloads to 0 and logging the error + * 5. Handle errors gracefully by returning null and logging the error * * @throws Will log an error to console if the API call fails, but won't throw an exception */ @@ -69,12 +73,12 @@ export class TotalDownloadsComponent implements OnInit { .pipe( catchError(error => { console.error('Failed to fetch total downloads configuration:', error); - // Default to true if configuration cannot be retrieved + // Default to false if configuration cannot be retrieved return of(null); }) ) .subscribe(configData => { - // Extract configuration value, default to 'true' if not found + // Extract configuration value, default to 'false' if not found const itemViewTotalDownloadsEnabled = configData?.payload?.values?.[0]; this.totalDownloadsEnabled.next(itemViewTotalDownloadsEnabled === 'true'); @@ -82,7 +86,7 @@ export class TotalDownloadsComponent implements OnInit { if (this.totalDownloadsEnabled.value) { this.fetchDownloadStatistics(); } else { - this.totalDownloads = 0; // Ensure it's 0 when disabled + this.totalDownloads = null; // Ensure it's null when disabled } }); } From c87aa06506bfe15063e30bd0569dc4ad7060d3d8 Mon Sep 17 00:00:00 2001 From: Juraj Roka <95219754+jr-rk@users.noreply.github.com> Date: Thu, 18 Sep 2025 16:43:00 +0200 Subject: [PATCH 4/4] Refactored by Copilot's suggestions - extended type of totalDownloads to null --- .../field-components/file-section/total-downloads.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts b/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts index f0797292e97..25f3d2119c0 100644 --- a/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts +++ b/src/app/item-page/simple/field-components/file-section/total-downloads.component.ts @@ -30,7 +30,7 @@ export class TotalDownloadsComponent implements OnInit { * The total number of downloads across all bitstreams for the item. * Defaults to 0 and will show 0 if no data is available or an error occurs. */ - totalDownloads = 0; + totalDownloads: number | null = 0; /** * Flag indicating whether the total downloads feature is enabled in the configuration.