Skip to content
Merged
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
2 changes: 1 addition & 1 deletion src/app/core/components/nav-menu/nav-menu.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export class NavMenuComponent {

const isCollectionsWithId = urlSegments[0] === 'collections' && urlSegments[1] && urlSegments[1] !== '';
const isRegistryRoute = urlSegments[0] === 'registries' && !!urlSegments[2];
const isRegistryRouteDetails = urlSegments[0] === 'registries' && urlSegments[2];
const isRegistryRouteDetails = urlSegments[0] === 'registries' && urlSegments[2] === 'overview';

return {
resourceId,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<section class="registries-hero-container py-5 px-3 flex flex-column gap-4 md:py-6 md:px-4">
<div class="flex flex-column align-items-start gap-4 md:flex-row">
<div class="flex align-items-center gap-2">
@if (isProviderLoading()) {
<p-skeleton width="3rem" height="1.5rem" />
<p-skeleton width="12rem" height="1.5rem" />
} @else {
<img
class="preprint-provider-hero-logo"
alt="Provider Logo"
height="40"
[src]="provider()!.brand.heroLogoImageUrl"
/>
}
</div>
</div>

<div class="provider-description">
@if (isProviderLoading()) {
<div class="flex flex-column gap-2">
<p-skeleton width="40%" height="1.5rem"></p-skeleton>
<p-skeleton width="70%" height="1.5rem"></p-skeleton>

<p-skeleton width="10%" height="1rem"></p-skeleton>
</div>
} @else {
<div [innerHTML]="provider()!.descriptionHtml | decodeHtml"></div>
}
</div>

@if (isProviderLoading()) {
<p-skeleton class="w-full" height="3rem" />
} @else {
<div class="search-input-container">
<osf-search-input
class="w-full"
[showHelpIcon]="true"
[placeholder]="'preprints.searchPlaceholder' | translate: { preprintWord: 'Registrations' } | titlecase"
[control]="searchControl()"
(triggerSearch)="onTriggerSearch($event)"
(helpClicked)="openHelpDialog()"
/>
</div>
}
</section>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { RegistryProviderHeroComponent } from './registry-provider-hero.component';

describe('RegistryProviderHeroComponent', () => {
let component: RegistryProviderHeroComponent;
let fixture: ComponentFixture<RegistryProviderHeroComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RegistryProviderHeroComponent],
}).compileComponents();

fixture = TestBed.createComponent(RegistryProviderHeroComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { TranslatePipe, TranslateService } from '@ngx-translate/core';

import { DialogService } from 'primeng/dynamicdialog';
import { Skeleton } from 'primeng/skeleton';

import { TitleCasePipe } from '@angular/common';
import { ChangeDetectionStrategy, Component, effect, inject, input, output } from '@angular/core';
import { FormControl } from '@angular/forms';

import { PreprintsHelpDialogComponent } from '@osf/features/preprints/components';
import { RegistryProviderDetails } from '@osf/features/registries/models/registry-provider.model';
import { SearchInputComponent } from '@shared/components';
import { DecodeHtmlPipe } from '@shared/pipes';
import { BrandService } from '@shared/services';
import { HeaderStyleHelper } from '@shared/utils';

@Component({
selector: 'osf-registry-provider-hero',
imports: [DecodeHtmlPipe, SearchInputComponent, Skeleton, TitleCasePipe, TranslatePipe],
templateUrl: './registry-provider-hero.component.html',
styleUrl: './registry-provider-hero.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RegistryProviderHeroComponent {
protected translateService = inject(TranslateService);
protected dialogService = inject(DialogService);

searchControl = input<FormControl>(new FormControl());
provider = input.required<RegistryProviderDetails | null>();
isProviderLoading = input.required<boolean>();
triggerSearch = output<string>();

onTriggerSearch(value: string) {
this.triggerSearch.emit(value);
}

constructor() {
effect(() => {
const provider = this.provider();

if (provider) {
BrandService.applyBranding(provider.brand);
HeaderStyleHelper.applyHeaderStyles(
provider.brand.primaryColor,
undefined,
provider.brand.heroBackgroundImageUrl
);
}
});
}

openHelpDialog() {
this.dialogService.open(PreprintsHelpDialogComponent, {
focusOnShow: false,
header: this.translateService.instant('preprints.helpDialog.header'),
closeOnEscape: true,
modal: true,
closable: true,
});
}
}
22 changes: 22 additions & 0 deletions src/app/features/registries/mappers/providers.mapper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { RegistryProviderDetails } from '@osf/features/registries/models/registry-provider.model';
import { RegistryProviderDetailsJsonApi } from '@osf/features/registries/models/registry-provider-json-api.model';

import { ProviderSchema, ProvidersResponseJsonApi } from '../models';

export class ProvidersMapper {
Expand All @@ -7,4 +10,23 @@ export class ProvidersMapper {
name: item.attributes.name,
}));
}

static fromRegistryProvider(response: RegistryProviderDetailsJsonApi): RegistryProviderDetails {
const brandRaw = response.embeds!.brand.data;
return {
id: response.id,
name: response.attributes.name,
descriptionHtml: response.attributes.description,
brand: {
id: brandRaw.id,
name: brandRaw.attributes.name,
heroLogoImageUrl: brandRaw.attributes.hero_logo_image,
heroBackgroundImageUrl: brandRaw.attributes.hero_background_image,
topNavLogoImageUrl: brandRaw.attributes.topnav_logo_image,
primaryColor: brandRaw.attributes.primary_color,
secondaryColor: brandRaw.attributes.secondary_color,
},
iri: response.links.iri,
};
}
}
2 changes: 2 additions & 0 deletions src/app/features/registries/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ export * from './project';
export * from './projects-json-api.model';
export * from './provider-schema.model';
export * from './providers-json-api.model';
export * from './registry-provider.model';
export * from './registry-provider-json-api.model';
export * from './schema-blocks-json-api.model';
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { BrandDataJsonApi } from '@shared/models';

export interface RegistryProviderDetailsJsonApi {
id: string;
type: 'registration-providers';
attributes: {
name: string;
description: string;
};
embeds?: {
brand: {
data: BrandDataJsonApi;
};
};
links: {
iri: string;
};
}
9 changes: 9 additions & 0 deletions src/app/features/registries/models/registry-provider.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Brand } from '@shared/models';

export interface RegistryProviderDetails {
id: string;
name: string;
descriptionHtml: string;
brand: Brand;
iri: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<osf-registry-provider-hero
[searchControl]="searchControl"
[provider]="provider()"
[isProviderLoading]="isProviderLoading()"
></osf-registry-provider-hero>

<div class="flex flex-column flex-1 w-full">
<div class="py-4 px-3 md:px-5 xl:px-4 bg-white">
<osf-search-results-container
[resources]="resources()"
[searchCount]="resourcesCount()"
[selectedSort]="selectedSort()"
[selectedTab]="resourceType()"
[selectedValues]="selectedValues()"
[first]="first()"
[prev]="previous()"
[next]="next()"
[isFiltersOpen]="isFiltersOpen()"
[isSortingOpen]="isSortingOpen()"
[showTabs]="false"
(sortChanged)="onSortChanged($event)"
(pageChanged)="onPageChanged($event)"
(filtersToggled)="onFiltersToggled()"
(sortingToggled)="onSortingToggled()"
>
<div slot="filter-chips">
<osf-filter-chips
[selectedValues]="selectedValues()"
[filterLabels]="filterLabels()"
[filterOptions]="filterOptions()"
(filterRemoved)="onFilterChipRemoved($event)"
(allFiltersCleared)="onAllFiltersCleared()"
/>
</div>

<div slot="filters">
<osf-reusable-filters
[filters]="filters()"
[selectedValues]="selectedValues()"
[isLoading]="isResourcesLoading()"
[showEmptyState]="true"
(loadFilterOptions)="onLoadFilterOptions($event)"
(filterValueChanged)="onFilterChanged($event)"
/>
</div>

<div slot="mobile-filters">
<osf-reusable-filters
[filters]="filters()"
[selectedValues]="selectedValues()"
[isLoading]="isResourcesLoading()"
[showEmptyState]="true"
(loadFilterOptions)="onLoadFilterOptions($event)"
(filterValueChanged)="onFilterChanged($event)"
/>
</div>
</osf-search-results-container>

<osf-search-help-tutorial [(currentStep)]="currentStep"></osf-search-help-tutorial>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { RegistriesProviderSearchComponent } from './registries-provider-search.component';

describe('RegistriesProviderSearchComponent', () => {
let component: RegistriesProviderSearchComponent;
let fixture: ComponentFixture<RegistriesProviderSearchComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RegistriesProviderSearchComponent],
}).compileComponents();

fixture = TestBed.createComponent(RegistriesProviderSearchComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Loading