diff --git a/apps/datahub/src/app/app.module.ts b/apps/datahub/src/app/app.module.ts index 9080984953..40576e5773 100644 --- a/apps/datahub/src/app/app.module.ts +++ b/apps/datahub/src/app/app.module.ts @@ -102,7 +102,7 @@ import { matStarOutline, } from '@ng-icons/material-icons/outline' import { NgIconsModule, provideNgIconsConfig } from '@ng-icons/core' -import { MAX_FEATURE_COUNT } from './record/record-metadata/record-metadata.component' +import { MAX_FEATURE_COUNT } from './record/record-data-preview/record-data-preview.component' export const metaReducers: MetaReducer[] = !environment.production ? [] : [] diff --git a/apps/datahub/src/app/record/record-data-preview/record-data-preview.component.css b/apps/datahub/src/app/record/record-data-preview/record-data-preview.component.css new file mode 100644 index 0000000000..853d4fe426 --- /dev/null +++ b/apps/datahub/src/app/record/record-data-preview/record-data-preview.component.css @@ -0,0 +1,39 @@ +/* TODO(mdc-migration): The following rule targets internal classes of tabs that may no longer apply for the MDC version. */ +::ng-deep .mat-mdc-tab-labels { + /* move tabs on the right to let the title show */ + margin-left: 140px; +} +::ng-deep .mat-mdc-tab.mdc-tab { + letter-spacing: 0.88px; +} +::ng-deep .mat-mdc-tab.mdc-tab:hover .tab-header-label { + color: var(--color-primary-darkest); +} +::ng-deep .mat-mdc-tab.mdc-tab.mdc-tab--active .tab-header-label { + opacity: 100%; + font-weight: bold; +} +::ng-deep .mdc-tab-indicator--active .mdc-tab-indicator__content { + border: none !important; +} +::ng-deep .mdc-tab__ripple::before { + background-color: transparent !important; +} +@media only screen and (max-width: 639px) { + /* TODO(mdc-migration): The following rule targets internal classes of tabs that may no longer apply for the MDC version. */ + ::ng-deep .mat-mdc-tab-labels { + margin-left: 0px; + } + ::ng-deep .mat-mdc-tab.mdc-tab { + padding: 0px !important; + margin-right: 24px; + justify-content: left !important; + } + /*hide chart tab on mobile*/ + ::ng-deep .mat-mdc-tab.mdc-tab:nth-child(3) { + display: none; + } +} +.tab-header-label { + @apply uppercase text-sm text-primary opacity-75 hover:text-primary-darker; +} diff --git a/apps/datahub/src/app/record/record-data-preview/record-data-preview.component.html b/apps/datahub/src/app/record/record-data-preview/record-data-preview.component.html new file mode 100644 index 0000000000..8b473a62cc --- /dev/null +++ b/apps/datahub/src/app/record/record-data-preview/record-data-preview.component.html @@ -0,0 +1,81 @@ +
+
+
+
+
+ record.metadata.preview +
+ + + + record.tab.map + +
+ +
+
+ + + record.tab.data + +
+ +
+
+ + + record.tab.chart + +
+ + + record.feature.limit + + + + + +
+
+
+
+
+
+
+ diff --git a/apps/datahub/src/app/record/record-data-preview/record-data-preview.component.spec.ts b/apps/datahub/src/app/record/record-data-preview/record-data-preview.component.spec.ts new file mode 100644 index 0000000000..424b03925e --- /dev/null +++ b/apps/datahub/src/app/record/record-data-preview/record-data-preview.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing' +import { RecordDataPreviewComponent } from './record-data-preview.component' + +describe('RecordDataPreviewComponent', () => { + let component: RecordDataPreviewComponent + let fixture: ComponentFixture + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [RecordDataPreviewComponent], + }).compileComponents() + + fixture = TestBed.createComponent(RecordDataPreviewComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it('should create', () => { + expect(component).toBeTruthy() + }) +}) diff --git a/apps/datahub/src/app/record/record-data-preview/record-data-preview.component.ts b/apps/datahub/src/app/record/record-data-preview/record-data-preview.component.ts new file mode 100644 index 0000000000..94096b159d --- /dev/null +++ b/apps/datahub/src/app/record/record-data-preview/record-data-preview.component.ts @@ -0,0 +1,122 @@ +import { CommonModule } from '@angular/common' +import { + ChangeDetectionStrategy, + Component, + Inject, + InjectionToken, + Optional, +} from '@angular/core' +import { MatTabsModule } from '@angular/material/tabs' +import { DataService } from '@geonetwork-ui/feature/dataviz' +import { + DataViewComponent, + DataViewShareComponent, + MapViewComponent, + MdViewFacade, +} from '@geonetwork-ui/feature/record' +import { PopupAlertComponent } from '@geonetwork-ui/ui/widgets' +import { TranslateModule } from '@ngx-translate/core' +import { + BehaviorSubject, + combineLatest, + map, + of, + startWith, + switchMap, +} from 'rxjs' + +export const MAX_FEATURE_COUNT = new InjectionToken('maxFeatureCount') + +@Component({ + selector: 'datahub-record-data-preview', + templateUrl: './record-data-preview.component.html', + styleUrls: ['./record-data-preview.component.css'], + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [ + CommonModule, + MatTabsModule, + TranslateModule, + DataViewShareComponent, + DataViewComponent, + MapViewComponent, + PopupAlertComponent, + ], +}) +export class RecordDataPreviewComponent { + displayMap$ = combineLatest([ + this.metadataViewFacade.mapApiLinks$, + this.metadataViewFacade.geoDataLinksWithGeometry$, + ]).pipe( + map(([mapApiLinks, geoDataLinksWithGeometry]) => { + return mapApiLinks?.length > 0 || geoDataLinksWithGeometry?.length > 0 + }), + startWith(false) + ) + + displayData$ = combineLatest([ + this.metadataViewFacade.dataLinks$, + this.metadataViewFacade.geoDataLinks$, + ]).pipe( + map( + ([dataLinks, geoDataLinks]) => + dataLinks?.length > 0 || geoDataLinks?.length > 0 + ) + ) + + exceedsMaxFeatureCount$ = + this.metadataViewFacade.geoDataLinksWithGeometry$.pipe( + map( + (links) => + links.filter((link) => link.accessServiceProtocol === 'wfs')[0] + ), + switchMap((link) => + link + ? this.dataService + .getWfsFeatureCount(link.url.toString(), link.name) + .pipe(map((count) => !count || count > this.maxFeatureCount)) + : of(false) + ) + ) + + selectedView$ = new BehaviorSubject('map') + + displayViewShare$ = combineLatest([ + this.displayMap$, + this.displayData$, + this.selectedView$, + this.exceedsMaxFeatureCount$, + ]).pipe( + map( + ([displayMap, displayData, selectedView, exceedsMaxFeatureCount]) => + (displayData || displayMap) && + !(selectedView === 'chart' && exceedsMaxFeatureCount) + ) + ) + + constructor( + public metadataViewFacade: MdViewFacade, + private dataService: DataService, + @Inject(MAX_FEATURE_COUNT) + @Optional() + protected maxFeatureCount: number + ) {} + + onTabIndexChange(index: number): void { + let view + switch (index) { + case 0: + view = 'map' + break + case 1: + view = 'table' + break + default: + view = 'chart' + } + this.selectedView$.next(view) + setTimeout(() => { + window.dispatchEvent(new Event('resize')) + }, 0) + } +} diff --git a/apps/datahub/src/app/record/record-metadata/record-metadata.component.css b/apps/datahub/src/app/record/record-metadata/record-metadata.component.css index 55d8c876f6..2d66e5922f 100644 --- a/apps/datahub/src/app/record/record-metadata/record-metadata.component.css +++ b/apps/datahub/src/app/record/record-metadata/record-metadata.component.css @@ -1,43 +1,3 @@ -/* TODO(mdc-migration): The following rule targets internal classes of tabs that may no longer apply for the MDC version. */ -::ng-deep .mat-mdc-tab-labels { - /* move tabs on the right to let the title show */ - margin-left: 140px; -} -::ng-deep .mat-mdc-tab.mdc-tab { - letter-spacing: 0.88px; -} -::ng-deep .mat-mdc-tab.mdc-tab:hover .tab-header-label { - color: var(--color-primary-darkest); -} -::ng-deep .mat-mdc-tab.mdc-tab.mdc-tab--active .tab-header-label { - opacity: 100%; - font-weight: bold; -} -::ng-deep .mdc-tab-indicator--active .mdc-tab-indicator__content { - border: none !important; -} -::ng-deep .mdc-tab__ripple::before { - background-color: transparent !important; -} -@media only screen and (max-width: 639px) { - /* TODO(mdc-migration): The following rule targets internal classes of tabs that may no longer apply for the MDC version. */ - ::ng-deep .mat-mdc-tab-labels { - margin-left: 0px; - } - ::ng-deep .mat-mdc-tab.mdc-tab { - padding: 0px !important; - margin-right: 24px; - justify-content: left !important; - } - /*hide chart tab on mobile*/ - ::ng-deep .mat-mdc-tab.mdc-tab:nth-child(3) { - display: none; - } -} .tracking-wider { letter-spacing: 0.88px; } - -.tab-header-label { - @apply uppercase text-sm text-primary opacity-75 hover:text-primary-darker; -} diff --git a/apps/datahub/src/app/record/record-metadata/record-metadata.component.html b/apps/datahub/src/app/record/record-metadata/record-metadata.component.html index 97a679951e..69fa60b0c5 100644 --- a/apps/datahub/src/app/record/record-metadata/record-metadata.component.html +++ b/apps/datahub/src/app/record/record-metadata/record-metadata.component.html @@ -53,89 +53,7 @@ -
-
-
-
-
- record.metadata.preview -
- - - - record.tab.map - -
- -
-
- - - record.tab.data - -
- -
-
- - - record.tab.chart - -
- - - record.feature.limit - - - - - -
-
-
-
-
-
-
- +
('maxFeatureCount') @Component({ selector: 'datahub-record-metadata', templateUrl: './record-metadata.component.html', @@ -64,41 +43,18 @@ export const MAX_FEATURE_COUNT = new InjectionToken('maxFeatureCount') RecordDownloadsComponent, RecordApisComponent, RecordOtherlinksComponent, - DataViewShareComponent, MetadataInfoComponent, MetadataContactComponent, MetadataQualityComponent, MetadataCatalogComponent, RecordRelatedRecordsComponent, - DataViewComponent, - MapViewComponent, TranslateModule, - PopupAlertComponent, + RecordDataPreviewComponent, ], }) export class RecordMetadataComponent { @Input() metadataQualityDisplay: boolean - displayMap$ = combineLatest([ - this.metadataViewFacade.mapApiLinks$, - this.metadataViewFacade.geoDataLinksWithGeometry$, - ]).pipe( - map(([mapApiLinks, geoDataLinksWithGeometry]) => { - return mapApiLinks?.length > 0 || geoDataLinksWithGeometry?.length > 0 - }), - startWith(false) - ) - - displayData$ = combineLatest([ - this.metadataViewFacade.dataLinks$, - this.metadataViewFacade.geoDataLinks$, - ]).pipe( - map( - ([dataLinks, geoDataLinks]) => - dataLinks?.length > 0 || geoDataLinks?.length > 0 - ) - ) - displayDownload$ = this.metadataViewFacade.downloadLinks$.pipe( map((links) => links?.length > 0) ) @@ -128,21 +84,6 @@ export class RecordMetadataComponent { ) ) - exceedsMaxFeatureCount$ = - this.metadataViewFacade.geoDataLinksWithGeometry$.pipe( - map( - (links) => - links.filter((link) => link.accessServiceProtocol === 'wfs')[0] - ), - switchMap((link) => - link - ? this.dataService - .getWfsFeatureCount(link.url.toString(), link.name) - .pipe(map((count) => !count || count > this.maxFeatureCount)) - : of(false) - ) - ) - organisationName$ = this.metadataViewFacade.metadata$.pipe( map((record) => record?.ownerOrganization?.name), filter(Boolean) @@ -161,21 +102,6 @@ export class RecordMetadataComponent { errorTypes = ErrorType - selectedView$ = new BehaviorSubject('map') - - displayViewShare$ = combineLatest([ - this.displayMap$, - this.displayData$, - this.selectedView$, - this.exceedsMaxFeatureCount$, - ]).pipe( - map( - ([displayMap, displayData, selectedView, exceedsMaxFeatureCount]) => - (displayData || displayMap) && - !(selectedView === 'chart' && exceedsMaxFeatureCount) - ) - ) - thumbnailUrl$ = this.metadataViewFacade.metadata$.pipe( map((metadata) => { // in order to differentiate between metadata not loaded yet @@ -195,31 +121,9 @@ export class RecordMetadataComponent { public metadataViewFacade: MdViewFacade, private searchService: SearchService, private sourceService: SourcesService, - private orgsService: OrganizationsServiceInterface, - private dataService: DataService, - @Inject(MAX_FEATURE_COUNT) - @Optional() - protected maxFeatureCount: number + private orgsService: OrganizationsServiceInterface ) {} - onTabIndexChange(index: number): void { - let view - switch (index) { - case 0: - view = 'map' - break - case 1: - view = 'table' - break - default: - view = 'chart' - } - this.selectedView$.next(view) - setTimeout(() => { - window.dispatchEvent(new Event('resize')) - }, 0) - } - onInfoKeywordClick(keyword: Keyword) { this.searchService.updateFilters({ any: keyword.label }) }