Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<ds-metadata-field-wrapper [label]="label | translate">
<ng-container *ngFor="let mdValue of mdValues; let last=last;">
<!--
Choose a template. Priority: markdown, link, browse link.
-->
<ng-container *ngTemplateOutlet="(renderMarkdown ? markdown : (hasLink(mdValue) ? (hasValue(img) ? linkImg : link) : (hasBrowseDefinition() ? browselink : simple)));
context: {value: mdValue.value, img}">
</ng-container>
<span class="separator" *ngIf="!last" [innerHTML]="separator"></span>
</ng-container>
</ds-metadata-field-wrapper>

<!-- Render value as markdown -->
<ng-template #markdown let-value="value">
<span class="dont-break-out" [dsMarkdown]="value">
</span>
</ng-template>

<!-- Render value as a link (href and label) -->
<ng-template #link let-value="value">
<a class="dont-break-out ds-simple-metadata-link" [href]="value" [attr.target]="getLinkAttributes(value).target"
[attr.rel]="getLinkAttributes(value).rel">
{{value}}
</a>
</ng-template>

<!-- Render value as a link with icon -->
<ng-template #linkImg let-img="img" let-value="value">
<a [href]="value" class="link-anchor dont-break-out ds-simple-metadata-link" target="_blank">
<img class="link-logo" [alt]="img.alt | translate"
[style.height]="'var(' + img.heightVar + ', --ds-item-page-img-field-default-inline-height)'"
[src]="img.URI" />
{{value}}
</a>
</ng-template>

<!-- Render simple value in a span -->
<ng-template #simple let-value="value">
<span class="dont-break-out preserve-line-breaks">{{value}}</span>
</ng-template>

<!-- Render value as a link to browse index -->
<ng-template #browselink let-value="value">
<a class="dont-break-out preserve-line-breaks ds-browse-link"
[routerLink]="['/browse', getBrowseRouteSegment()]"
[queryParams]="getQueryParams(value)"
role="link" tabindex="0">{{value}}</a>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import {

Check failure on line 1 in src/themes/qulto/app/item-page/simple/field-components/metadata-values/metadata-values.component.ts

View workflow job for this annotation

GitHub Actions / tests (18.x)

Run autofix to sort these imports!

Check failure on line 1 in src/themes/qulto/app/item-page/simple/field-components/metadata-values/metadata-values.component.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

Run autofix to sort these imports!

Check failure on line 1 in src/themes/qulto/app/item-page/simple/field-components/metadata-values/metadata-values.component.ts

View workflow job for this annotation

GitHub Actions / tests (18.x)

Run autofix to sort these imports!

Check failure on line 1 in src/themes/qulto/app/item-page/simple/field-components/metadata-values/metadata-values.component.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

Run autofix to sort these imports!
AsyncPipe,
NgFor,
NgIf,
NgTemplateOutlet,
} from '@angular/common';
import {
Component,
Inject,
Input,
OnChanges,
SimpleChanges,
} from '@angular/core';
import { RouterLink } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';

import {
APP_CONFIG,
AppConfig,
} from '../../../../../../../config/app-config.interface';
import { environment } from '../../../../../../../environments/environment';
import { BrowseDefinition } from 'src/app/core/shared/browse-definition.model';
import { MetadataValue } from 'src/app/core/shared/metadata.models';
import { hasValue } from 'src/app/shared/empty.util';
import { MetadataFieldWrapperComponent } from 'src/app/shared/metadata-field-wrapper/metadata-field-wrapper.component';
import { MarkdownDirective } from 'src/app/shared/utils/markdown.directive';
import { ImageField } from 'src/app/item-page/simple/field-components/specific-field/image-field';
import { ResourceType } from 'src/app/core/shared/resource-type';
import { listableObjectComponent } from 'src/app/shared/object-collection/shared/listable-object/listable-object.decorator';
import { ViewMode } from 'src/app/core/shared/view-mode.model';
import { Context } from 'src/app/core/shared/context.model';

/**
* This component renders the configured 'values' into the ds-metadata-field-wrapper component.
* It puts the given 'separator' between each two values.
*/
@listableObjectComponent('MetadataValuesComponent', ViewMode.ListElement, Context.Any, 'qulto')
@Component({
selector: 'ds-metadata-values',
styleUrls: ['./metadata-values.component.scss'],
templateUrl: './metadata-values.component.html',
standalone: true,
imports: [MetadataFieldWrapperComponent, NgFor, NgTemplateOutlet, NgIf, RouterLink, AsyncPipe, TranslateModule, MarkdownDirective],
})
export class MetadataValuesComponent implements OnChanges {

constructor(
@Inject(APP_CONFIG) private appConfig: AppConfig,
) {
}

/**
* The metadata values to display
*/
@Input() mdValues: MetadataValue[];

/**
* The seperator used to split the metadata values (can contain HTML)
*/
@Input() separator: string;

/**
* The label for this iteration of metadata values
*/
@Input() label: string;

/**
* Whether the {@link MarkdownDirective} should be used to render these metadata values.
* This will only have effect if {@link MarkdownConfig#enabled} is true.
* Mathjax will only be rendered if {@link MarkdownConfig#mathjax} is true.
*/
@Input() enableMarkdown = false;

/**
* Whether any valid HTTP(S) URL should be rendered as a link
*/
@Input() urlRegex?;

/**
* This variable will be true if both {@link environment.markdown.enabled} and {@link enableMarkdown} are true.
*/
renderMarkdown;


@Input() browseDefinition?: BrowseDefinition;

/**
* Optional {@code ImageField} reference that represents an image to be displayed inline.
*/
@Input() img?: ImageField;

hasValue = hasValue;

ngOnChanges(changes: SimpleChanges): void {
this.renderMarkdown = !!this.appConfig.markdown.enabled && this.enableMarkdown;
}

/**
* Does this metadata value have a configured link to a browse definition?
*/
hasBrowseDefinition(): boolean {
console.log('hasBrowseDefinition');
return hasValue(this.browseDefinition);
}

/**
* Does this metadata value have a valid URL that should be rendered as a link?
* @param value A MetadataValue being displayed
*/
hasLink(value: MetadataValue): boolean {
console.log('hasLink');
if (hasValue(this.urlRegex)) {
const pattern = new RegExp(this.urlRegex);
return pattern.test(value.value);
}
return false;
}

/**
* Return a queryparams object for use in a link, with the key dependent on whether this browse
* definition is metadata browse, or item browse
* @param value the specific metadata value being linked
*/
getQueryParams(value) {
console.log('getQueryParams');
const queryParams = { value: value };
// todo: should compare with type instead?
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
if (this.browseDefinition.getRenderType() === new ResourceType("startsWith").value) {

Check failure on line 129 in src/themes/qulto/app/item-page/simple/field-components/metadata-values/metadata-values.component.ts

View workflow job for this annotation

GitHub Actions / tests (18.x)

Strings must use singlequote

Check failure on line 129 in src/themes/qulto/app/item-page/simple/field-components/metadata-values/metadata-values.component.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

Strings must use singlequote

Check failure on line 129 in src/themes/qulto/app/item-page/simple/field-components/metadata-values/metadata-values.component.ts

View workflow job for this annotation

GitHub Actions / tests (18.x)

Strings must use singlequote

Check failure on line 129 in src/themes/qulto/app/item-page/simple/field-components/metadata-values/metadata-values.component.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

Strings must use singlequote
return { startsWith: value };
}
return queryParams;
}

getBrowseRouteSegment(): string {
console.log('getBrowseRouteSegment');
if (this.browseDefinition?.id === 'srsc') {
return 'subject';
}
return this.browseDefinition?.id;
}


/**
* Checks if the given link value is an internal link.
* @param linkValue - The link value to check.
* @returns True if the link value starts with the base URL defined in the environment configuration, false otherwise.
*/
hasInternalLink(linkValue: string): boolean {
console.log('hasInternalLink');
return linkValue.startsWith(environment.ui.baseUrl);
}

/**
* This method performs a validation and determines the target of the url.
* @returns - Returns the target url.
*/
getLinkAttributes(urlValue: string): { target: string, rel: string } {
console.log('getLinkAttributes');
if (this.hasInternalLink(urlValue)) {
return { target: '_self', rel: '' };
} else {
return { target: '_blank', rel: 'noopener noreferrer' };
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { AsyncPipe } from '@angular/common';

Check failure on line 1 in src/themes/qulto/app/item-page/simple/field-components/specific-field/generic/generic-item-page-field.component.ts

View workflow job for this annotation

GitHub Actions / tests (18.x)

Run autofix to sort these imports!

Check failure on line 1 in src/themes/qulto/app/item-page/simple/field-components/specific-field/generic/generic-item-page-field.component.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

Run autofix to sort these imports!

Check failure on line 1 in src/themes/qulto/app/item-page/simple/field-components/specific-field/generic/generic-item-page-field.component.ts

View workflow job for this annotation

GitHub Actions / tests (18.x)

Run autofix to sort these imports!

Check failure on line 1 in src/themes/qulto/app/item-page/simple/field-components/specific-field/generic/generic-item-page-field.component.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

Run autofix to sort these imports!
import {
Component,
Input,
} from '@angular/core';

import { Item } from 'src/app/core/shared/item.model';
import { MetadataValuesComponent } from '../../metadata-values/metadata-values.component';
import { ItemPageFieldComponent } from 'src/app/item-page/simple/field-components/specific-field/item-page-field.component';

@Component({
selector: 'ds-generic-item-page-field',
templateUrl: '../item-page-field.component.html',
standalone: true,
imports: [MetadataValuesComponent, AsyncPipe],
})
/**
* This component can be used to represent metadata on a simple item page.
* It is the most generic way of displaying metadata values
* It expects 4 parameters: The item, a separator, the metadata keys and an i18n key
*/
export class GenericItemPageFieldComponent extends ItemPageFieldComponent {

/**
* The item to display metadata for
*/
@Input() item: Item;

/**
* Separator string between multiple values of the metadata fields defined
* @type {string}
*/
@Input() separator: string;

/**
* Fields (schema.element.qualifier) used to render their values.
*/
@Input() fields: string[];

/**
* Label i18n key for the rendered metadata
*/
@Input() label: string;

/**
* Whether the {@link MarkdownDirective} should be used to render this metadata.
*/
@Input() enableMarkdown = false;

/**
* Whether any valid HTTP(S) URL should be rendered as a link
*/
@Input() urlRegex?: string;


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class="item-page-field">
<ds-metadata-values
[mdValues]="item?.allMetadata(fields)"
[separator]="separator"
[label]="label"
[enableMarkdown]="enableMarkdown"
[urlRegex]="urlRegex"
[browseDefinition]="browseDefinition|async"
[img]="img"
></ds-metadata-values>
</div>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {

Check failure on line 1 in src/themes/qulto/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.spec.ts

View workflow job for this annotation

GitHub Actions / tests (18.x)

Run autofix to sort these imports!

Check failure on line 1 in src/themes/qulto/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.spec.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

Run autofix to sort these imports!

Check failure on line 1 in src/themes/qulto/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.spec.ts

View workflow job for this annotation

GitHub Actions / tests (18.x)

Run autofix to sort these imports!

Check failure on line 1 in src/themes/qulto/app/item-page/simple/field-components/specific-field/title/item-page-title-field.component.spec.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

Run autofix to sort these imports!
ChangeDetectionStrategy,
NO_ERRORS_SCHEMA,
} from '@angular/core';
Expand All @@ -13,7 +13,7 @@
} from '@ngx-translate/core';

import { TranslateLoaderMock } from '../../../../../../../../app/shared/testing/translate-loader.mock';
import { MetadataValuesComponent } from '../../../../../../../../app/item-page/field-components/metadata-values/metadata-values.component';
import { MetadataValuesComponent } from '../../metadata-values/metadata-values.component';
import { mockItemWithMetadataFieldsAndValue } from '../../../../../../../../app/item-page/simple/field-components/specific-field/item-page-field.component.spec';
import { ItemPageTitleFieldComponent } from './item-page-title-field.component';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { MiradorViewerComponent } from '../../../../../../../app/item-page/mirad
import { ThemedFileSectionComponent } from '../../../../../../../app/item-page/simple/field-components/file-section/themed-file-section.component';
import { ItemPageAbstractFieldComponent } from '../../../../../../../app/item-page/simple/field-components/specific-field/abstract/item-page-abstract-field.component';
import { ItemPageDateFieldComponent } from '../../../../../../../app/item-page/simple/field-components/specific-field/date/item-page-date-field.component';
import { GenericItemPageFieldComponent } from '../../../../../../../app/item-page/simple/field-components/specific-field/generic/generic-item-page-field.component';
import { GenericItemPageFieldComponent } from '../../field-components/specific-field/generic/generic-item-page-field.component';
import { ThemedItemPageTitleFieldComponent } from '../../field-components/specific-field/title/themed-item-page-field.component';
import { ItemPageUriFieldComponent } from '../../../../../../../app/item-page/simple/field-components/specific-field/uri/item-page-uri-field.component';
import { ThemedMetadataRepresentationListComponent } from '../../../../../../../app/item-page/simple/metadata-representation-list/themed-metadata-representation-list.component';
Expand Down
5 changes: 4 additions & 1 deletion src/themes/qulto/eager-theme.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { NavbarComponent } from './app/navbar/navbar.component';
import { LangSwitchComponent } from './app/shared/lang-switch/lang-switch.component';
import { CommunityListElementComponent } from './app/shared/object-list/community-list-element/community-list-element.component';
import { PublicationComponent } from './app/item-page/simple/item-types/publication/publication.component';
import { MetadataValuesComponent } from './app/item-page/simple/field-components/metadata-values/metadata-values.component';


/**
Expand All @@ -28,14 +29,16 @@ const DECLARATIONS = [
NavbarComponent,
FooterComponent,
LangSwitchComponent,
PublicationComponent
PublicationComponent,
MetadataValuesComponent
];

@NgModule({
imports: [
CommonModule,
RootModule,
PublicationComponent,
MetadataValuesComponent,
...DECLARATIONS,
],
providers: [
Expand Down
4 changes: 4 additions & 0 deletions src/themes/qulto/lazy-theme.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { HomePageComponent } from './app/home-page/home-page.component';
import { FullItemPageComponent } from './app/item-page/full/full-item-page.component';
import { PublicationComponent } from './app/item-page/simple/item-types/publication/publication.component';
import { ThemedItemPageTitleFieldComponent } from './app/item-page/simple/field-components/specific-field/title/themed-item-page-field.component';
import { MetadataValuesComponent } from './app/item-page/simple/field-components/metadata-values/metadata-values.component';
import { GenericItemPageFieldComponent } from './app/item-page/simple/field-components/specific-field/generic/generic-item-page-field.component';
import { LoginPageComponent } from './app/login-page/login-page.component';
import { AuthNavMenuComponent } from './app/shared/auth-nav-menu/auth-nav-menu.component';
import { ObjectListComponent } from './app/shared/object-list/object-list.component';
Expand Down Expand Up @@ -48,6 +50,8 @@ const DECLARATIONS = [
NgxGalleryModule,
PublicationComponent,
ThemedItemPageTitleFieldComponent,
GenericItemPageFieldComponent,
MetadataValuesComponent,
...DECLARATIONS,
],
})
Expand Down
Loading