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]])]])],