diff --git a/src/app/item-page/item-page.module.ts b/src/app/item-page/item-page.module.ts index 26040cfcb18..dba86ff8142 100644 --- a/src/app/item-page/item-page.module.ts +++ b/src/app/item-page/item-page.module.ts @@ -92,6 +92,7 @@ import { ClarinDateItemFieldComponent } from './simple/field-components/clarin-d import { ClarinDescriptionItemFieldComponent } from './simple/field-components/clarin-description-item-field/clarin-description-item-field.component'; import { ClarinFilesSectionComponent } from './clarin-files-section/clarin-files-section.component'; import { UsageReportDataService } from '../core/statistics/usage-report-data.service'; +import { CreativeCommonsLicenseFieldComponent } from './simple/field-components/creative-commons-license-field/creative-commons-license-field.component'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -157,7 +158,8 @@ const DECLARATIONS = [ ClarinIdentifierItemFieldComponent, ClarinDateItemFieldComponent, ClarinDescriptionItemFieldComponent, - ClarinFilesSectionComponent + ClarinFilesSectionComponent, + CreativeCommonsLicenseFieldComponent ]; @NgModule({ diff --git a/src/app/item-page/simple/field-components/creative-commons-license-field/creative-commons-license-field.component.html b/src/app/item-page/simple/field-components/creative-commons-license-field/creative-commons-license-field.component.html new file mode 100644 index 00000000000..21566fb02aa --- /dev/null +++ b/src/app/item-page/simple/field-components/creative-commons-license-field/creative-commons-license-field.component.html @@ -0,0 +1,66 @@ +
+
+
+
{{ 'item.page.cc-license' | translate }}
+
+
+
+ + + + + +
+
+
diff --git a/src/app/item-page/simple/field-components/creative-commons-license-field/creative-commons-license-field.component.scss b/src/app/item-page/simple/field-components/creative-commons-license-field/creative-commons-license-field.component.scss new file mode 100644 index 00000000000..57e9f8102e0 --- /dev/null +++ b/src/app/item-page/simple/field-components/creative-commons-license-field/creative-commons-license-field.component.scss @@ -0,0 +1,113 @@ +@import '../../item-page.component'; + +@media (min-width: 992px) { + .col-2-5 { + flex: 0 0 20%; + max-width: 20%; + } +} + +.clarin-item-page-field { + .cc-license-content { + .cc-license-row { + display: flex; + flex-direction: column; + gap: 4px; + } + + .cc-license-link { + display: inline-flex; + align-items: center; + gap: 8px; + text-decoration: none; + color: #007bff; + font-weight: 500; + transition: all 0.2s ease; + + &:hover { + color: #0056b3; + text-decoration: none; + } + + .cc-icons { + display: flex; + align-items: center; + gap: 2px; + + i { + font-size: 1.1rem; + + &.fa-creative-commons { + color: #f39c12; + } + + &.fa-creative-commons-by { + color: #3498db; + } + + &.fa-creative-commons-sa { + color: #27ae60; + } + + &.fa-creative-commons-nc { + color: #e74c3c; + } + + &.fa-creative-commons-nd { + color: #9b59b6; + } + + &.fa-creative-commons-zero { + color: #34495e; + } + } + } + + .cc-license-text { + font-size: 0.95rem; + font-weight: 500; + } + + &:hover .cc-icons i { + font-size: 1.2rem; + } + } + + .cc-license-description { + font-size: 0.85rem; + color: #6c757d; + font-style: italic; + margin-left: 0; + } + } +} + +// Responsive design +@media (max-width: 991.98px) { + .clarin-item-page-field { + .cc-license-content { + .cc-license-link { + flex-direction: column; + align-items: flex-start; + gap: 4px; + + .cc-icons { + gap: 1px; + + i { + font-size: 1rem; + } + } + + .cc-license-text { + font-size: 0.9rem; + } + } + + .cc-license-description { + font-size: 0.8rem; + margin-top: 2px; + } + } + } +} diff --git a/src/app/item-page/simple/field-components/creative-commons-license-field/creative-commons-license-field.component.spec.ts b/src/app/item-page/simple/field-components/creative-commons-license-field/creative-commons-license-field.component.spec.ts new file mode 100644 index 00000000000..a89dd992f0a --- /dev/null +++ b/src/app/item-page/simple/field-components/creative-commons-license-field/creative-commons-license-field.component.spec.ts @@ -0,0 +1,384 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; +import { TranslateModule } from '@ngx-translate/core'; +import { of } from 'rxjs'; + +import { CreativeCommonsLicenseFieldComponent } from './creative-commons-license-field.component'; +import { BundleDataService } from '../../../../core/data/bundle-data.service'; +import { BitstreamDataService } from '../../../../core/data/bitstream-data.service'; +import { Item } from '../../../../core/shared/item.model'; +import { RemoteData } from '../../../../core/data/remote-data'; +import { Bundle } from '../../../../core/shared/bundle.model'; +import { PaginatedList, buildPaginatedList } from '../../../../core/data/paginated-list.model'; +import { Bitstream } from '../../../../core/shared/bitstream.model'; +import { createSuccessfulRemoteDataObject, createFailedRemoteDataObject } from '../../../../shared/remote-data.utils'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { PageInfo } from '../../../../core/shared/page-info.model'; + +describe('CreativeCommonsLicenseFieldComponent', () => { + let component: CreativeCommonsLicenseFieldComponent; + let fixture: ComponentFixture; + let bundleDataService: jasmine.SpyObj; + let bitstreamDataService: jasmine.SpyObj; + + const mockItem = { + uuid: 'test-item-uuid', + metadata: { + 'dc.rights.uri': [{ value: 'https://creativecommons.org/licenses/by/4.0/' }], + 'dc.rights': [{ value: 'Attribution 4.0 International' }] + }, + allMetadata: jasmine.createSpy('allMetadata').and.callFake((field: string) => { + return mockItem.metadata[field] || []; + }) + } as any as Item; + + const mockItemWithoutLicense = { + uuid: 'test-item-uuid-no-license', + metadata: { + 'dc.title': [{ value: 'Test Item' }] + }, + allMetadata: jasmine.createSpy('allMetadata').and.callFake((field: string) => { + return mockItemWithoutLicense.metadata[field] || []; + }) + } as any as Item; + + const mockBundle = { + uuid: 'test-bundle-uuid', + name: 'CC_LICENSE' + } as Bundle; + + const mockBitstream = { + uuid: 'test-bitstream-uuid', + name: 'license.txt', + metadata: { + 'dc.identifier.uri': [{ value: 'https://creativecommons.org/licenses/by-nc-sa/3.0/' }] + } + } as any as Bitstream; + + beforeEach(async () => { + const bundleDataServiceSpy = jasmine.createSpyObj('BundleDataService', ['findByItemAndName']); + const bitstreamDataServiceSpy = jasmine.createSpyObj('BitstreamDataService', ['findAllByItemAndBundleName']); + + await TestBed.configureTestingModule({ + declarations: [CreativeCommonsLicenseFieldComponent], + imports: [ + TranslateModule.forRoot(), + NoopAnimationsModule + ], + providers: [ + { provide: BundleDataService, useValue: bundleDataServiceSpy }, + { provide: BitstreamDataService, useValue: bitstreamDataServiceSpy } + ] + }).compileComponents(); + + fixture = TestBed.createComponent(CreativeCommonsLicenseFieldComponent); + component = fixture.componentInstance; + bundleDataService = TestBed.inject(BundleDataService) as jasmine.SpyObj; + bitstreamDataService = TestBed.inject(BitstreamDataService) as jasmine.SpyObj; + }); + + describe('Component Initialization', () => { + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should initialize with item input', () => { + component.item = mockItem; + expect(component.item).toBe(mockItem); + }); + }); + + describe('Creative Commons License Detection', () => { + beforeEach(() => { + component.item = mockItem; + }); + + it('should detect Creative Commons license from metadata', (done) => { + bundleDataService.findByItemAndName.and.returnValue(of(createFailedRemoteDataObject())); + + component.ngOnInit(); + + component.hasCcLicense$.subscribe(hasLicense => { + expect(hasLicense).toBe(true); + done(); + }); + }); + + it('should detect Creative Commons license from CC_LICENSE bundle', (done) => { + bundleDataService.findByItemAndName.and.returnValue(of(createSuccessfulRemoteDataObject(mockBundle))); + bitstreamDataService.findAllByItemAndBundleName.and.returnValue( + of(createSuccessfulRemoteDataObject(buildPaginatedList(new PageInfo(), [mockBitstream]))) + ); + + component.ngOnInit(); + + component.hasCcLicense$.subscribe(hasLicense => { + expect(hasLicense).toBe(true); + done(); + }); + }); + + it('should return false when no Creative Commons license is found', (done) => { + component.item = mockItemWithoutLicense; + bundleDataService.findByItemAndName.and.returnValue(of(createFailedRemoteDataObject())); + + component.ngOnInit(); + + component.hasCcLicense$.subscribe(hasLicense => { + expect(hasLicense).toBe(false); + done(); + }); + }); + }); + + describe('License URL Extraction', () => { + beforeEach(() => { + component.item = mockItem; + }); + + it('should extract license URL from metadata', (done) => { + bundleDataService.findByItemAndName.and.returnValue(of(createFailedRemoteDataObject())); + + component.ngOnInit(); + + component.ccLicenseUrl$.subscribe(url => { + expect(url).toBe('https://creativecommons.org/licenses/by/4.0/'); + done(); + }); + }); + + it('should extract license URL from bitstream metadata', (done) => { + bundleDataService.findByItemAndName.and.returnValue(of(createSuccessfulRemoteDataObject(mockBundle))); + bitstreamDataService.findAllByItemAndBundleName.and.returnValue( + of(createSuccessfulRemoteDataObject(buildPaginatedList(new PageInfo(), [mockBitstream]))) + ); + + component.ngOnInit(); + + component.ccLicenseUrl$.subscribe(url => { + expect(url).toBe('https://creativecommons.org/licenses/by-nc-sa/3.0/'); + done(); + }); + }); + + it('should return empty string when no license URL is found', (done) => { + component.item = mockItemWithoutLicense; + bundleDataService.findByItemAndName.and.returnValue(of(createFailedRemoteDataObject())); + + component.ngOnInit(); + + component.ccLicenseUrl$.subscribe(url => { + expect(url).toBe(''); + done(); + }); + }); + }); + + describe('License Name Extraction', () => { + beforeEach(() => { + component.item = mockItem; + }); + + it('should extract license name from URL', (done) => { + bundleDataService.findByItemAndName.and.returnValue(of(createFailedRemoteDataObject())); + + component.ngOnInit(); + + component.ccLicenseName$.subscribe(name => { + expect(name).toBe('CC BY 4.0'); + done(); + }); + }); + + it('should return empty string when no license URL is available', (done) => { + component.item = mockItemWithoutLicense; + bundleDataService.findByItemAndName.and.returnValue(of(createFailedRemoteDataObject())); + + component.ngOnInit(); + + component.ccLicenseName$.subscribe(name => { + expect(name).toBe(''); + done(); + }); + }); + }); + + describe('License Type Detection', () => { + const testCases = [ + { input: 'CC BY 4.0', expected: 'by' }, + { input: 'CC BY-SA 3.0', expected: 'by-sa' }, + { input: 'CC BY-NC 2.0', expected: 'by-nc' }, + { input: 'CC BY-NC-SA 4.0', expected: 'by-nc-sa' }, + { input: 'CC BY-ND 3.0', expected: 'by-nd' }, + { input: 'CC BY-NC-ND 2.0', expected: 'by-nc-nd' }, + { input: 'CC0 1.0', expected: 'cc0' }, + { input: 'Public Domain Mark', expected: 'cc0' }, + { input: '', expected: '' }, + { input: 'Unknown License', expected: '' } + ]; + + testCases.forEach(testCase => { + it(`should return '${testCase.expected}' for license '${testCase.input}'`, () => { + const result = component.getLicenseType(testCase.input); + expect(result).toBe(testCase.expected); + }); + }); + }); + + describe('License Name Extraction from URL', () => { + const urlTestCases = [ + { + url: 'https://creativecommons.org/licenses/by/4.0/', + expected: 'CC BY 4.0' + }, + { + url: 'https://creativecommons.org/licenses/by-sa/3.0/', + expected: 'CC BY-SA 3.0' + }, + { + url: 'https://creativecommons.org/licenses/by-nc/2.0/', + expected: 'CC BY-NC 2.0' + }, + { + url: 'https://creativecommons.org/licenses/by-nc-sa/4.0/', + expected: 'CC BY-NC-SA 4.0' + }, + { + url: 'https://creativecommons.org/licenses/by-nd/3.0/', + expected: 'CC BY-ND 3.0' + }, + { + url: 'https://creativecommons.org/licenses/by-nc-nd/2.0/', + expected: 'CC BY-NC-ND 2.0' + }, + { + url: 'https://creativecommons.org/publicdomain/zero/1.0/', + expected: 'CC0 1.0' + }, + { + url: 'https://creativecommons.org/publicdomain/mark/1.0/', + expected: 'Public Domain 1.0' + }, + { + url: 'https://example.com/not-cc-license', + expected: '' + }, + { + url: '', + expected: '' + } + ]; + + urlTestCases.forEach(testCase => { + it(`should extract '${testCase.expected}' from URL '${testCase.url}'`, () => { + const result = component['extractLicenseNameFromUrl'](testCase.url); + expect(result).toBe(testCase.expected); + }); + }); + }); + + describe('Metadata Extraction', () => { + it('should extract Creative Commons URL from dc.rights.uri', () => { + component.item = mockItem; + const result = component['extractUrlFromMetadata'](); + expect(result).toBe('https://creativecommons.org/licenses/by/4.0/'); + }); + + it('should return empty string when no Creative Commons URL is found in metadata', () => { + component.item = mockItemWithoutLicense; + const result = component['extractUrlFromMetadata'](); + expect(result).toBe(''); + }); + + it('should check multiple metadata fields for Creative Commons URL', () => { + const itemWithDifferentField = { + uuid: 'test-item-uuid', + metadata: { + 'dc.rights': [{ value: 'https://creativecommons.org/licenses/by-sa/3.0/' }] + }, + allMetadata: jasmine.createSpy('allMetadata').and.callFake((field: string) => { + return itemWithDifferentField.metadata[field] || []; + }) + } as any as Item; + + component.item = itemWithDifferentField; + const result = component['extractUrlFromMetadata'](); + expect(result).toBe('https://creativecommons.org/licenses/by-sa/3.0/'); + }); + }); + + describe('Component Template Integration', () => { + it('should not display license field when no license is present', () => { + component.item = mockItemWithoutLicense; + bundleDataService.findByItemAndName.and.returnValue(of(createFailedRemoteDataObject())); + + component.ngOnInit(); + fixture.detectChanges(); + + const licenseElement = fixture.debugElement.query(By.css('.clarin-item-page-field')); + expect(licenseElement).toBeNull(); + }); + + it('should display license field when Creative Commons license is present', () => { + component.item = mockItem; + bundleDataService.findByItemAndName.and.returnValue(of(createFailedRemoteDataObject())); + + component.ngOnInit(); + fixture.detectChanges(); + + setTimeout(() => { + fixture.detectChanges(); + const licenseElement = fixture.debugElement.query(By.css('.clarin-item-page-field')); + expect(licenseElement).toBeTruthy(); + }, 100); + }); + }); + + describe('Error Handling', () => { + it('should handle bundle service errors gracefully', (done) => { + component.item = mockItem; + bundleDataService.findByItemAndName.and.returnValue(of(createFailedRemoteDataObject())); + + component.ngOnInit(); + + component.hasCcLicense$.subscribe(hasLicense => { + expect(hasLicense).toBe(true); // Should still detect from metadata + done(); + }); + }); + + it('should handle bitstream service errors gracefully', (done) => { + component.item = mockItem; + bundleDataService.findByItemAndName.and.returnValue(of(createSuccessfulRemoteDataObject(mockBundle))); + bitstreamDataService.findAllByItemAndBundleName.and.returnValue(of(createFailedRemoteDataObject>())); + + component.ngOnInit(); + + component.ccLicenseUrl$.subscribe(url => { + expect(url).toBe('https://creativecommons.org/licenses/by/4.0/'); // Fallback to metadata + done(); + }); + }); + }); + + describe('Debug Methods', () => { + it('should return metadata values for debug purposes', () => { + component.item = mockItem; + const result = component.getMetadataValues('dc.rights.uri'); + expect(result).toBe('https://creativecommons.org/licenses/by/4.0/'); + }); + + it('should return "No values found" when metadata field does not exist', () => { + component.item = mockItem; + const result = component.getMetadataValues('nonexistent.field'); + expect(result).toBe('No values found'); + }); + + it('should return "No metadata available" when item has no metadata', () => { + component.item = { metadata: null } as any as Item; + const result = component.getMetadataValues('dc.rights.uri'); + expect(result).toBe('No metadata available'); + }); + }); +}); diff --git a/src/app/item-page/simple/field-components/creative-commons-license-field/creative-commons-license-field.component.ts b/src/app/item-page/simple/field-components/creative-commons-license-field/creative-commons-license-field.component.ts new file mode 100644 index 00000000000..fec3ac0ca1d --- /dev/null +++ b/src/app/item-page/simple/field-components/creative-commons-license-field/creative-commons-license-field.component.ts @@ -0,0 +1,257 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Observable, of } from 'rxjs'; +import { map, switchMap, catchError } from 'rxjs/operators'; +import { Item } from '../../../../core/shared/item.model'; +import { BundleDataService } from '../../../../core/data/bundle-data.service'; +import { BitstreamDataService } from '../../../../core/data/bitstream-data.service'; +import { getAllSucceededRemoteDataPayload, getFirstSucceededRemoteDataPayload } from '../../../../core/shared/operators'; +import { RemoteData } from '../../../../core/data/remote-data'; +import { Bundle } from '../../../../core/shared/bundle.model'; +import { PaginatedList } from '../../../../core/data/paginated-list.model'; +import { Bitstream } from '../../../../core/shared/bitstream.model'; +import { isNotEmpty } from '../../../../shared/empty.util'; + +/** + * Constants for Creative Commons license handling + */ +const CC_CONSTANTS = { + BUNDLE_NAME: 'CC_LICENSE', + DOMAIN: 'creativecommons.org', + METADATA_FIELDS: [ + 'dc.rights.uri', + 'dc.rights', + 'dc.identifier.uri' + ], + LICENSE_TYPES: { + 'by/': 'CC BY', + 'by-sa/': 'CC BY-SA', + 'by-nc/': 'CC BY-NC', + 'by-nc-sa/': 'CC BY-NC-SA', + 'by-nd/': 'CC BY-ND', + 'by-nc-nd/': 'CC BY-NC-ND', + 'publicdomain/zero/': 'CC0', + 'publicdomain/mark/': 'Public Domain' + }, + LICENSE_TYPE_PATTERNS: { + CC0: ['cc0', 'public domain'], + BY_NC_ND: ['by-nc-nd'], + BY_NC_SA: ['by-nc-sa'], + BY_NC: ['by-nc'], + BY_ND: ['by-nd'], + BY_SA: ['by-sa'], + BY: ['by'] + }, + ICON_CLASSES: { + BASE: 'fab fa-creative-commons', + BY: 'fab fa-creative-commons-by', + SA: 'fab fa-creative-commons-sa', + NC: 'fab fa-creative-commons-nc', + ND: 'fab fa-creative-commons-nd', + ZERO: 'fab fa-creative-commons-zero' + }, + TEMPLATE_SWITCH_CASES: { + CC0: 'cc0', + BY_NC_ND: 'by-nc-nd', + BY_NC_SA: 'by-nc-sa', + BY_NC: 'by-nc', + BY_ND: 'by-nd', + BY_SA: 'by-sa', + BY: 'by' + }, + DEFAULT_MESSAGES: { + NO_METADATA: 'No metadata available', + NO_VALUES: 'No values found', + DEFAULT_LICENSE: 'Creative Commons License' + } +} as const; + +/** + * Component for displaying Creative Commons license information on item pages + */ +@Component({ + selector: 'ds-creative-commons-license-field', + templateUrl: './creative-commons-license-field.component.html', + styleUrls: ['./creative-commons-license-field.component.scss'] +}) +export class CreativeCommonsLicenseFieldComponent implements OnInit { + + /** + * The item to display Creative Commons license for + */ + @Input() item: Item; + + /** + * Creative Commons license URL + */ + ccLicenseUrl$: Observable; + + /** + * Creative Commons license name + */ + ccLicenseName$: Observable; + + /** + * Whether the item has a Creative Commons license + */ + hasCcLicense$: Observable; + + constructor( + private bundleService: BundleDataService, + private bitstreamService: BitstreamDataService + ) { } + + ngOnInit(): void { + this.initializeCcLicense(); + } + + /** + * Initialize Creative Commons license information + */ + private initializeCcLicense(): void { + // Cache the metadata URL extraction to avoid repeated calls + const metadataUrl = this.extractUrlFromMetadata(); + + // Check if item has CC_LICENSE bundle and extract license information + const ccLicenseBundle$ = this.bundleService.findByItemAndName(this.item, CC_CONSTANTS.BUNDLE_NAME); + + this.hasCcLicense$ = ccLicenseBundle$.pipe( + map((bundleRD: RemoteData) => { + // Check if CC_LICENSE bundle exists OR if CC license metadata exists + const hasBundleLicense = bundleRD.hasSucceeded && isNotEmpty(bundleRD.payload); + const hasMetadataLicense = isNotEmpty(metadataUrl); + return hasBundleLicense || hasMetadataLicense; + }), + catchError(() => of(false)) + ); + + // Get the license URL from bitstreams in CC_LICENSE bundle + this.ccLicenseUrl$ = ccLicenseBundle$.pipe( + switchMap((bundleRD: RemoteData) => { + if (bundleRD.hasSucceeded && isNotEmpty(bundleRD.payload)) { + return this.bitstreamService.findAllByItemAndBundleName(this.item, CC_CONSTANTS.BUNDLE_NAME); + } + return of(null); + }), + switchMap((bitstreamsRD) => { + if (bitstreamsRD && bitstreamsRD.hasSucceeded && isNotEmpty(bitstreamsRD.payload)) { + const bitstreams = bitstreamsRD.payload; + if (bitstreams.page.length > 0) { + // Look for license URL in bitstream metadata or name + const licenseBitstream = bitstreams.page.find(bitstream => + bitstream.name.includes('license') || + bitstream.metadata[CC_CONSTANTS.METADATA_FIELDS[0]]?.[0]?.value + ); + const url = licenseBitstream?.metadata[CC_CONSTANTS.METADATA_FIELDS[0]]?.[0]?.value || + metadataUrl || + ''; + return of(url); + } + } + // Fallback to cached metadata-based detection + return of(metadataUrl); + }), + catchError(() => of('')) + ); + + // Extract license name from URL or metadata + this.ccLicenseName$ = this.ccLicenseUrl$.pipe( + map((url: string) => { + if (isNotEmpty(url)) { + return this.extractLicenseNameFromUrl(url); + } + return ''; + }) + ); + } + + /** + * Extract Creative Commons license URL from item metadata + */ + private extractUrlFromMetadata(): string { + // Check for common CC license metadata fields + for (const field of CC_CONSTANTS.METADATA_FIELDS) { + const values = this.item.allMetadata(field); + if (values) { + for (const value of values) { + if (value.value && value.value.includes(CC_CONSTANTS.DOMAIN)) { + return value.value; + } + } + } + } + return ''; + } + + /** + * Extract license name from Creative Commons URL + */ + private extractLicenseNameFromUrl(url: string): string { + if (!url || !url.includes(CC_CONSTANTS.DOMAIN)) { + return ''; + } + + // Parse common CC license types from URL + for (const [pattern, name] of Object.entries(CC_CONSTANTS.LICENSE_TYPES)) { + if (url.includes(pattern)) { + // Extract version if present + const versionMatch = url.match(/(\d+\.\d+)/); + const version = versionMatch ? ` ${versionMatch[1]}` : ''; + return `${name}${version}`; + } + } + + return CC_CONSTANTS.DEFAULT_MESSAGES.DEFAULT_LICENSE; + } + + /** + * Get Creative Commons icon class based on license type + */ + getCcIconClass(licenseName: string): string { + const lowerName = licenseName.toLowerCase(); + + if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.CC0.some(pattern => lowerName.includes(pattern))) { + return CC_CONSTANTS.ICON_CLASSES.ZERO; + } else if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.BY_NC_ND.some(pattern => lowerName.includes(pattern))) { + return `${CC_CONSTANTS.ICON_CLASSES.BASE} ${CC_CONSTANTS.ICON_CLASSES.BY} ${CC_CONSTANTS.ICON_CLASSES.NC} ${CC_CONSTANTS.ICON_CLASSES.ND}`; + } else if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.BY_NC_SA.some(pattern => lowerName.includes(pattern))) { + return `${CC_CONSTANTS.ICON_CLASSES.BASE} ${CC_CONSTANTS.ICON_CLASSES.BY} ${CC_CONSTANTS.ICON_CLASSES.NC} ${CC_CONSTANTS.ICON_CLASSES.SA}`; + } else if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.BY_NC.some(pattern => lowerName.includes(pattern))) { + return `${CC_CONSTANTS.ICON_CLASSES.BASE} ${CC_CONSTANTS.ICON_CLASSES.BY} ${CC_CONSTANTS.ICON_CLASSES.NC}`; + } else if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.BY_ND.some(pattern => lowerName.includes(pattern))) { + return `${CC_CONSTANTS.ICON_CLASSES.BASE} ${CC_CONSTANTS.ICON_CLASSES.BY} ${CC_CONSTANTS.ICON_CLASSES.ND}`; + } else if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.BY_SA.some(pattern => lowerName.includes(pattern))) { + return `${CC_CONSTANTS.ICON_CLASSES.BASE} ${CC_CONSTANTS.ICON_CLASSES.BY} ${CC_CONSTANTS.ICON_CLASSES.SA}`; + } else if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.BY.some(pattern => lowerName.includes(pattern))) { + return `${CC_CONSTANTS.ICON_CLASSES.BASE} ${CC_CONSTANTS.ICON_CLASSES.BY}`; + } + + return CC_CONSTANTS.ICON_CLASSES.BASE; + } + + /** + * Get license type for switch case in template + */ + getLicenseType(licenseName: string): string { + if (!licenseName) return ''; + + const name = licenseName.toLowerCase(); + + if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.CC0.some(pattern => name.includes(pattern))) { + return CC_CONSTANTS.TEMPLATE_SWITCH_CASES.CC0; + } else if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.BY_NC_ND.some(pattern => name.includes(pattern))) { + return CC_CONSTANTS.TEMPLATE_SWITCH_CASES.BY_NC_ND; + } else if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.BY_NC_SA.some(pattern => name.includes(pattern))) { + return CC_CONSTANTS.TEMPLATE_SWITCH_CASES.BY_NC_SA; + } else if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.BY_NC.some(pattern => name.includes(pattern))) { + return CC_CONSTANTS.TEMPLATE_SWITCH_CASES.BY_NC; + } else if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.BY_ND.some(pattern => name.includes(pattern))) { + return CC_CONSTANTS.TEMPLATE_SWITCH_CASES.BY_ND; + } else if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.BY_SA.some(pattern => name.includes(pattern))) { + return CC_CONSTANTS.TEMPLATE_SWITCH_CASES.BY_SA; + } else if (CC_CONSTANTS.LICENSE_TYPE_PATTERNS.BY.some(pattern => name.includes(pattern))) { + return CC_CONSTANTS.TEMPLATE_SWITCH_CASES.BY; + } else { + return ''; + } + } +} diff --git a/src/app/item-page/simple/item-types/publication/publication.component.html b/src/app/item-page/simple/item-types/publication/publication.component.html index 5c00b504060..dd53479c46c 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.html +++ b/src/app/item-page/simple/item-types/publication/publication.component.html @@ -94,6 +94,7 @@ [fields]="['dc.identifier.uri']" [label]="'item.page.uri'"> +