diff --git a/src/app/entity-groups/research-entities/metadata-representations/generic-item/generic-item-metadata-list-element.component.html b/src/app/entity-groups/research-entities/metadata-representations/generic-item/generic-item-metadata-list-element.component.html new file mode 100644 index 00000000000..1c44c860c85 --- /dev/null +++ b/src/app/entity-groups/research-entities/metadata-representations/generic-item/generic-item-metadata-list-element.component.html @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/app/entity-groups/research-entities/metadata-representations/generic-item/generic-item-metadata-list-element.component.ts b/src/app/entity-groups/research-entities/metadata-representations/generic-item/generic-item-metadata-list-element.component.ts new file mode 100644 index 00000000000..d27c9e0facf --- /dev/null +++ b/src/app/entity-groups/research-entities/metadata-representations/generic-item/generic-item-metadata-list-element.component.ts @@ -0,0 +1,90 @@ +import { CommonModule } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + Input, + OnDestroy, + OnInit, +} from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateService } from '@ngx-translate/core'; +import { Subscription } from 'rxjs'; +import { MetadataRepresentationListElementComponent } from 'src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component'; +import { TruncatableComponent } from 'src/app/shared/truncatable/truncatable.component'; + +import { MetadataValue } from '../../../../core/shared/metadata.models'; +import { ItemMetadataRepresentation } from '../../../../core/shared/metadata-representation/item/item-metadata-representation.model'; +import { getItemPageRoute } from '../../../../item-page/item-page-routing-paths'; + +@Component({ + selector: 'ds-item-metadata-representation-list-element', + templateUrl: './generic-item-metadata-list-element.component.html', + standalone: true, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ + CommonModule, + RouterModule, + NgbTooltipModule, + TruncatableComponent, + ], +}) +export class GenericItemMetadataListElementComponent extends MetadataRepresentationListElementComponent implements OnInit, OnDestroy { + + @Input() mdRepresentation!: ItemMetadataRepresentation; + + itemPageRoute = ''; + titleForUiLang = ''; + descriptionForUiLang = ''; + + private subs: Subscription[] = []; + + constructor(private translate: TranslateService) { + super(); + } + + ngOnInit(): void { + this.itemPageRoute = getItemPageRoute(this.mdRepresentation); + this.localizeTexts(this.translate.currentLang); + + this.subs.push( + this.translate.onLangChange.subscribe(e => this.localizeTexts(e.lang)), + ); + } + + ngOnDestroy(): void { + this.subs.forEach(s => s?.unsubscribe()); + } + + private localizeTexts(lang: string): void { + this.titleForUiLang = this.pickByLang(['dc.title'], lang) ?? ''; + this.descriptionForUiLang = this.pickByLang(['dc.description'], lang) ?? ''; + } + + private pickByLang(keys: string[], uiLanguage: string): string | undefined { + const metadataValues = this.mdRepresentation.allMetadata(keys) as MetadataValue[] | undefined; + if (!metadataValues?.length){ + return undefined; + } + + const normalizeLanguage = (s?: string) => (s ?? '').toLowerCase(); + const getLanguageBase = (s?: string) => normalizeLanguage(s).split(/[_-]/)[0]; + + const currentLocale = normalizeLanguage(uiLanguage); + const currentLangBase = getLanguageBase(uiLanguage); + + const exactMatch = metadataValues.find(v => normalizeLanguage(v.language) === currentLocale); + if (exactMatch) { + return exactMatch.value; + } + const baseLangMatch = metadataValues.find(v => getLanguageBase(v.language) === currentLangBase); + if (baseLangMatch) { + return baseLangMatch.value; + } + const languageAgnostic = metadataValues.find(v => !v.language); + if (languageAgnostic) { + return languageAgnostic.value; + } + return metadataValues[0]?.value; + } +} diff --git a/src/app/shared/metadata-representation/metadata-representation.decorator.ts b/src/app/shared/metadata-representation/metadata-representation.decorator.ts index c34eb0d2191..93a0801c865 100644 --- a/src/app/shared/metadata-representation/metadata-representation.decorator.ts +++ b/src/app/shared/metadata-representation/metadata-representation.decorator.ts @@ -1,4 +1,5 @@ import { InjectionToken } from '@angular/core'; +import { GenericItemMetadataListElementComponent } from 'src/app/entity-groups/research-entities/metadata-representations/generic-item/generic-item-metadata-list-element.component'; import { Context } from '../../core/shared/context.model'; import { GenericConstructor } from '../../core/shared/generic-constructor'; @@ -34,7 +35,8 @@ export type MetadataRepresentationComponent = typeof ItemMetadataListElementComponent | typeof OrgUnitItemMetadataListElementComponent | typeof PersonItemMetadataListElementComponent | - typeof ProjectItemMetadataListElementComponent; + typeof ProjectItemMetadataListElementComponent | + typeof GenericItemMetadataListElementComponent; export const METADATA_REPRESENTATION_COMPONENT_DECORATOR_MAP = new Map>>>([ @@ -52,6 +54,66 @@ export const METADATA_REPRESENTATION_COMPONENT_DECORATOR_MAP = [MetadataRepresentationType.Item, new Map([ [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, PersonItemMetadataListElementComponent]])]])], ])], + ['LearningObject', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['Language', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['EducationLevel', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['Type', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['Format', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['TeachingMethod', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['License', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['FieldOfScience', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['Course', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['DoctoralSchool', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['Faculty', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['Department', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['Institute', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['SchoolSubject', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], + ['AccessLevel', new Map([ + [MetadataRepresentationType.Item, new Map([ + [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, GenericItemMetadataListElementComponent]])]])], + ])], ['OrgUnit', new Map([ [MetadataRepresentationType.Item, new Map([ [DEFAULT_CONTEXT, new Map([[DEFAULT_THEME, OrgUnitItemMetadataListElementComponent]])]])],