Skip to content

Commit 0f0f6b9

Browse files
authored
Merge pull request #974 from nsemets/fix/ENG-10348
[ENG-10348] Funder information, Language, Subject and Resource type should be included on the registration and project overview page metadata panes
2 parents d8f827c + df398ac commit 0f0f6b9

28 files changed

Lines changed: 384 additions & 210 deletions

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/features/files/components/edit-file-metadata-dialog/edit-file-metadata-dialog.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Select } from 'primeng/select';
88
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
99
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
1010

11-
import { languageCodes } from '@osf/shared/constants/language.const';
11+
import { LANGUAGE_CODES } from '@osf/shared/constants/language.const';
1212
import { resourceTypes } from '@osf/shared/constants/resource-types.const';
1313

1414
import { OsfFileCustomMetadata, PatchFileMetadata } from '../../models';
@@ -22,7 +22,7 @@ import { OsfFileCustomMetadata, PatchFileMetadata } from '../../models';
2222
})
2323
export class EditFileMetadataDialogComponent {
2424
readonly resourceTypes = resourceTypes;
25-
readonly languages = languageCodes;
25+
readonly languages = LANGUAGE_CODES;
2626

2727
private readonly dialogRef = inject(DynamicDialogRef);
2828
readonly config = inject(DynamicDialogConfig);

src/app/features/files/components/file-metadata/file-metadata.component.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { MockProvider } from 'ng-mocks';
33
import { ComponentFixture, TestBed } from '@angular/core/testing';
44
import { ActivatedRoute, Router } from '@angular/router';
55

6-
import { languageCodes } from '@osf/shared/constants/language.const';
6+
import { LANGUAGE_CODES } from '@osf/shared/constants/language.const';
77
import { CustomDialogService } from '@osf/shared/services/custom-dialog.service';
88

99
import { provideOSFCore } from '@testing/osf.testing.provider';
@@ -64,7 +64,7 @@ describe('FileMetadataComponent', () => {
6464
expect(component.fileMetadata).toBeDefined();
6565
expect(component.isLoading).toBeDefined();
6666
expect(component.hasWriteAccess).toBeDefined();
67-
expect(component.languageCodes).toBe(languageCodes);
67+
expect(component.languageCodes).toBe(LANGUAGE_CODES);
6868
expect(component.metadataFields).toBe(FileMetadataFields);
6969
});
7070

src/app/features/files/components/file-metadata/file-metadata.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { toSignal } from '@angular/core/rxjs-interop';
1212
import { ActivatedRoute, Router } from '@angular/router';
1313

1414
import { ENVIRONMENT } from '@core/provider/environment.provider';
15-
import { languageCodes } from '@osf/shared/constants/language.const';
15+
import { LANGUAGE_CODES } from '@osf/shared/constants/language.const';
1616
import { CustomDialogService } from '@osf/shared/services/custom-dialog.service';
1717
import { ViewOnlyLinkHelperService } from '@osf/shared/services/view-only-link-helper.service';
1818
import { LanguageCodeModel } from '@shared/models/language-code.model';
@@ -44,7 +44,7 @@ export class FileMetadataComponent {
4444

4545
hasViewOnly = computed(() => this.viewOnlyService.hasViewOnlyParam(this.router));
4646

47-
readonly languageCodes = languageCodes;
47+
readonly languageCodes = LANGUAGE_CODES;
4848

4949
readonly fileGuid = toSignal(this.route.params.pipe(map((params) => params['fileGuid'])));
5050

src/app/features/metadata/components/metadata-resource-information/metadata-resource-information.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ <h2>
2626
<div class="flex-column flex gap-2">
2727
<p class="inline-block font-bold" data-test-display-resource-type-general>
2828
<span> {{ 'project.overview.metadata.resourceType' | translate }}: </span>
29-
<span>{{ getResourceTypeName(customItemMetadata()?.resourceTypeGeneral!) }}</span>
29+
<span>{{ customItemMetadata()?.resourceTypeGeneral | resourceTypeGeneralLabel }}</span>
3030
</p>
3131

3232
<p class="inline-block font-bold" data-test-display-resource-language>
3333
<span> {{ 'project.overview.metadata.resourceLanguage' | translate }}: </span>
34-
<span>{{ getLanguageName(customItemMetadata()?.language || '') }}</span>
34+
<span>{{ customItemMetadata()?.language | languageLabel }}</span>
3535
</p>
3636
</div>
3737
} @else {

src/app/features/metadata/components/metadata-resource-information/metadata-resource-information.component.ts

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ import { Card } from 'primeng/card';
55

66
import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';
77

8-
import { RESOURCE_TYPE_OPTIONS } from '@osf/features/metadata/constants';
98
import { CustomItemMetadataRecord } from '@osf/features/metadata/models';
10-
import { languageCodes } from '@osf/shared/constants/language.const';
11-
import { LanguageCodeModel } from '@shared/models/language-code.model';
9+
import { LanguageLabelPipe } from '@osf/shared/pipes/language-label.pipe';
10+
import { ResourceTypeGeneralLabelPipe } from '@osf/shared/pipes/resource-type-general-label.pipe';
1211

1312
@Component({
1413
selector: 'osf-metadata-resource-information',
15-
imports: [Button, Card, TranslatePipe],
14+
imports: [Button, Card, TranslatePipe, LanguageLabelPipe, ResourceTypeGeneralLabelPipe],
1615
templateUrl: './metadata-resource-information.component.html',
1716
changeDetection: ChangeDetectionStrategy.OnPush,
1817
})
@@ -22,17 +21,4 @@ export class MetadataResourceInformationComponent {
2221
customItemMetadata = input.required<CustomItemMetadataRecord | null>();
2322
readonly = input<boolean>(false);
2423
showResourceInfo = output<void>();
25-
26-
readonly languageCodes = languageCodes;
27-
readonly resourceTypes = RESOURCE_TYPE_OPTIONS;
28-
29-
getLanguageName(languageCode: string): string {
30-
const language = this.languageCodes.find((lang: LanguageCodeModel) => lang.code === languageCode);
31-
return language ? language.name : languageCode;
32-
}
33-
34-
getResourceTypeName(resourceType: string): string {
35-
const resource = this.resourceTypes.find((res) => res.value === resourceType);
36-
return resource ? resource.label : resourceType;
37-
}
3824
}
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
export * from './cedar-config.const';
2-
export * from './resource-type-options.const';

src/app/features/metadata/dialogs/resource-information-dialog/resource-information-dialog.component.html

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66

77
<p-select
88
id="resourceType"
9+
class="w-full"
10+
appendTo="body"
11+
data-test-select-resource-type
912
[formControl]="resourceForm.controls.resourceType"
1013
[options]="resourceTypeOptions"
1114
optionLabel="label"
1215
optionValue="value"
1316
[placeholder]="'common.buttons.select' | translate"
14-
appendTo="body"
15-
class="w-full"
16-
data-test-select-resource-type
1717
/>
1818
</div>
1919

@@ -24,22 +24,19 @@
2424

2525
<p-select
2626
id="resourceLanguage"
27+
class="w-full"
28+
data-test-select-resource-language
29+
appendTo="body"
2730
[filter]="true"
2831
filterBy="label"
2932
[formControl]="resourceForm.controls.resourceLanguage"
3033
[options]="languageOptions"
31-
optionLabel="label"
32-
optionValue="value"
34+
optionLabel="name"
35+
optionValue="code"
3336
[placeholder]="'common.buttons.select' | translate"
34-
appendTo="body"
3537
[virtualScroll]="true"
3638
[virtualScrollItemSize]="35"
37-
class="w-full"
38-
data-test-select-resource-language
3939
>
40-
<ng-template #item let-option>
41-
<span>{{ option.label }}</span>
42-
</ng-template>
4340
</p-select>
4441
</div>
4542

src/app/features/metadata/dialogs/resource-information-dialog/resource-information-dialog.component.spec.ts

Lines changed: 32 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { ResourceInformationDialogComponent } from './resource-information-dialo
1212
describe('ResourceInformationDialogComponent', () => {
1313
let component: ResourceInformationDialogComponent;
1414
let fixture: ComponentFixture<ResourceInformationDialogComponent>;
15+
let dialogRef: DynamicDialogRef;
16+
let config: DynamicDialogConfig;
1517

1618
beforeEach(() => {
1719
TestBed.configureTestingModule({
@@ -21,83 +23,58 @@ describe('ResourceInformationDialogComponent', () => {
2123

2224
fixture = TestBed.createComponent(ResourceInformationDialogComponent);
2325
component = fixture.componentInstance;
26+
dialogRef = TestBed.inject(DynamicDialogRef);
27+
config = TestBed.inject(DynamicDialogConfig);
2428
});
2529

2630
it('should create', () => {
2731
expect(component).toBeTruthy();
2832
});
2933

30-
it('should have resource type options', () => {
31-
expect(component.resourceTypeOptions).toBeDefined();
32-
expect(component.resourceTypeOptions.length).toBeGreaterThan(0);
33-
});
34-
35-
it('should have language options', () => {
36-
expect(component.languageOptions).toBeDefined();
37-
expect(component.languageOptions.length).toBeGreaterThan(0);
38-
});
34+
it('should patch form values on init when metadata is provided', () => {
35+
config.data = {
36+
customItemMetadata: {
37+
resourceTypeGeneral: 'Dataset',
38+
language: 'eng',
39+
},
40+
};
3941

40-
it('should not save when form is invalid', () => {
41-
const dialogRef = TestBed.inject(DynamicDialogRef);
42-
const closeSpy = vi.spyOn(dialogRef, 'close');
42+
component.ngOnInit();
4343

44-
component.resourceForm.patchValue({
45-
resourceType: 'dataset',
46-
resourceLanguage: 'en',
44+
expect(component.resourceForm.getRawValue()).toEqual({
45+
resourceType: 'Dataset',
46+
resourceLanguage: 'eng',
4747
});
48+
});
4849

49-
component.save();
50+
it('should keep default empty values on init when metadata is not provided', () => {
51+
config.data = {};
5052

51-
expect(closeSpy).toHaveBeenCalledWith({
52-
resourceTypeGeneral: 'dataset',
53-
language: 'en',
53+
component.ngOnInit();
54+
55+
expect(component.resourceForm.getRawValue()).toEqual({
56+
resourceType: '',
57+
resourceLanguage: '',
5458
});
5559
});
5660

57-
it('should not save when resource type is missing', () => {
58-
const dialogRef = TestBed.inject(DynamicDialogRef);
59-
const closeSpy = vi.spyOn(dialogRef, 'close');
60-
61-
component.resourceForm.patchValue({
62-
resourceType: '',
63-
resourceLanguage: 'en',
61+
it('should close dialog with mapped payload on save when form is valid', () => {
62+
component.resourceForm.setValue({
63+
resourceType: 'JournalArticle',
64+
resourceLanguage: 'deu',
6465
});
6566

6667
component.save();
6768

68-
expect(closeSpy).toHaveBeenCalledWith({
69-
resourceTypeGeneral: '',
70-
language: 'en',
69+
expect(dialogRef.close).toHaveBeenCalledWith({
70+
resourceTypeGeneral: 'JournalArticle',
71+
language: 'deu',
7172
});
7273
});
7374

74-
it('should cancel dialog', () => {
75-
const dialogRef = TestBed.inject(DynamicDialogRef);
76-
const closeSpy = vi.spyOn(dialogRef, 'close');
77-
75+
it('should close dialog without payload on cancel', () => {
7876
component.cancel();
7977

80-
expect(closeSpy).toHaveBeenCalled();
81-
});
82-
83-
it('should validate required fields', () => {
84-
const resourceTypeControl = component.resourceForm.get('resourceType');
85-
86-
expect(resourceTypeControl?.hasError('required')).toBe(false);
87-
88-
resourceTypeControl?.setValue('dataset');
89-
90-
expect(resourceTypeControl?.hasError('required')).toBe(false);
91-
});
92-
93-
it('should handle form validation state', () => {
94-
expect(component.resourceForm.valid).toBe(true);
95-
96-
component.resourceForm.patchValue({
97-
resourceType: 'dataset',
98-
resourceLanguage: 'en',
99-
});
100-
101-
expect(component.resourceForm.valid).toBe(true);
78+
expect(dialogRef.close).toHaveBeenCalledWith();
10279
});
10380
});

src/app/features/metadata/dialogs/resource-information-dialog/resource-information-dialog.component.ts

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ import { Select } from 'primeng/select';
77
import { ChangeDetectionStrategy, Component, inject, OnInit } from '@angular/core';
88
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
99

10-
import { languageCodes } from '@osf/shared/constants/language.const';
11-
import { LanguageCodeModel } from '@shared/models/language-code.model';
10+
import { LANGUAGE_CODES } from '@osf/shared/constants/language.const';
11+
import { RESOURCE_TYPE_GENERAL_OPTIONS } from '@osf/shared/constants/resource-type-general-options.const';
1212

13-
import { RESOURCE_TYPE_OPTIONS } from '../../constants';
14-
import { CustomItemMetadataRecord, ResourceInformationForm } from '../../models';
13+
import { ResourceInformationForm } from '../../models';
1514

1615
@Component({
1716
selector: 'osf-resource-information-dialog',
@@ -28,26 +27,12 @@ export class ResourceInformationDialogComponent implements OnInit {
2827
resourceLanguage: new FormControl(''),
2928
});
3029

31-
resourceTypeOptions = RESOURCE_TYPE_OPTIONS;
32-
languageOptions = languageCodes.map((lang: LanguageCodeModel) => ({
33-
label: lang.name,
34-
value: lang.code,
35-
}));
36-
37-
get customItemMetadata(): CustomItemMetadataRecord | null {
38-
return this.config.data?.customItemMetadata || null;
39-
}
40-
41-
get isEditMode(): boolean {
42-
return !!this.customItemMetadata;
43-
}
44-
45-
getResourceTypeName(resourceType: string): string {
46-
return Object.fromEntries(RESOURCE_TYPE_OPTIONS.map((item) => [item.value, item.label]))[resourceType];
47-
}
30+
resourceTypeOptions = RESOURCE_TYPE_GENERAL_OPTIONS;
31+
languageOptions = LANGUAGE_CODES;
4832

4933
ngOnInit(): void {
50-
const metadata = this.customItemMetadata;
34+
const metadata = this.config.data?.customItemMetadata;
35+
5136
if (metadata) {
5237
this.resourceForm.patchValue({
5338
resourceType: metadata.resourceTypeGeneral || '',
@@ -57,13 +42,11 @@ export class ResourceInformationDialogComponent implements OnInit {
5742
}
5843

5944
save(): void {
60-
if (this.resourceForm.valid) {
61-
const formValue = this.resourceForm.getRawValue();
62-
this.dialogRef.close({
63-
resourceTypeGeneral: formValue.resourceType,
64-
language: formValue.resourceLanguage,
65-
});
66-
}
45+
const formValue = this.resourceForm.getRawValue();
46+
this.dialogRef.close({
47+
resourceTypeGeneral: formValue.resourceType,
48+
language: formValue.resourceLanguage,
49+
});
6750
}
6851

6952
cancel(): void {

0 commit comments

Comments
 (0)