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 }}
+                    &nbsp;
+                    <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