diff --git a/src/app/core/metadata/metadata-bitstream.model.ts b/src/app/core/metadata/metadata-bitstream.model.ts
index c5eed0594a4..5d89c0a2a85 100644
--- a/src/app/core/metadata/metadata-bitstream.model.ts
+++ b/src/app/core/metadata/metadata-bitstream.model.ts
@@ -80,6 +80,20 @@ export class MetadataBitstream extends ListableObject implements HALResource {
@autoserialize
canPreview: boolean;
+ /**
+ * The access status of this bitstream (e.g. "open.access", "embargo", "restricted").
+ * Unlike the standard Bitstream HAL resource, this endpoint embeds the status directly
+ * rather than exposing it via a resolvable accessStatus link.
+ */
+ @autoserialize
+ status: string;
+
+ /**
+ * The date this bitstream's embargo lifts. Only set when status is "embargo".
+ */
+ @autoserialize
+ embargoDate: string;
+
/**
* The {@link HALLink}s for this MetadataField
*/
diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html
index 4d4e95b0b49..5e2f5abe13a 100644
--- a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html
+++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html
@@ -8,7 +8,13 @@
- {{'item.file.description.name' | translate}}
-
- {{ fileInput.name }}
+
+
+ {{ fileInput.name }}
+
+ {{ 'embargo.listelement.badge' | translate: { date: fileInput.embargoDate } }}
+
+ {{ fileInput.name }}
- {{'item.file.description.size' | translate}}
-
diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.spec.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.spec.ts
index 19cd1bf778f..210dca9999c 100644
--- a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.spec.ts
+++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.spec.ts
@@ -12,6 +12,7 @@ import { RouterTestingModule } from '@angular/router/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HALEndpointService } from '../../../../../core/shared/hal-endpoint.service';
import { FileSizePipe } from '../../../../../shared/utils/file-size-pipe';
+import { environment } from '../../../../../../environments/environment';
describe('FileDescriptionComponent', () => {
let component: FileDescriptionComponent;
@@ -47,11 +48,7 @@ describe('FileDescriptionComponent', () => {
}).compileComponents();
});
- beforeEach(() => {
- fixture = TestBed.createComponent(FileDescriptionComponent);
- component = fixture.componentInstance;
-
- // Mock the input value
+ function createFileInput(overrides: Partial = {}): MetadataBitstream {
const fileInput = new MetadataBitstream();
fileInput.id = 123;
fileInput.name = 'testFile';
@@ -66,20 +63,86 @@ describe('FileDescriptionComponent', () => {
self: { href: '' },
schema: { href: '' },
};
+ return Object.assign(fileInput, overrides);
+ }
+
+ describe('by default', () => {
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FileDescriptionComponent);
+ component = fixture.componentInstance;
+ component.fileInput = createFileInput();
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should display the file name', () => {
+ const fileNameElement = fixture.debugElement.query(
+ By.css('.file-content dd')
+ ).nativeElement;
+ expect(fileNameElement.textContent).toContain('testFile');
+ });
- component.fileInput = fileInput;
+ it('should not show the embargo badge', () => {
+ const badge = fixture.debugElement.query(By.css('span.badge'));
+ expect(badge).toBeNull();
+ });
- fixture.detectChanges();
+ it('should not show the lock icon', () => {
+ const lockIcon = fixture.debugElement.query(By.css('.file-content dd i.fa-lock'));
+ expect(lockIcon).toBeNull();
+ });
});
- it('should create', () => {
- expect(component).toBeTruthy();
+ describe('when the bitstream is embargoed and the feature flag is on', () => {
+ beforeEach(() => {
+ environment.item.bitstream.showAccessStatuses = true;
+ fixture = TestBed.createComponent(FileDescriptionComponent);
+ component = fixture.componentInstance;
+ component.fileInput = createFileInput({ status: 'embargo', embargoDate: '2050-01-01' });
+ fixture.detectChanges();
+ });
+
+ afterEach(() => {
+ environment.item.bitstream.showAccessStatuses = false;
+ });
+
+ it('should show the embargo badge', () => {
+ const badge = fixture.debugElement.query(By.css('span.badge'));
+ expect(badge).not.toBeNull();
+ expect(badge.nativeElement.textContent).toContain('embargo.listelement.badge');
+ });
+
+ it('should show the lock icon next to the file name', () => {
+ const lockIcon = fixture.debugElement.query(By.css('.file-content dd i.fa-lock'));
+ expect(lockIcon).not.toBeNull();
+ });
+
+ it('should render the file name as a clickable link, matching the ZCU-PUB pattern', () => {
+ const link = fixture.debugElement.query(By.css('.file-content dd a'));
+ expect(link).not.toBeNull();
+ expect(link.nativeElement.textContent).toContain('testFile');
+ });
});
- it('should display the file name', () => {
- const fileNameElement = fixture.debugElement.query(
- By.css('.file-content dd')
- ).nativeElement;
- expect(fileNameElement.textContent).toContain('testFile');
+ describe('when the bitstream is embargoed but the feature flag is off', () => {
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FileDescriptionComponent);
+ component = fixture.componentInstance;
+ component.fileInput = createFileInput({ status: 'embargo', embargoDate: '2050-01-01' });
+ fixture.detectChanges();
+ });
+
+ it('should not show the embargo badge', () => {
+ const badge = fixture.debugElement.query(By.css('span.badge'));
+ expect(badge).toBeNull();
+ });
+
+ it('should not show the lock icon', () => {
+ const lockIcon = fixture.debugElement.query(By.css('.file-content dd i.fa-lock'));
+ expect(lockIcon).toBeNull();
+ });
});
});
diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts
index cb2a2bf2ed1..ee754501013 100644
--- a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts
+++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts
@@ -2,6 +2,7 @@ import { Component, Input } from '@angular/core';
import { MetadataBitstream } from 'src/app/core/metadata/metadata-bitstream.model';
import { HALEndpointService } from '../../../../../core/shared/hal-endpoint.service';
import {Router} from '@angular/router';
+import { environment } from 'src/environments/environment';
const allowedPreviewFormats = ['text/plain', 'text/html', 'application/zip'];
@Component({
@@ -13,6 +14,14 @@ export class FileDescriptionComponent {
MIME_TYPE_IMAGES_PATH = '/assets/images/mime/';
MIME_TYPE_DEFAULT_IMAGE_NAME = 'application-octet-stream.png';
+ /**
+ * Whether to show the embargo-date badge for a restricted bitstream. Same feature flag as
+ * the standard file-download-link/AccessStatusBadgeComponent path on other customer instances.
+ */
+ get showAccessStatus(): boolean {
+ return environment.item.bitstream.showAccessStatuses;
+ }
+
@Input()
fileInput: MetadataBitstream;
diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5
index 4d0ec104948..9ae830d2672 100644
--- a/src/assets/i18n/cs.json5
+++ b/src/assets/i18n/cs.json5
@@ -8397,4 +8397,6 @@
// "item.page.cc.license.disclaimer": "Except where otherwised noted, this item's license is described as",
// TODO New key - Add a translation
"item.page.cc.license.disclaimer": "Except where otherwised noted, this item's license is described as",
+ // "embargo.listelement.badge": "Embargo until {{ date }}",
+ "embargo.listelement.badge": "Embargo do {{ date }}",
}
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5
index 1ae3aa647db..062f3e6f876 100644
--- a/src/assets/i18n/en.json5
+++ b/src/assets/i18n/en.json5
@@ -5930,4 +5930,6 @@
"navbar.about.service-integrations": "Service integrations",
"navbar.about.project-partnership": "Project partnerships",
+
+ "embargo.listelement.badge": "Embargo until {{ date }}",
}
diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts
index 6f05dedb112..e1578b2da74 100644
--- a/src/config/default-app-config.ts
+++ b/src/config/default-app-config.ts
@@ -285,7 +285,10 @@ export class DefaultAppConfig implements AppConfig {
// Number of entries in the bitstream list in the item view page.
// Rounded to the nearest size in the list of selectable sizes on the
// settings menu. See pageSizeOptions in 'pagination-component-options.model.ts'.
- pageSize: 5
+ pageSize: 5,
+ // Show the bitstream embargo-date badge.
+ // Keep this false until the backend accessStatus support (DSpace#1380) is deployed.
+ showAccessStatuses: false
}
};
diff --git a/src/config/item-config.interface.ts b/src/config/item-config.interface.ts
index 35cb5260aea..f3141f77238 100644
--- a/src/config/item-config.interface.ts
+++ b/src/config/item-config.interface.ts
@@ -12,5 +12,7 @@ export interface ItemConfig extends Config {
// Rounded to the nearest size in the list of selectable sizes on the
// settings menu. See pageSizeOptions in 'pagination-component-options.model.ts'.
pageSize: number;
+ // Show the bitstream embargo-date badge
+ showAccessStatuses: boolean;
}
}
diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts
index 8a6a5d1fccb..46164ae5da4 100644
--- a/src/environments/environment.test.ts
+++ b/src/environments/environment.test.ts
@@ -254,7 +254,9 @@ export const environment: BuildConfig = {
// Number of entries in the bitstream list in the item view page.
// Rounded to the nearest size in the list of selectable sizes on the
// settings menu. See pageSizeOptions in 'pagination-component-options.model.ts'.
- pageSize: 5
+ pageSize: 5,
+ // Show the bitstream embargo-date badge
+ showAccessStatuses: false
}
},
collection: {