Skip to content

Commit 26f117e

Browse files
authored
[ENG-10048] Add Registry Name to Registration Metadata (#858)
- Ticket: [ENG-10048] - Feature flag: n/a ## Summary of Changes 1. Added registry info to overview and metadata pages.
1 parent 61cf622 commit 26f117e

15 files changed

Lines changed: 187 additions & 2 deletions

src/app/features/metadata/components/metadata-date-info/metadata-date-info.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ <h2>
55
{{ 'project.overview.metadata.dateCreated' | translate }}
66
</h2>
77

8-
<p class="m-0">
8+
<p class="mt-4">
99
{{ dateCreated() | date: dateFormat }}
1010
</p>
1111
</div>
@@ -15,7 +15,7 @@ <h2>
1515
{{ 'project.overview.metadata.dateUpdated' | translate }}
1616
</h2>
1717

18-
<p class="m-0">
18+
<p class="mt-4">
1919
{{ dateModified() | date: dateFormat }}
2020
</p>
2121
</div>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<p-card>
2+
<div class="flex justify-content-between flex-wrap gap-4">
3+
<div class="flex flex-column gap-2 flex-1">
4+
<h2>{{ 'registry.overview.metadata.type' | translate }}</h2>
5+
<p data-test-display-registry-type class="mt-4">{{ type() }}</p>
6+
</div>
7+
8+
<div class="flex flex-column gap-2 flex-1">
9+
<h2>{{ 'registry.overview.metadata.registry' | translate }}</h2>
10+
<p data-test-display-registry-provider class="mt-4">{{ provider()?.name }}</p>
11+
</div>
12+
</div>
13+
</p-card>

src/app/features/metadata/components/metadata-registry-info/metadata-registry-info.component.scss

Whitespace-only changes.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { RegistryProviderDetails } from '@osf/shared/models/provider/registry-provider.model';
4+
5+
import { MetadataRegistryInfoComponent } from './metadata-registry-info.component';
6+
7+
import { OSFTestingModule } from '@testing/osf.testing.module';
8+
9+
describe('MetadataRegistryInfoComponent', () => {
10+
let component: MetadataRegistryInfoComponent;
11+
let fixture: ComponentFixture<MetadataRegistryInfoComponent>;
12+
13+
const mockProvider: RegistryProviderDetails = {
14+
id: 'test-provider-id',
15+
name: 'Test Registry Provider',
16+
descriptionHtml: '<p>Test description</p>',
17+
permissions: [],
18+
brand: null,
19+
iri: 'https://example.com/registry',
20+
reviewsWorkflow: 'standard',
21+
};
22+
23+
beforeEach(async () => {
24+
await TestBed.configureTestingModule({
25+
imports: [MetadataRegistryInfoComponent, OSFTestingModule],
26+
}).compileComponents();
27+
28+
fixture = TestBed.createComponent(MetadataRegistryInfoComponent);
29+
component = fixture.componentInstance;
30+
});
31+
32+
it('should create', () => {
33+
expect(component).toBeTruthy();
34+
});
35+
36+
it('should initialize with default values', () => {
37+
expect(component.type()).toBe('');
38+
expect(component.provider()).toBeUndefined();
39+
});
40+
41+
it('should set type input', () => {
42+
const mockType = 'Clinical Trial';
43+
fixture.componentRef.setInput('type', mockType);
44+
fixture.detectChanges();
45+
46+
expect(component.type()).toBe(mockType);
47+
});
48+
49+
it('should set provider input', () => {
50+
fixture.componentRef.setInput('provider', mockProvider);
51+
fixture.detectChanges();
52+
53+
expect(component.provider()).toEqual(mockProvider);
54+
});
55+
56+
it('should handle undefined type input', () => {
57+
fixture.componentRef.setInput('type', undefined);
58+
fixture.detectChanges();
59+
60+
expect(component.type()).toBeUndefined();
61+
});
62+
63+
it('should handle null provider input', () => {
64+
fixture.componentRef.setInput('provider', null);
65+
fixture.detectChanges();
66+
67+
expect(component.provider()).toBeNull();
68+
});
69+
70+
it('should render type in template', () => {
71+
const mockType = 'Preprint';
72+
fixture.componentRef.setInput('type', mockType);
73+
fixture.detectChanges();
74+
75+
const compiled = fixture.nativeElement;
76+
const typeElement = compiled.querySelector('[data-test-display-registry-type]');
77+
expect(typeElement).toBeTruthy();
78+
expect(typeElement.textContent.trim()).toBe(mockType);
79+
});
80+
81+
it('should render provider name in template', () => {
82+
fixture.componentRef.setInput('provider', mockProvider);
83+
fixture.detectChanges();
84+
85+
const compiled = fixture.nativeElement;
86+
const providerElement = compiled.querySelector('[data-test-display-registry-provider]');
87+
expect(providerElement).toBeTruthy();
88+
expect(providerElement.textContent.trim()).toBe(mockProvider.name);
89+
});
90+
91+
it('should display empty string when type is empty', () => {
92+
fixture.componentRef.setInput('type', '');
93+
fixture.detectChanges();
94+
95+
const compiled = fixture.nativeElement;
96+
const typeElement = compiled.querySelector('[data-test-display-registry-type]');
97+
expect(typeElement.textContent.trim()).toBe('');
98+
});
99+
100+
it('should display empty string when provider is null', () => {
101+
fixture.componentRef.setInput('provider', null);
102+
fixture.detectChanges();
103+
104+
const compiled = fixture.nativeElement;
105+
const providerElement = compiled.querySelector('[data-test-display-registry-provider]');
106+
expect(providerElement.textContent.trim()).toBe('');
107+
});
108+
109+
it('should display both type and provider when both are set', () => {
110+
const mockType = 'Registered Report';
111+
fixture.componentRef.setInput('type', mockType);
112+
fixture.componentRef.setInput('provider', mockProvider);
113+
fixture.detectChanges();
114+
115+
const compiled = fixture.nativeElement;
116+
const typeElement = compiled.querySelector('[data-test-display-registry-type]');
117+
const providerElement = compiled.querySelector('[data-test-display-registry-provider]');
118+
119+
expect(typeElement.textContent.trim()).toBe(mockType);
120+
expect(providerElement.textContent.trim()).toBe(mockProvider.name);
121+
});
122+
123+
it('should display translated labels', () => {
124+
fixture.detectChanges();
125+
126+
const compiled = fixture.nativeElement;
127+
const headings = compiled.querySelectorAll('h2');
128+
expect(headings.length).toBe(2);
129+
});
130+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { TranslatePipe } from '@ngx-translate/core';
2+
3+
import { Card } from 'primeng/card';
4+
5+
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
6+
7+
import { RegistryProviderDetails } from '@osf/shared/models/provider/registry-provider.model';
8+
9+
@Component({
10+
selector: 'osf-metadata-registry-info',
11+
imports: [Card, TranslatePipe],
12+
templateUrl: './metadata-registry-info.component.html',
13+
styleUrl: './metadata-registry-info.component.scss',
14+
changeDetection: ChangeDetectionStrategy.OnPush,
15+
})
16+
export class MetadataRegistryInfoComponent {
17+
type = input<string | undefined>('');
18+
provider = input<RegistryProviderDetails | null>();
19+
}

src/app/features/metadata/mappers/metadata.mapper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class MetadataMapper {
2525
provider: response.embeds?.provider?.data.id,
2626
public: response.attributes.public,
2727
currentUserPermissions: response.attributes.current_user_permissions,
28+
registrationSupplement: response.attributes.registration_supplement,
2829
};
2930
}
3031

src/app/features/metadata/metadata.component.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
[readonly]="!hasWriteAccess()"
3434
/>
3535

36+
@if (isRegistrationType()) {
37+
<osf-metadata-registry-info [type]="metadata()?.registrationSupplement" [provider]="registryProvider()" />
38+
}
39+
3640
<osf-metadata-date-info [dateCreated]="metadata()?.dateCreated" [dateModified]="metadata()?.dateModified" />
3741

3842
<osf-metadata-contributors

src/app/features/metadata/metadata.component.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { ResourceType } from '@osf/shared/enums/resource-type.enum';
2424
import { CustomConfirmationService } from '@osf/shared/services/custom-confirmation.service';
2525
import { CustomDialogService } from '@osf/shared/services/custom-dialog.service';
2626
import { ToastService } from '@osf/shared/services/toast.service';
27+
import { RegistrationProviderSelectors } from '@osf/shared/stores/registration-provider';
2728

2829
import { MetadataComponent } from './metadata.component';
2930

@@ -106,6 +107,7 @@ describe('MetadataComponent', () => {
106107
{ selector: MetadataSelectors.getSubmitting, value: false },
107108
{ selector: MetadataSelectors.getCedarRecords, value: [] },
108109
{ selector: MetadataSelectors.getCedarTemplates, value: null },
110+
{ selector: RegistrationProviderSelectors.getBrandedProvider, value: null },
109111
],
110112
}),
111113
],

src/app/features/metadata/metadata.component.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
InstitutionsSelectors,
3838
UpdateResourceInstitutions,
3939
} from '@osf/shared/stores/institutions';
40+
import { RegistrationProviderSelectors } from '@osf/shared/stores/registration-provider';
4041
import {
4142
FetchChildrenSubjects,
4243
FetchSelectedSubjects,
@@ -48,6 +49,7 @@ import { MetadataTabsModel } from '@shared/models/metadata-tabs.model';
4849
import { SubjectModel } from '@shared/models/subject/subject.model';
4950

5051
import { MetadataCollectionsComponent } from './components/metadata-collections/metadata-collections.component';
52+
import { MetadataRegistryInfoComponent } from './components/metadata-registry-info/metadata-registry-info.component';
5153
import { EditTitleDialogComponent } from './dialogs/edit-title-dialog/edit-title-dialog.component';
5254
import {
5355
MetadataAffiliatedInstitutionsComponent,
@@ -112,6 +114,7 @@ import {
112114
MetadataTitleComponent,
113115
MetadataRegistrationDoiComponent,
114116
MetadataCollectionsComponent,
117+
MetadataRegistryInfoComponent,
115118
],
116119
templateUrl: './metadata.component.html',
117120
styleUrl: './metadata.component.scss',
@@ -150,6 +153,7 @@ export class MetadataComponent implements OnInit {
150153
affiliatedInstitutions = select(InstitutionsSelectors.getResourceInstitutions);
151154
areInstitutionsLoading = select(InstitutionsSelectors.areResourceInstitutionsLoading);
152155
areResourceInstitutionsSubmitting = select(InstitutionsSelectors.areResourceInstitutionsSubmitting);
156+
registryProvider = select(RegistrationProviderSelectors.getBrandedProvider);
153157

154158
projectSubmissions = select(CollectionsSelectors.getCurrentProjectSubmissions);
155159
isProjectSubmissionsLoading = select(CollectionsSelectors.getCurrentProjectSubmissionsLoading);

src/app/features/metadata/models/metadata-json-api.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export interface MetadataAttributesJsonApi {
2121
category?: string;
2222
node_license?: LicenseRecordJsonApi;
2323
public?: boolean;
24+
registration_supplement?: string;
2425
current_user_permissions: UserPermissions[];
2526
}
2627

0 commit comments

Comments
 (0)