From 724bdd09cfc40801ad09cc8eff309a6ddb051c60 Mon Sep 17 00:00:00 2001 From: Tifenn Guillas <tifenn.guillas@gmail.com> Date: Wed, 21 Jul 2021 16:56:51 +0200 Subject: [PATCH] Add dataset by family tabs => DONE --- .gitignore | 45 ++++++++++++ .../dataset-by-family.component.html | 54 ++++++++++++++ .../dataset-by-family.component.scss | 32 +++++++++ .../components/dataset-by-family.component.ts | 28 ++++++++ .../components/dataset-card.component.html | 38 ++++++++++ .../doc/components/dataset-card.component.ts | 36 ++++++++++ .../src/app/instance/doc/components/index.ts | 7 ++ .../containers/dataset-list.component.html | 26 +++++++ .../doc/containers/dataset-list.component.ts | 71 +++++++++++++++++++ .../app/instance/doc/doc-routing.module.ts | 27 +++++++ .../src/app/instance/doc/doc.component.scss | 30 ++++++++ client/src/app/instance/doc/doc.module.ts | 26 +++++++ .../app/instance/instance-routing.module.ts | 1 + client/src/app/instance/instance.component.ts | 3 +- data | 2 +- 15 files changed, 424 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 client/src/app/instance/doc/components/dataset-by-family.component.html create mode 100644 client/src/app/instance/doc/components/dataset-by-family.component.scss create mode 100644 client/src/app/instance/doc/components/dataset-by-family.component.ts create mode 100644 client/src/app/instance/doc/components/dataset-card.component.html create mode 100644 client/src/app/instance/doc/components/dataset-card.component.ts create mode 100644 client/src/app/instance/doc/components/index.ts create mode 100644 client/src/app/instance/doc/containers/dataset-list.component.html create mode 100644 client/src/app/instance/doc/containers/dataset-list.component.ts create mode 100644 client/src/app/instance/doc/doc-routing.module.ts create mode 100644 client/src/app/instance/doc/doc.component.scss create mode 100644 client/src/app/instance/doc/doc.module.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..de51f68a --- /dev/null +++ b/.gitignore @@ -0,0 +1,45 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp +/out-tsc +# Only exists if Bazel was run +/bazel-out + +# dependencies +/node_modules + +# profiling files +chrome-profiler-events*.json + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db diff --git a/client/src/app/instance/doc/components/dataset-by-family.component.html b/client/src/app/instance/doc/components/dataset-by-family.component.html new file mode 100644 index 00000000..98b4513e --- /dev/null +++ b/client/src/app/instance/doc/components/dataset-by-family.component.html @@ -0,0 +1,54 @@ +<div *ngIf="datasetFamilyList.length === 1"> + <div class="border rounded my-2"> + <p *ngIf="(datasetList | datasetListByFamily:datasetFamilyList[0].id).length === 1" + class="border-bottom bg-light text-primary py-4 pl-4"> + Dataset + </p> + <p *ngIf="(datasetList | datasetListByFamily:datasetFamilyList[0].id).length > 1" + class="border-bottom bg-light text-primary py-4 pl-4"> + List of datasets + </p> + <ul class="p-0"> + <li *ngFor="let dataset of (datasetList | datasetListByFamily:datasetFamilyList[0].id); last as isLast" + class="list-unstyled px-3 pt-3 pb-0"> +<!-- <app-dataset-card--> +<!-- [dataset]="dataset"--> +<!-- [survey]="surveyList | surveyByName:dataset.survey_name"--> +<!-- [instanceSelected]="instanceSelected"--> +<!-- [datasetSelected]="datasetSelected">--> +<!-- </app-dataset-card>--> + <hr *ngIf="!isLast"> + </li> + </ul> + </div> +</div> + +<accordion *ngIf="datasetFamilyList.length > 1" [isAnimated]="true"> + <ng-container *ngFor="let family of datasetFamilyList"> + <accordion-group #ag *ngIf="(datasetList | datasetListByFamily:family.id).length > 0" [panelClass]="'custom-accordion'" + [isOpen]="true" class="my-2"> + <button class="btn btn-link btn-block clearfix" accordion-heading> + <span class="pull-left float-left"> + {{ family.label }} + + <span *ngIf="ag.isOpen"> + <span class="fas fa-chevron-up"></span> + </span> + <span *ngIf="!ag.isOpen"> + <span class="fas fa-chevron-down"></span> + </span> + </span> + </button> + <div *ngFor="let dataset of (datasetList | datasetListByFamily:family.id); last as isLast"> + {{ dataset.name }} +<!-- <app-dataset-card--> +<!-- [dataset]="dataset" --> +<!-- [survey]="surveyList | surveyByName:dataset.survey_name"--> +<!-- [instanceSelected]="instanceSelected"--> +<!-- [datasetSelected]="datasetSelected">--> +<!-- </app-dataset-card>--> + <hr *ngIf="!isLast"> + </div> + </accordion-group> + </ng-container> +</accordion> diff --git a/client/src/app/instance/doc/components/dataset-by-family.component.scss b/client/src/app/instance/doc/components/dataset-by-family.component.scss new file mode 100644 index 00000000..537c2ca1 --- /dev/null +++ b/client/src/app/instance/doc/components/dataset-by-family.component.scss @@ -0,0 +1,32 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +.tabset .tab-pane, .tabset .tab-pane .family-empty { + min-height: 300px; +} + +.tabset .tab-pane { + padding-top: 13px; +} + +.tabset .active.tab-pane { + border: 1px solid #dee2e6; + border-top: none; + border-bottom-left-radius: .25rem; + border-bottom-right-radius: .25rem; +} + +.dataset-card { + width: 95%; + border-bottom: 1px solid #dee2e6; +} + +.dataset-card:last-child { + border: none; +} diff --git a/client/src/app/instance/doc/components/dataset-by-family.component.ts b/client/src/app/instance/doc/components/dataset-by-family.component.ts new file mode 100644 index 00000000..329cb29c --- /dev/null +++ b/client/src/app/instance/doc/components/dataset-by-family.component.ts @@ -0,0 +1,28 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; + +import { Dataset, DatasetFamily } from 'src/app/metamodel/models'; + +@Component({ + selector: 'app-dataset-by-family', + templateUrl: 'dataset-by-family.component.html', + styleUrls: ['dataset-by-family.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +/** + * @class + * @classdesc Documentation dataset by family component. + */ +export class DatasetByFamilyComponent { + @Input() datasetList: Dataset[]; + @Input() datasetFamilyList: DatasetFamily[]; + @Input() instanceSelected: string; +} diff --git a/client/src/app/instance/doc/components/dataset-card.component.html b/client/src/app/instance/doc/components/dataset-card.component.html new file mode 100644 index 00000000..190c9bc9 --- /dev/null +++ b/client/src/app/instance/doc/components/dataset-card.component.html @@ -0,0 +1,38 @@ +<div class="card border-0"> + <div class="card-body py-2"> + <div class="row"> + <div class="col"> + <div class="row"> + <p class="lead m-0 d-inline"> + {{ dataset.label }} + </p> + </div> + <div class="row"> + <p class="my-3">{{ dataset.description }}</p> + </div> + <div class="row"> + <button class="btn btn-link p-0" + popover="{{ survey.description }}" + popoverTitle="{{ survey.label }}" + placement="bottom" + [outsideClick]="true" + triggers="mouseenter:mouseleave"> + <small> + More about {{ survey.label }} survey <span class="fas fa-question-circle"></span> + </small> + </button> + </div> + </div> + <div class="col-auto"> + <button *ngIf="dataset.name !== datasetSelected" + (click)="selectDataset(dataset.name)" + class="btn btn-outline-secondary"> + Select + </button> + <span *ngIf="dataset.name === datasetSelected"> + <span class="far fa-check-circle fa-2x text-success"></span> + </span> + </div> + </div> + </div> +</div> diff --git a/client/src/app/instance/doc/components/dataset-card.component.ts b/client/src/app/instance/doc/components/dataset-card.component.ts new file mode 100644 index 00000000..ffeb52d4 --- /dev/null +++ b/client/src/app/instance/doc/components/dataset-card.component.ts @@ -0,0 +1,36 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import { Component, Input, ChangeDetectionStrategy, Output, EventEmitter } from '@angular/core'; +import { Router } from '@angular/router'; + +import { Survey, Dataset } from 'src/app/metamodel/models'; + +@Component({ + selector: 'app-dataset-card', + templateUrl: 'dataset-card.component.html', + changeDetection: ChangeDetectionStrategy.OnPush +}) +/** + * @class + * @classdesc Search dataset card component. + */ +export class DatasetCardComponent { + @Input() survey: Survey; + @Input() dataset: Dataset; + @Input() instanceSelected: string; + @Input() datasetSelected: string; + + constructor(private router: Router) { } + + selectDataset(datasetName: string) { + this.router.routeReuseStrategy.shouldReuseRoute = () => false; + this.router.navigate([`/instance/${this.instanceSelected}/search/dataset/${datasetName}`]); + } +} diff --git a/client/src/app/instance/doc/components/index.ts b/client/src/app/instance/doc/components/index.ts new file mode 100644 index 00000000..55f50b8b --- /dev/null +++ b/client/src/app/instance/doc/components/index.ts @@ -0,0 +1,7 @@ +import { DatasetByFamilyComponent } from './dataset-by-family.component'; +import { DatasetCardComponent } from './dataset-card.component'; + +export const dummiesComponents = [ + DatasetByFamilyComponent, + DatasetCardComponent +]; diff --git a/client/src/app/instance/doc/containers/dataset-list.component.html b/client/src/app/instance/doc/containers/dataset-list.component.html new file mode 100644 index 00000000..8c69e6de --- /dev/null +++ b/client/src/app/instance/doc/containers/dataset-list.component.html @@ -0,0 +1,26 @@ +<app-spinner *ngIf="(datasetFamilyListIsLoading | async) + || (datasetListIsLoading | async)"> +</app-spinner> + +<div *ngIf="(datasetFamilyListIsLoaded | async) + && (datasetListIsLoaded | async)" class="container"> + <div class="row mt-4"> + <ng-container *ngIf="(datasetList | async).length === 0"> + <div class="col-12 lead text-center"> + Oops! No dataset available... + <span *ngIf="!(isAuthenticated | async)"> + Try to sign in to access to protected datasets. + </span> + </div> + </ng-container> + <ng-container *ngIf="(datasetList | async).length > 0"> + <div class="col-12"> + <app-dataset-by-family + [datasetList]="datasetList | async" + [datasetFamilyList]="datasetFamilyList | async" + [instanceSelected]="instanceSelected | async"> + </app-dataset-by-family> + </div> + </ng-container> + </div> +</div> \ No newline at end of file diff --git a/client/src/app/instance/doc/containers/dataset-list.component.ts b/client/src/app/instance/doc/containers/dataset-list.component.ts new file mode 100644 index 00000000..b47b7b64 --- /dev/null +++ b/client/src/app/instance/doc/containers/dataset-list.component.ts @@ -0,0 +1,71 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import { Component, OnInit } from '@angular/core'; + +import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs'; + +import * as datasetActions from 'src/app/metamodel/actions/dataset.actions'; +import * as datasetFamilySelector from 'src/app/metamodel/selectors/dataset-family.selector'; +import * as datasetSelector from 'src/app/metamodel/selectors/dataset.selector'; +import { Dataset, DatasetFamily } from 'src/app/metamodel/models'; +import { environment } from 'src/environments/environment'; +import * as authSelector from "../../../auth/auth.selector"; +import * as instanceSelector from "../../../metamodel/selectors/instance.selector"; + +@Component({ + selector: 'app-dataset-list', + templateUrl: 'dataset-list.component.html', + styleUrls: ['../doc.component.scss'] +}) +/** + * @class + * @classdesc Documentation container. + * + * @implements OnInit + */ +export class DatasetListComponent implements OnInit { + public instanceSelected: Observable<string>; + public isAuthenticated: Observable<boolean>; + public datasetFamilyListIsLoading: Observable<boolean>; + public datasetFamilyListIsLoaded: Observable<boolean>; + public datasetFamilyList: Observable<DatasetFamily[]>; + public datasetListIsLoading: Observable<boolean>; + public datasetListIsLoaded: Observable<boolean>; + public datasetList: Observable<Dataset[]>; + + constructor(private store: Store<{ }>) { + this.instanceSelected = store.select(instanceSelector.selectInstanceNameByRoute); + this.isAuthenticated = store.select(authSelector.selectIsAuthenticated); + this.datasetFamilyListIsLoading = store.select(datasetFamilySelector.selectDatasetFamilyListIsLoading); + this.datasetFamilyListIsLoaded = store.select(datasetFamilySelector.selectDatasetFamilyListIsLoaded); + this.datasetFamilyList = store.select(datasetFamilySelector.selectAllDatasetFamilies); + this.datasetListIsLoading = store.select(datasetSelector.selectDatasetListIsLoading); + this.datasetListIsLoaded = store.select(datasetSelector.selectDatasetListIsLoaded); + this.datasetList = store.select(datasetSelector.selectAllDatasets); + } + + ngOnInit() { + this.store.dispatch(datasetActions.loadDatasetList()); + } + + /** + * Returns strict url address. + * + * @return string + */ + getUrlServer(): string { + if (!environment.apiUrl.startsWith('http')) { + const url = window.location; + return url.protocol + '//' + url.host + environment.apiUrl; + } + return environment.apiUrl; + } +} diff --git a/client/src/app/instance/doc/doc-routing.module.ts b/client/src/app/instance/doc/doc-routing.module.ts new file mode 100644 index 00000000..69ac131b --- /dev/null +++ b/client/src/app/instance/doc/doc-routing.module.ts @@ -0,0 +1,27 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { DatasetListComponent } from "./containers/dataset-list.component"; + +const routes: Routes = [ + { path: '', component: DatasetListComponent } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class DocRoutingModule { } + +export const routedComponents = [ + DatasetListComponent +]; diff --git a/client/src/app/instance/doc/doc.component.scss b/client/src/app/instance/doc/doc.component.scss new file mode 100644 index 00000000..9628a449 --- /dev/null +++ b/client/src/app/instance/doc/doc.component.scss @@ -0,0 +1,30 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +blockquote { + background: #f9f9f9; + border-left: 10px solid #ccc; + margin: 1.5em 10px; + padding: 1em 10px 1em 10px; +} + +table, th, td { + background-color: #f9f9f9; + padding: 6px 13px; + border: 1px solid #ccc; + border-collapse: collapse; + margin-bottom: 1em; +} + +.attributes-table { + display: inline-block; + max-height : 500px; + overflow-y : auto; + overflow-x: hidden; +} diff --git a/client/src/app/instance/doc/doc.module.ts b/client/src/app/instance/doc/doc.module.ts new file mode 100644 index 00000000..74d696f1 --- /dev/null +++ b/client/src/app/instance/doc/doc.module.ts @@ -0,0 +1,26 @@ +/** + * This file is part of Anis Client. + * + * @copyright Laboratoire d'Astrophysique de Marseille / CNRS + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import { NgModule } from '@angular/core'; + +import { SharedModule } from 'src/app/shared/shared.module'; +import { DocRoutingModule, routedComponents } from './doc-routing.module'; +import { dummiesComponents } from './components'; + +@NgModule({ + imports: [ + SharedModule, + DocRoutingModule + ], + declarations: [ + routedComponents, + dummiesComponents + ] +}) +export class DocModule { } diff --git a/client/src/app/instance/instance-routing.module.ts b/client/src/app/instance/instance-routing.module.ts index 37baa107..b023c7cf 100644 --- a/client/src/app/instance/instance-routing.module.ts +++ b/client/src/app/instance/instance-routing.module.ts @@ -18,6 +18,7 @@ const routes: Routes = [ { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) }, { path: 'documentation', loadChildren: () => import('./documentation/documentation.module').then(m => m.DocumentationModule) }, + { path: 'doc', loadChildren: () => import('./doc/doc.module').then(m => m.DocModule) }, { path: 'search', loadChildren: () => import('./search/search.module').then(m => m.SearchModule) } ] } diff --git a/client/src/app/instance/instance.component.ts b/client/src/app/instance/instance.component.ts index 6d2d3146..96a8223e 100644 --- a/client/src/app/instance/instance.component.ts +++ b/client/src/app/instance/instance.component.ts @@ -29,7 +29,8 @@ export class InstanceComponent implements OnInit { { label: 'Home', icon: 'fas fa-home', routerLink: 'home' }, { label: 'Search', icon: 'fas fa-search', routerLink: 'search' }, { label: 'Search multiple', icon: 'fas fa-search-plus', routerLink: 'search-multiple' }, - { label: 'Documentation', icon: 'fas fa-question', routerLink: 'documentation' } + { label: 'Documentation', icon: 'fas fa-question', routerLink: 'documentation' }, + { label: 'Doc', icon: 'fas fa-question', routerLink: 'doc' } ]; public isAuthenticated: Observable<boolean>; public userProfile: Observable<UserProfile>; diff --git a/data b/data index a47bad13..ee2cc741 120000 --- a/data +++ b/data @@ -1 +1 @@ -../anis/anis-data \ No newline at end of file +../anis-data/ \ No newline at end of file -- GitLab