diff --git a/libs/ui/elements/src/lib/metadata-info/linkify.directive.spec.ts b/libs/ui/elements/src/lib/metadata-info/linkify.directive.spec.ts
new file mode 100644
index 0000000000..09f9b93ecd
--- /dev/null
+++ b/libs/ui/elements/src/lib/metadata-info/linkify.directive.spec.ts
@@ -0,0 +1,45 @@
+import { TestBed, ComponentFixture, waitForAsync } from '@angular/core/testing'
+import { Component, DebugElement } from '@angular/core'
+import { By } from '@angular/platform-browser'
+import { GnUiLinkifyDirective } from './linkify.directive'
+
+@Component({
+ template: `
Click this link https://www.example.com
`,
+})
+class TestComponent {}
+
+describe('GnUiLinkifyDirective', () => {
+ let fixture: ComponentFixture
+ let component: TestComponent
+ let debugElement: DebugElement
+
+ beforeEach(waitForAsync(() => {
+ TestBed.configureTestingModule({
+ declarations: [GnUiLinkifyDirective, TestComponent],
+ })
+
+ fixture = TestBed.createComponent(TestComponent)
+ component = fixture.componentInstance
+ debugElement = fixture.debugElement.query(
+ By.directive(GnUiLinkifyDirective)
+ )
+
+ fixture.detectChanges()
+ }))
+
+ it('should create an anchor element with the correct href', () => {
+ fixture.detectChanges()
+ const anchorElement = debugElement.query(By.css('a'))
+
+ const href = anchorElement.nativeElement.getAttribute('href')
+ expect(href).toBe('https://www.example.com')
+ })
+
+ it('should have the target attribute set to "_blank"', () => {
+ fixture.detectChanges()
+ const anchorElement = debugElement.query(By.css('a'))
+
+ const target = anchorElement.nativeElement.getAttribute('target')
+ expect(target).toBe('_blank')
+ })
+})
diff --git a/libs/ui/elements/src/lib/metadata-info/linkify.directive.stories.ts b/libs/ui/elements/src/lib/metadata-info/linkify.directive.stories.ts
new file mode 100644
index 0000000000..3bca5ce296
--- /dev/null
+++ b/libs/ui/elements/src/lib/metadata-info/linkify.directive.stories.ts
@@ -0,0 +1,41 @@
+import {
+ componentWrapperDecorator,
+ Meta,
+ moduleMetadata,
+ StoryObj,
+} from '@storybook/angular'
+import { GnUiLinkifyDirective } from './linkify.directive'
+
+export default {
+ title: 'Elements/GnUiLinkifyDirective',
+ decorators: [
+ moduleMetadata({
+ declarations: [GnUiLinkifyDirective],
+ }),
+ ],
+} as Meta
+
+export const Primary: StoryObj = {
+ args: {
+ htmlContent: `Région Hauts-de-France, Dreal, IGN BD Topo
+
+ Les données produites s'appuient sur le modèle CNIG de juin 2018 relatif aux SCoT : http://cnig.gouv.fr/wp-content/uploads/2019/04/190315_Standard_CNIG_SCOT.pdf
+
+ La structure a été modifiée au 03/2023 pour prendre en compte les évolutions du modèle CNIG du 10/06/2021 :
+ http://cnig.gouv.fr/IMG/pdf/210615_standard_cnig_nouveauscot.pdf
+ (il coexiste donc dans le modèle des champs liés aux deux modèles, par exemple sur les PADD pour les "anciens" SCoT, ou encore sur les PAS ou les DAAC pour les "nouveaux" SCoT)`,
+ },
+ argTypes: {
+ htmlContent: {
+ control: 'text',
+ },
+ },
+ render: (args) => ({
+ props: args,
+ template: `
+
+ ${args.htmlContent}
+
`,
+ }),
+}
diff --git a/libs/ui/elements/src/lib/metadata-info/linkify.directive.ts b/libs/ui/elements/src/lib/metadata-info/linkify.directive.ts
new file mode 100644
index 0000000000..3ef699bad1
--- /dev/null
+++ b/libs/ui/elements/src/lib/metadata-info/linkify.directive.ts
@@ -0,0 +1,38 @@
+/* eslint-disable @angular-eslint/directive-selector */
+import { Directive, ElementRef, Renderer2, OnInit } from '@angular/core'
+
+@Directive({
+ selector: '[gnUiLinkify]',
+})
+export class GnUiLinkifyDirective implements OnInit {
+ constructor(private el: ElementRef, private renderer: Renderer2) {}
+
+ ngOnInit() {
+ setTimeout(() => {
+ this.processLinks()
+ }, 0)
+ }
+
+ private processLinks() {
+ const container = this.el.nativeElement
+
+ const nodes = Array.from(container.childNodes)
+ nodes.forEach((node) => {
+ if (node instanceof Text) {
+ const textNode = node as Text
+ const linkified = this.linkifyText(textNode.nodeValue)
+ const span = this.renderer.createElement('span')
+ span.innerHTML = linkified
+ container.insertBefore(span, textNode)
+ container.removeChild(textNode)
+ }
+ })
+ }
+
+ private linkifyText(text: string): string {
+ return text.replace(/(\bhttps?:\/\/\S+\b)/g, (match) => {
+ return `${match} open_in_new`
+ })
+ }
+}
diff --git a/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html b/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html
index e37afb9ca7..fe1fb2cf6a 100644
--- a/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html
+++ b/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html
@@ -32,7 +32,7 @@
*ngIf="metadata.lineage"
[title]="'record.metadata.origin' | translate"
>
-
+
{{ metadata.lineage }}
record.metadata.isOpenData
-
+
{{ constraint }}
diff --git a/libs/ui/elements/src/lib/ui-elements.module.ts b/libs/ui/elements/src/lib/ui-elements.module.ts
index d67290b3b3..74a897c6bb 100644
--- a/libs/ui/elements/src/lib/ui-elements.module.ts
+++ b/libs/ui/elements/src/lib/ui-elements.module.ts
@@ -23,6 +23,7 @@ import { UiInputsModule } from '@geonetwork-ui/ui/inputs'
import { FormsModule } from '@angular/forms'
import { AvatarComponent } from './avatar/avatar.component'
import { UserPreviewComponent } from './user-preview/user-preview.component'
+import { GnUiLinkifyDirective } from './metadata-info/linkify.directive'
@NgModule({
imports: [
@@ -53,6 +54,7 @@ import { UserPreviewComponent } from './user-preview/user-preview.component'
ThumbnailComponent,
AvatarComponent,
UserPreviewComponent,
+ GnUiLinkifyDirective,
],
exports: [
MetadataInfoComponent,