From 74909882c3a1a512763cdedd6863268c485492c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Agneray?= <francois.agneray@lam.fr>
Date: Tue, 8 Nov 2022 21:33:15 +0100
Subject: [PATCH] #97 + details components improvments

---
 .../display-json.component.html               |  1 +
 .../display-json.component.ts                 | 19 +++++++++++++++++
 ...y-object-by-output-category.component.html |  2 +-
 ...lay-object-by-output-category.component.ts |  1 +
 ...lay-object-by-output-family.component.html |  2 +-
 ...splay-object-by-output-family.component.ts |  1 +
 .../display-value-by-attribute.component.html | 15 ++++++++++++-
 .../display-value-by-attribute.component.ts   | 21 ++++++++++++++++++-
 .../dynamic-components/index.ts               |  2 ++
 .../dynamic-accordion.component.html          | 18 ++++++++++++++++
 .../dynamic-accordion.component.ts            | 19 +++++++++++++++++
 .../dynamic-components/index.ts               |  4 +++-
 conf-dev/create-db.sh                         |  2 +-
 13 files changed, 101 insertions(+), 6 deletions(-)
 create mode 100644 client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.html
 create mode 100644 client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.ts
 create mode 100644 client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.html
 create mode 100644 client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.ts

diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.html b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.html
new file mode 100644
index 00000000..bab73190
--- /dev/null
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.html
@@ -0,0 +1 @@
+<ngx-json-viewer [json]="getValue()"></ngx-json-viewer>
\ No newline at end of file
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.ts b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.ts
new file mode 100644
index 00000000..7a20dfbe
--- /dev/null
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-json.component.ts
@@ -0,0 +1,19 @@
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
+
+import { Attribute } from 'src/app/metamodel/models';
+
+@Component({
+    selector: 'app-display-json',
+    templateUrl: 'display-json.component.html',
+    changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class DisplayJsonComponent {
+    @Input() object: any;
+    @Input() attributeList: Attribute[];
+    @Input() attributeJsonId: number;
+
+    getValue() {
+        const labelAttributeJson = this.attributeList.find(attribute => attribute.id === this.attributeJsonId).label;
+        return this.object[labelAttributeJson];
+    }
+}
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.html b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.html
index eed45dc7..62575eba 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.html
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.html
@@ -1,6 +1,6 @@
 <!-- Accordion categories -->
 <accordion [isAnimated]="true">
-    <accordion-group [panelClass]="'custom-accordion'" #ag [isOpen]="true" class="my-2">
+    <accordion-group [panelClass]="'custom-accordion'" #ag [isOpen]="isOpened" class="my-2">
         <button class="btn btn-link btn-block clearfix pb-2" accordion-heading>
             <span class="pull-left float-left">
                 {{ getCategory().label }}
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.ts b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.ts
index 015fe691..023a1244 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.ts
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-category.component.ts
@@ -19,6 +19,7 @@ export class DisplayObjectByOutputCategoryComponent {
     @Input() outputCategoryList: OutputCategory[];
     @Input() queryParams: SearchQueryParams;
     @Input() outputCategoryId: number;
+    @Input() isOpened: boolean;
 
     constructor(protected store: Store<{}>) { }
 
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.html b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.html
index 03c8324e..965f015a 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.html
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.html
@@ -1,6 +1,6 @@
 <!-- Accordion families -->
 <accordion [isAnimated]="true">
-    <accordion-group [panelClass]="'custom-accordion'" #ag [isOpen]="true" class="my-2">
+    <accordion-group [panelClass]="'custom-accordion'" #ag [isOpen]="isOpened" class="my-2">
         <button class="btn btn-link btn-block clearfix" accordion-heading>
             <span class="pull-left float-left">
                 {{ getFamily().label }}
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.ts b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.ts
index fda6fb34..5b965f86 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.ts
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-object-by-output-family.component.ts
@@ -20,6 +20,7 @@ export class DisplayObjectByOutputFamilyComponent {
     @Input() outputCategoryList: OutputCategory[];
     @Input() queryParams: SearchQueryParams;
     @Input() outputFamilyId: number;
+    @Input() isOpened: boolean;
 
     constructor(protected store: Store<{}>) { }
 
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.html b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.html
index 035011ce..93dcf146 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.html
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.html
@@ -1 +1,14 @@
-{{ object[getAttributeById().label] }}
\ No newline at end of file
+<app-display-detail-renderer
+    *ngIf="rendererEnabled; else displayValue"
+    [rendererType]="'detail'"
+    [value]="object[getAttributeById().label]"
+    [dataset]="dataset"
+    [instance]="instance"
+    [attribute]="getAttributeById()"
+    [queryParams]="queryParams"
+    (downloadFile)="downloadFile($event)">
+</app-display-detail-renderer>
+
+<ng-template #displayValue>
+    {{ object[getAttributeById().label] }}
+</ng-template>
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.ts b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.ts
index ad1dca1c..92772c1e 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.ts
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/display-value-by-attribute.component.ts
@@ -1,6 +1,10 @@
 import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
 
-import { Attribute } from 'src/app/metamodel/models';
+import { Store } from '@ngrx/store';
+
+import { Attribute, Dataset, Instance, OutputCategory } from 'src/app/metamodel/models';
+import { SearchQueryParams } from 'src/app/instance/store/models';
+import * as searchActions from 'src/app/instance/store/actions/search.actions';
 
 @Component({
     selector: 'app-display-value-by-attribute',
@@ -9,10 +13,25 @@ import { Attribute } from 'src/app/metamodel/models';
 })
 export class DisplayValueByAttributeComponent {
     @Input() object: any;
+    @Input() dataset: Dataset;
+    @Input() instance: Instance;
     @Input() attributeList: Attribute[];
+    @Input() queryParams: SearchQueryParams;
     @Input() attributeId: number;
+    @Input() rendererEnabled: boolean;
+
+    constructor(protected store: Store<{}>) { }
 
     getAttributeById() {
         return this.attributeList.find(attribute => attribute.id === this.attributeId);
     }
+
+    /**
+     * Dispatches action to launch the file download
+     * 
+     * @param { url: string, filename: string } download
+     */
+    downloadFile(download: { url: string, filename: string }): void {
+        this.store.dispatch(searchActions.downloadFile(download));
+    }
 }
diff --git a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/index.ts b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/index.ts
index 440ca467..7451ee92 100644
--- a/client/src/app/instance/search/detail/dynamic-content/dynamic-components/index.ts
+++ b/client/src/app/instance/search/detail/dynamic-content/dynamic-components/index.ts
@@ -14,6 +14,7 @@ import { DisplayValueByAttributeComponent } from './display-value-by-attribute.c
 import { DisplayRaDecComponent } from './display-ra-dec.component';
 import { DisplaySpectraComponent } from './display-spectra.component';
 import { DisplayImageComponent } from './display-image.component';
+import { DisplayJsonComponent } from './display-json.component';
 import { SpectraGraphComponent } from './spectra-graph/spectra-graph.component';
 
 export const dynamicComponents = [
@@ -24,5 +25,6 @@ export const dynamicComponents = [
     DisplayRaDecComponent,
     DisplaySpectraComponent,
     DisplayImageComponent,
+    DisplayJsonComponent,
     SpectraGraphComponent
 ];
diff --git a/client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.html b/client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.html
new file mode 100644
index 00000000..4f55c8c4
--- /dev/null
+++ b/client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.html
@@ -0,0 +1,18 @@
+<accordion [isAnimated]="true">
+    <accordion-group [panelClass]="'custom-accordion'" #ag [isOpen]="isOpen" class="my-2">
+        <button class="btn btn-link btn-block clearfix pb-2" accordion-heading>
+            <span class="pull-left float-left">
+                {{ 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>
+
+        <ng-content></ng-content>
+    </accordion-group>
+</accordion>
diff --git a/client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.ts b/client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.ts
new file mode 100644
index 00000000..1f1ca950
--- /dev/null
+++ b/client/src/app/shared/dynamic-content/dynamic-components/dynamic-accordion.component.ts
@@ -0,0 +1,19 @@
+/**
+ * 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 } from '@angular/core';
+
+@Component({
+    selector: 'app-dynamic-accordion',
+    templateUrl: 'dynamic-accordion.component.html'
+})
+export class DynamicAccordionComponent {
+    @Input() label: string;
+    @Input() isOpen: boolean;
+}
diff --git a/client/src/app/shared/dynamic-content/dynamic-components/index.ts b/client/src/app/shared/dynamic-content/dynamic-components/index.ts
index 233cdba7..cda8088e 100644
--- a/client/src/app/shared/dynamic-content/dynamic-components/index.ts
+++ b/client/src/app/shared/dynamic-content/dynamic-components/index.ts
@@ -8,7 +8,9 @@
  */
 
 import { DynamicRouterLinkComponent } from './dynamic-router-link.component';
+import { DynamicAccordionComponent } from './dynamic-accordion.component';
 
 export const dynamicComponents = [
-    DynamicRouterLinkComponent
+    DynamicRouterLinkComponent,
+    DynamicAccordionComponent
 ];
diff --git a/conf-dev/create-db.sh b/conf-dev/create-db.sh
index 17c4b5e1..587a6f40 100644
--- a/conf-dev/create-db.sh
+++ b/conf-dev/create-db.sh
@@ -80,7 +80,7 @@ curl -d '{"id":9,"name":"fits_png","label":"fits_png","form_label":"fits_png","d
 curl -d '{"id":10,"name":"id_obspack","label":"id_obspack","form_label":"id_obspack","description":null,"primary_key":false,"type":"integer","search_type":null,"operator":null,"dynamic_operator":null,"min":null,"max":null,"options":null,"placeholder_min":null,"placeholder_max":null,"criteria_display":100,"output_display":100,"detail_renderer":null,"detail_renderer_config":null,"selected":true,"renderer":"link","renderer_config":{"href":"/instance/default/search/result/iris_obspack?s=100&a=1;2;3&c=1::eq::$value","display":"text","text":"$value","icon":"fas fa-link","blank":false},"order_by":true,"archive":false,"detail_display":100,"vo_utype":null,"vo_ucd":null,"vo_unit":null,"vo_description":null,"vo_datatype":null,"vo_size":null,"id_criteria_family":null,"id_output_category":4,"id_detail_output_category":null}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/attribute
 
 # Add observations detail config
-curl -d '{"content":"<h1 class=\"text-center\">\n    <app-display-value-by-attribute\n        [object]=\"context.object\"\n        [attributeList]=\"context.attributeList\"\n        [attributeId]=\"7\">\n    </app-display-value-by-attribute>\n</h1>\n<div class=\"row\">\n    <div class=\"col-md-8 col-sm-12 col-xs-12\">\n        <app-display-image\n            [object]=\"context.object\"\n            [attributeList]=\"context.attributeList\"\n            [dataset]=\"context.dataset\"\n            [attributeImageId]=\"9\"\n            [type]=\"'\''fits'\''\">\n        </app-display-image>\n    </div>\n    <div class=\"col-md-4 col-sm-12 col-xs-12\">\n        <app-display-ra-dec\n            [object]=\"context.object\"\n            [attributeList]=\"context.attributeList\"\n            [attributeRaId]=\"2\"\n            [attributeDecId]=\"3\">\n        </app-display-ra-dec>\n        <app-display-object-by-output-category\n            [object]=\"context.object\"\n            [dataset]=\"context.dataset\"\n            [instance]=\"context.instance\"\n            [attributeList]=\"context.attributeList\"\n            [outputCategoryList]=\"context.outputCategoryList\"\n            [queryParams]=\"context.queryParams\"\n            [outputCategoryId]=\"4\">\n        </app-display-object-by-output-category>\n    </div>\n</div>\n","style_sheet":"h1 {\n    color: red;\n}\n\n.panel-heading.card-header {\n    background-color: #dee2ff;\n}\n\n.panel .btn.btn-link .text-primary {\n    color: red !important;\n}\n"}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/detail-config
+curl -d '{"content":"<h1 class=\"text-center\">\n    <app-display-value-by-attribute\n        [object]=\"context.object\"\n        [attributeList]=\"context.attributeList\"\n        [attributeId]=\"7\">\n    </app-display-value-by-attribute>\n</h1>\n<div class=\"row\">\n    <div class=\"col-md-8 col-sm-12 col-xs-12\">\n        <app-display-image\n            [object]=\"context.object\"\n            [attributeList]=\"context.attributeList\"\n            [dataset]=\"context.dataset\"\n            [attributeImageId]=\"9\"\n            [type]=\"'\''fits'\''\">\n        </app-display-image>\n    </div>\n    <div class=\"col-md-4 col-sm-12 col-xs-12\">\n        <app-display-ra-dec\n            [object]=\"context.object\"\n            [attributeList]=\"context.attributeList\"\n            [attributeRaId]=\"2\"\n            [attributeDecId]=\"3\">\n        </app-display-ra-dec>\n        <app-display-object-by-output-category\n            [object]=\"context.object\"\n            [dataset]=\"context.dataset\"\n            [instance]=\"context.instance\"\n            [attributeList]=\"context.attributeList\"\n            [outputCategoryList]=\"context.outputCategoryList\"\n            [queryParams]=\"context.queryParams\"\n            [outputCategoryId]=\"4\"\n            [isOpened]=\"true\">\n        </app-display-object-by-output-category>\n    </div>\n</div>\n","style_sheet":"h1 {\n    color: red;\n}\n\n.panel-heading.card-header {\n    background-color: #dee2ff;\n}\n\n.panel .btn.btn-link .text-primary {\n    color: red !important;\n}\n"}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/observations/detail-config
 
 # Add vvds_f02_udeep attributes
 curl -d '{"label":"Default","display":10,"opened":true}' --header 'Content-Type: application/json' -X POST http://localhost/dataset/vvds_f02_udeep/criteria-family
-- 
GitLab