From 4188bd517c3f1bc31447c8bcabdc16137adc4219 Mon Sep 17 00:00:00 2001 From: FORESTIER Fabien <fabien.forestier@soprasteria.com> Date: Tue, 13 Aug 2019 17:28:16 +0200 Subject: [PATCH] Add reuse detail component --- src/app/editorialisation/components/index.ts | 3 + .../reuse-detail/reuse-detail.component.html | 35 +++++++ .../reuse-detail/reuse-detail.component.scss | 98 +++++++++++++++++++ .../reuse-detail/reuse-detail.component.ts | 79 +++++++++++++++ .../reuses-list/reuses-list.component.html | 31 +++--- .../reuses-list/reuses-list.component.scss | 4 + .../editorialisation-routing.module.ts | 13 ++- .../editorialisation/models/reuse.model.ts | 22 ++--- .../services/reuses.service.ts | 6 ++ src/i18n/messages.en.xlf | 5 + src/i18n/messages.fr.xlf | 4 + 11 files changed, 269 insertions(+), 31 deletions(-) create mode 100644 src/app/editorialisation/components/reuse-detail/reuse-detail.component.html create mode 100644 src/app/editorialisation/components/reuse-detail/reuse-detail.component.scss create mode 100644 src/app/editorialisation/components/reuse-detail/reuse-detail.component.ts diff --git a/src/app/editorialisation/components/index.ts b/src/app/editorialisation/components/index.ts index b7104f4a..609725ab 100644 --- a/src/app/editorialisation/components/index.ts +++ b/src/app/editorialisation/components/index.ts @@ -9,6 +9,7 @@ import { SiteMapComponent } from './site-map/site-map.component'; import { ChangelogComponent } from './changelog/changelog.component'; import { ContributionComponent } from './contribution/contribution.component'; import { ReusesListComponent } from './reuses-list/reuses-list.component'; +import { ReuseDetailComponent } from './reuse-detail/reuse-detail.component'; export { @@ -22,6 +23,7 @@ export { ChangelogComponent, ContributionComponent, ReusesListComponent, + ReuseDetailComponent, }; // tslint:disable-next-line:variable-name @@ -36,4 +38,5 @@ export const EditorialisationComponents = [ ChangelogComponent, ContributionComponent, ReusesListComponent, + ReuseDetailComponent, ]; diff --git a/src/app/editorialisation/components/reuse-detail/reuse-detail.component.html b/src/app/editorialisation/components/reuse-detail/reuse-detail.component.html new file mode 100644 index 00000000..0c75fda0 --- /dev/null +++ b/src/app/editorialisation/components/reuse-detail/reuse-detail.component.html @@ -0,0 +1,35 @@ +<section class="page-container is-fullwidth"> + + <div class="page-header-container"> + <app-page-header [pageInfo]="pageHeaderInfo"></app-page-header> + <img class="logo" [src]="reuse.logo" [alt]="reuse.name + 'logo'"> + </div> + + <div class="page-content"> + <div class="first-column"> + <span class="column-title"> + {{reuse.datasetsUsed ? reuse.datasetsUsed.length : 0 }} <span + *ngIf="reuse.datasetsUsed.length > 1; else oneReuse" i18n="@@reuses.ngDatasetsReused">datasets used</span> + <ng-template #oneReuse i18n="@@reuses.oneDatasetReused">dataset used</ng-template> + </span> + + <div class="dataset-list"> + <div class="reused-dataset" *ngFor="let dataset of datasetsUsed"> + <img [src]="dataset.image.url" alt="Dataset image" + onerror="this.onerror=null;this.src='./assets/img/vignette-data.png';this.alt='Default image'"> + <div class="dataset-title"> + <a class="link-without-decoration" + [routerLink]="['/', AppRoutes.datasets.uri, dataset.parentDataset.slug]">{{dataset.title}}</a> + </div> + </div> + </div> + </div> + <div> + <span class="column-title" i18n="@@reuses.officialWebsite"> + Offcial website + </span> + <a [href]="reuse.website">{{reuse.website}}</a> + </div> + + </div> +</section> \ No newline at end of file diff --git a/src/app/editorialisation/components/reuse-detail/reuse-detail.component.scss b/src/app/editorialisation/components/reuse-detail/reuse-detail.component.scss new file mode 100644 index 00000000..264b9f37 --- /dev/null +++ b/src/app/editorialisation/components/reuse-detail/reuse-detail.component.scss @@ -0,0 +1,98 @@ +@import './../../../../scss/variables.scss'; +@import "../../../../../node_modules/bulma/sass/utilities/_all"; + +.page-container { + background-color: white; + padding: 0 1.25rem 4rem 1.25rem; +} + +.page-header-container { + display: flex; + justify-content: space-between; + align-items: center; + + @media screen and (min-width: $tablet) { + margin-bottom: 1rem; + } + + .logo { + height: 82px; + width: 110px; + border: 1px solid $grey-super-light-color; + border-radius: 4px; + object-fit: contain; + + @media screen and (max-width: $desktop) { + display: none; + } + } +} + +.page-content { + display: block; + + @media screen and (min-width: $desktop) { + display: flex; + } + + .first-column { + margin-bottom: 1rem; + + @media screen and (min-width: $desktop) { + width: 66%; + margin-bottom: 0; + margin-right: 1.5rem; + } + } +} + +.column-title { + text-transform: uppercase; + color: $grey-dark-color; + font-size: 0.875rem; + display: block; + margin-bottom: 0.5rem; +} + +.dataset-list { + border: 1px solid $grey-super-light-color; +} + +.reused-dataset { + display: flex; + align-items: stretch; + padding: 0.75rem; + + img { + height: 50px; + width: 70px; + object-fit: cover; + border: 1px solid $grey-super-light-color; + border-radius: 4px; + margin-right: 0.5rem; + } + + .dataset-title { + flex-grow: 1; + display: flex; + align-items: center; + } + + a.link-without-decoration { + font-size: 1rem; + font-weight: 600; + } + + &:not(:last-of-type) { + padding-bottom: 0; + + .dataset-title { + border-bottom: 1px solid $grey-super-light-color; + padding-bottom: 0.75rem; + } + + img { + margin-bottom: 0.75rem; + } + } +} diff --git a/src/app/editorialisation/components/reuse-detail/reuse-detail.component.ts b/src/app/editorialisation/components/reuse-detail/reuse-detail.component.ts new file mode 100644 index 00000000..8d6dd56d --- /dev/null +++ b/src/app/editorialisation/components/reuse-detail/reuse-detail.component.ts @@ -0,0 +1,79 @@ +import { Component, OnInit } from '@angular/core'; +import { IPageHeaderInfo } from '../../../shared/models'; +import { ReusesService } from '../../services'; +import { filter, switchMap, map } from 'rxjs/operators'; +import { ParamMap, ActivatedRoute } from '@angular/router'; +import { IReuse, Reuse } from '../../models'; +import { ElasticsearchService } from '../../../geosource/services'; +import { Metadata, IElasticsearchResponse } from '../../../geosource/models'; +import { typesMetadata } from '../../../geosource/models/metadata.model'; +import { forkJoin } from 'rxjs'; +import { AppRoutes } from '../../../routes'; + +@Component({ + selector: 'app-reuse-detail', + templateUrl: './reuse-detail.component.html', + styleUrls: ['./reuse-detail.component.scss'] +}) +export class ReuseDetailComponent implements OnInit { + + pageHeaderInfo: IPageHeaderInfo = { + title: null, + }; + reuse: Reuse = new Reuse(); + datasetsUsed: Metadata[] = []; + AppRoutes = AppRoutes; + + constructor( + private _reusesService: ReusesService, + private _route: ActivatedRoute, + private _elasticSearchService: ElasticsearchService, + ) { } + + ngOnInit() { + this._route.paramMap.pipe( + filter((paramMap: ParamMap) => (paramMap.get('id') !== null)), + switchMap((paramMap: ParamMap) => this._reusesService.getReuse(paramMap.get('id'))), + ).subscribe((reuse: Reuse) => { + this.pageHeaderInfo.title = reuse.name; + this.pageHeaderInfo.subtitle = reuse.creator; + this.reuse = reuse; + // this.datasetsUsed = []; + const calls = this.reuse.datasetsUsed.map((slug) => { + return this._elasticSearchService.getDatasetMetadata(slug); + }); + + forkJoin(calls).pipe( + map((response) => { + return response.map((e, i) => { + if (e.hits.hits.length > 0) { + const metadata = new Metadata(e.hits.hits[0]._source['metadata-fr']); + // If the dataset doesn't have any image set the default one + metadata.parentDataset.slug = this.reuse.datasetsUsed[i]; + if (!(metadata.image && metadata.image.url)) { + this.setBackupImage(metadata); + } + console.log(metadata) + return metadata; + } + }); + }), + ).subscribe(res => this.datasetsUsed = res); + }); + } + + setBackupImage(metadata: Metadata) { + // Init the image property to make sure that 'url' is accessible in the following lines + metadata.image = { + url: null, + type: null, + }; + if (metadata.type === typesMetadata.series) { + metadata.image.url = './assets/img/vignette_collection.png'; + } else { + metadata.image.url = metadata.type === typesMetadata.dataset ? + './assets/img/vignette-data-geo.png' : './assets/img/vignette-data.png'; + } + } + +} diff --git a/src/app/editorialisation/components/reuses-list/reuses-list.component.html b/src/app/editorialisation/components/reuses-list/reuses-list.component.html index 35c7f6ab..deb2b460 100644 --- a/src/app/editorialisation/components/reuses-list/reuses-list.component.html +++ b/src/app/editorialisation/components/reuses-list/reuses-list.component.html @@ -13,22 +13,23 @@ <div class="reuses-container"> <div class="item" *ngFor="let reuse of reuses"> <div class="reuse"> + <a [routerLink]="['/', AppRoutes.reuses.uri, reuse._id]"> + <div class="logo-content"> + <img [src]="reuse.logo" [alt]="reuse.name + 'logo'"> + </div> + <span class="title">{{reuse.name}}</span> + <p>{{reuse.creator}}</p> - <div class="logo-content"> - <img [src]="reuse.logo" [alt]="reuse.name + 'logo'"> - </div> - <span class="title">{{reuse.name}}</span> - <p>{{reuse.creator}}</p> - - <div class="bottom-section"> - <span>{{ formatReusesTypes(reuse.reuseTypes) }}</span> - <span> - {{reuse.datasetsUsed ? reuse.datasetsUsed.length : 0 }} <span - *ngIf="reuse.datasetsUsed.length > 1; else oneReuse" i18n="@@reuses.ngDatasetsReused">jeux de données - utilisés</span> - <ng-template #oneReuse i18n="@@reuses.oneDatasetReused">jeu de données utilisé</ng-template> - </span> - </div> + <div class="bottom-section"> + <span>{{ formatReusesTypes(reuse.reuseTypes) }}</span> + <span> + {{reuse.datasetsUsed ? reuse.datasetsUsed.length : 0 }} <span + *ngIf="reuse.datasetsUsed.length > 1; else oneReuse" i18n="@@reuses.ngDatasetsReused">datasets + used</span> + <ng-template #oneReuse i18n="@@reuses.oneDatasetReused">dataset used</ng-template> + </span> + </div> + </a> </div> </div> </div> diff --git a/src/app/editorialisation/components/reuses-list/reuses-list.component.scss b/src/app/editorialisation/components/reuses-list/reuses-list.component.scss index 48ab4cf0..1f4d2576 100644 --- a/src/app/editorialisation/components/reuses-list/reuses-list.component.scss +++ b/src/app/editorialisation/components/reuses-list/reuses-list.component.scss @@ -14,6 +14,10 @@ padding-bottom: 1.875rem; } +a:hover { + text-decoration: none; +} + .reuses-container { display: flex; flex-wrap: wrap; diff --git a/src/app/editorialisation/editorialisation-routing.module.ts b/src/app/editorialisation/editorialisation-routing.module.ts index 6770aa4d..a9a23479 100644 --- a/src/app/editorialisation/editorialisation-routing.module.ts +++ b/src/app/editorialisation/editorialisation-routing.module.ts @@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { HomeComponent, OrganizationsComponent, CMSPageComponent, CMSDraftsListComponent, - SiteMapComponent, ChangelogComponent, ContributionComponent, ReusesListComponent, + SiteMapComponent, ChangelogComponent, ContributionComponent, ReusesListComponent, ReuseDetailComponent, } from './components'; import { CMSPostDetailComponent } from './components/cms-post-detail/cms-post-detail.component'; import { PostDetailResolver } from './resolvers/post-detail.resolver'; @@ -114,7 +114,6 @@ export const routes: Routes = [ component: SiteMapComponent, data: { title: AppRoutes.siteMap.title, - uri: AppRoutes.siteMap.uri, }, }, { @@ -122,7 +121,6 @@ export const routes: Routes = [ component: ChangelogComponent, data: { title: AppRoutes.changelog.title, - uri: AppRoutes.changelog.uri, }, }, { @@ -200,7 +198,6 @@ export const routes: Routes = [ component: CreditsComponent, data: { title: AppRoutes.credits.title, - uri: AppRoutes.credits.uri, }, }, { @@ -208,7 +205,13 @@ export const routes: Routes = [ component: ReusesListComponent, data: { title: AppRoutes.reuses.title, - uri: AppRoutes.reuses.uri, + }, + }, + { + path: `${AppRoutes.reuses.uri}/:id`, + component: ReuseDetailComponent, + data: { + // title: AppRoutes.reusesDetail.title, }, }, { diff --git a/src/app/editorialisation/models/reuse.model.ts b/src/app/editorialisation/models/reuse.model.ts index 23a6155e..5eab2ca7 100644 --- a/src/app/editorialisation/models/reuse.model.ts +++ b/src/app/editorialisation/models/reuse.model.ts @@ -23,16 +23,16 @@ export class Reuse implements IReuse { createDate: Date; updateDate: Date; - constructor(reuse: IReuse) { - this._id = reuse._id ? reuse._id : null; - this.name = reuse.name ? reuse.name : null; - this.creator = reuse.creator ? reuse.creator : null; - this.logo = reuse.logo ? reuse.logo : null; - this.website = reuse.website ? reuse.website : null; - this.reuseTypes = reuse.reuseTypes ? reuse.reuseTypes : []; - this.datasetsUsed = reuse.datasetsUsed ? reuse.datasetsUsed : []; - this.published = reuse.published ? reuse.published : null; - this.createDate = reuse.createDate ? reuse.createDate : null; - this.updateDate = reuse.updateDate ? reuse.updateDate : null; + constructor(reuse?: IReuse) { + this._id = reuse && reuse._id ? reuse._id : null; + this.name = reuse && reuse.name ? reuse.name : null; + this.creator = reuse && reuse.creator ? reuse.creator : null; + this.logo = reuse && reuse.logo ? reuse.logo : null; + this.website = reuse && reuse.website ? reuse.website : null; + this.reuseTypes = reuse && reuse.reuseTypes ? reuse.reuseTypes : []; + this.datasetsUsed = reuse && reuse.datasetsUsed ? reuse.datasetsUsed : []; + this.published = reuse && reuse.published ? reuse.published : null; + this.createDate = reuse && reuse.createDate ? reuse.createDate : null; + this.updateDate = reuse && reuse.updateDate ? reuse.updateDate : null; } } diff --git a/src/app/editorialisation/services/reuses.service.ts b/src/app/editorialisation/services/reuses.service.ts index 9e7804aa..74f7a4b1 100644 --- a/src/app/editorialisation/services/reuses.service.ts +++ b/src/app/editorialisation/services/reuses.service.ts @@ -21,4 +21,10 @@ export class ReusesService { return reuses; })); } + + getReuse(id: string) { + return this._httpClient.get<IReuse>(`${APP_CONFIG.backendUrls.reuses}/${id}`, { withCredentials: true }).pipe( + map(reuse => new Reuse(reuse)), + ); + } } diff --git a/src/i18n/messages.en.xlf b/src/i18n/messages.en.xlf index b8c9972d..0be03db2 100644 --- a/src/i18n/messages.en.xlf +++ b/src/i18n/messages.en.xlf @@ -1283,6 +1283,11 @@ Here is the list of the last evolutions of the portal. If you wish to contribute <trans-unit id="reuses.oneDatasetReused" datatype="html"> <source>dataset used</source> <target>dataset used</target> + </trans-unit> + <trans-unit id="reuses.officialWebsite" datatype="html"> + <source>Official website</source> + <target>Official website</target> + </trans-unit> </body> </file> </xliff> diff --git a/src/i18n/messages.fr.xlf b/src/i18n/messages.fr.xlf index 180a375c..54cac211 100644 --- a/src/i18n/messages.fr.xlf +++ b/src/i18n/messages.fr.xlf @@ -1293,6 +1293,10 @@ Voici la liste des dernières évolutions du portail. Si vous souhaitez contribu <source>dataset used</source> <target>jeu de données utilisé</target> </trans-unit> + <trans-unit id="reuses.officialWebsite" datatype="html"> + <source>Official website</source> + <target>Site officiel</target> + </trans-unit> </body> </file> </xliff> -- GitLab