diff --git a/client/src/app/admin/instance/components/instance-form.component.html b/client/src/app/admin/instance/components/instance-form.component.html index 3a8d4f404eb9d74ebf1a85362f635e8d657b781c..bf91dd5ec5f0cc62246a2fd6bfef47576144fd7d 100644 --- a/client/src/app/admin/instance/components/instance-form.component.html +++ b/client/src/app/admin/instance/components/instance-form.component.html @@ -1,124 +1,130 @@ <form [formGroup]="form" (ngSubmit)="submit()" novalidate> - <accordion [isAnimated]="true"> - <accordion-group heading="General information" [isOpen]="true"> - <div class="form-group"> - <label for="name">Name</label> - <input type="text" class="form-control" id="name" name="name" formControlName="name"> - </div> - <div class="form-group"> - <label for="label">Label</label> - <input type="text" class="form-control" id="label" name="label" formControlName="label"> - </div> - <div class="form-group"> - <label for="description">Description</label> - <textarea class="form-control" rows="5" id="description" name="description" formControlName="description"></textarea> - </div> - <div class="form-group"> - <label for="display">Display</label> - <input type="number" class="form-control" id="display" name="display" formControlName="display"> - </div> - <app-data-path-form-control - [form]="form" - [rootDirectory]="rootDirectory" - [rootDirectoryIsLoading]="rootDirectoryIsLoading" - [rootDirectoryIsLoaded]="rootDirectoryIsLoaded" - (loadRootDirectory)="loadRootDirectory.emit($event)"> - </app-data-path-form-control> - <div class="form-row"> - <div class="form-group col-md-6"> - <label for="design_color_picker">Instance color (picker)</label> - <input class="form-control" type="color" id="design_color_picker" [value]="form.value.design_color" formControlName="design_color"> - </div> - <div class="form-group col-md-6"> - <label for="design_color_input">Instance color (value)</label> - <input type="text" class="form-control" id="design_color_input" [value]="form.value.design_color" formControlName="design_color"> - </div> - </div> - <div class="form-row"> - <div class="form-group col-md-6"> - <label for="design_background_color_picker">Instance background color (picker)</label> - <input class="form-control" type="color" id="design_background_color_picker" [value]="form.value.design_background_color" formControlName="design_background_color"> - </div> - <div class="form-group col-md-6"> - <label for="design_background_color_input">Instance background color (value)</label> - <input type="text" class="form-control" id="design_background_color_input" [value]="form.value.design_background_color" formControlName="design_background_color"> - </div> - </div> - <app-file-select-form-control - [form]="form" - [disabled]="isDataPathEmpty()" - [controlName]="'design_logo'" - [controlLabel]="'Logo'" - [rootDirectory]="rootDirectory" - [rootDirectoryIsLoading]="rootDirectoryIsLoading" - [rootDirectoryIsLoaded]="rootDirectoryIsLoaded" - (loadRootDirectory)="loadRootDirectory.emit($event)"> - </app-file-select-form-control> - <app-file-select-form-control - [form]="form" - [disabled]="isDataPathEmpty()" - [controlName]="'design_favicon'" - [controlLabel]="'Favicon'" - [rootDirectory]="rootDirectory" - [rootDirectoryIsLoading]="rootDirectoryIsLoading" - [rootDirectoryIsLoaded]="rootDirectoryIsLoaded" - (loadRootDirectory)="loadRootDirectory.emit($event)"> - </app-file-select-form-control> - <div class="form-group"> - <label for="home_component">Component</label> - <select class="form-control" name="home_component" formControlName="home_component"> - <option value="WelcomeComponent">WelcomeComponent</option> - </select> - </div> - <div formGroupName="home_component_config"> - <div class="form-group"> - <label for="home_component_text">Text</label> - <textarea class="form-control" id="home_component_text" formControlName="home_component_text" rows="3"></textarea> - </div> - <app-file-select-form-control - [form]="getHomeConfigFormGroup()" - [controlName]="'home_component_logo'" - [controlLabel]="'Logo'" - [rootDirectory]="rootDirectory" - [rootDirectoryIsLoading]="rootDirectoryIsLoading" - [rootDirectoryIsLoaded]="rootDirectoryIsLoaded" - (loadRootDirectory)="loadRootDirectory.emit($event)"> - </app-file-select-form-control> - </div> - <div class="custom-control custom-switch mb-2"> - <input class="custom-control-input" type="checkbox" id="search_by_criteria_allowed" name="search_by_criteria_allowed" formControlName="search_by_criteria_allowed" (change)="checkDisableSearchByCriteriaAllowed()"> - <label class="custom-control-label" for="search_by_criteria_allowed">Classic search allowed</label> - </div> - <div class="form-group"> - <label for="search_by_criteria_label">Label</label> - <input type="text" class="form-control" id="search_by_criteria_label" formControlName="search_by_criteria_label"> - </div> - <div class="custom-control custom-switch mb-2"> - <input class="custom-control-input" type="checkbox" id="search_multiple_allowed" name="search_multiple_allowed" formControlName="search_multiple_allowed" (change)="checkDisableAllDatasetsSelected()"> - <label class="custom-control-label" for="search_multiple_allowed">Search multiple allowed</label> - </div> - <div class="form-group"> - <label for="search_multiple_label">Label</label> - <input type="text" class="form-control" id="search_multiple_label" formControlName="search_multiple_label"> - </div> - <div class="custom-control custom-switch"> - <input class="custom-control-input" - type="checkbox" - id="search_multiple_all_datasets_selected" - name="search_multiple_all_datasets_selected" - formControlName="search_multiple_all_datasets_selected"> - <label class="custom-control-label" for="search_multiple_all_datasets_selected">All datasets with cone search enabled selected by default</label> - </div> - <div class="custom-control custom-switch mb-2"> - <input class="custom-control-input" type="checkbox" id="documentation_allowed" name="documentation_allowed" formControlName="documentation_allowed" (change)="checkDisableDocumentationAllowed()"> - <label class="custom-control-label" for="documentation_allowed">Documentation allowed</label> - </div> - <div class="form-group"> - <label for="documentation_label">Label</label> - <input type="text" class="form-control" id="documentation_label" formControlName="documentation_label"> - </div> - </accordion-group> - </accordion> + <div class="form-group"> + <label for="name">Name</label> + <input type="text" class="form-control" id="name" name="name" formControlName="name"> + </div> + <div class="form-group"> + <label for="label">Label</label> + <input type="text" class="form-control" id="label" name="label" formControlName="label"> + </div> + <div class="form-group"> + <label for="description">Description</label> + <textarea class="form-control" rows="5" id="description" name="description" formControlName="description"></textarea> + </div> + <div class="form-group"> + <label for="display">Display</label> + <input type="number" class="form-control" id="display" name="display" formControlName="display"> + </div> + <app-data-path-form-control + [form]="form" + [rootDirectory]="rootDirectory" + [rootDirectoryIsLoading]="rootDirectoryIsLoading" + [rootDirectoryIsLoaded]="rootDirectoryIsLoaded" + (loadRootDirectory)="loadRootDirectory.emit($event)"> + </app-data-path-form-control> + <app-file-select-form-control + [form]="form" + [disabled]="isDataPathEmpty()" + [controlName]="'portal_logo'" + [controlLabel]="'Portal logo'" + [rootDirectory]="rootDirectory" + [rootDirectoryIsLoading]="rootDirectoryIsLoading" + [rootDirectoryIsLoaded]="rootDirectoryIsLoaded" + (loadRootDirectory)="loadRootDirectory.emit($event)"> + </app-file-select-form-control> + <div class="form-row"> + <div class="form-group col-md-6"> + <label for="design_color_picker">Instance color (picker)</label> + <input class="form-control" type="color" id="design_color_picker" [value]="form.value.design_color" formControlName="design_color"> + </div> + <div class="form-group col-md-6"> + <label for="design_color_input">Instance color (value)</label> + <input type="text" class="form-control" id="design_color_input" [value]="form.value.design_color" formControlName="design_color"> + </div> + </div> + <div class="form-row"> + <div class="form-group col-md-6"> + <label for="design_background_color_picker">Instance background color (picker)</label> + <input class="form-control" type="color" id="design_background_color_picker" [value]="form.value.design_background_color" formControlName="design_background_color"> + </div> + <div class="form-group col-md-6"> + <label for="design_background_color_input">Instance background color (value)</label> + <input type="text" class="form-control" id="design_background_color_input" [value]="form.value.design_background_color" formControlName="design_background_color"> + </div> + </div> + <app-file-select-form-control + [form]="form" + [disabled]="isDataPathEmpty()" + [controlName]="'design_logo'" + [controlLabel]="'Logo'" + [rootDirectory]="rootDirectory" + [rootDirectoryIsLoading]="rootDirectoryIsLoading" + [rootDirectoryIsLoaded]="rootDirectoryIsLoaded" + (loadRootDirectory)="loadRootDirectory.emit($event)"> + </app-file-select-form-control> + <app-file-select-form-control + [form]="form" + [disabled]="isDataPathEmpty()" + [controlName]="'design_favicon'" + [controlLabel]="'Favicon'" + [rootDirectory]="rootDirectory" + [rootDirectoryIsLoading]="rootDirectoryIsLoading" + [rootDirectoryIsLoaded]="rootDirectoryIsLoaded" + (loadRootDirectory)="loadRootDirectory.emit($event)"> + </app-file-select-form-control> + <div class="form-group"> + <label for="home_component">Component</label> + <select class="form-control" name="home_component" formControlName="home_component"> + <option value="WelcomeComponent">WelcomeComponent</option> + </select> + </div> + <div formGroupName="home_component_config"> + <div class="form-group"> + <label for="home_component_text">Text</label> + <textarea class="form-control" id="home_component_text" formControlName="home_component_text" rows="3"></textarea> + </div> + <app-file-select-form-control + [form]="getHomeConfigFormGroup()" + [controlName]="'home_component_logo'" + [controlLabel]="'Logo'" + [rootDirectory]="rootDirectory" + [rootDirectoryIsLoading]="rootDirectoryIsLoading" + [rootDirectoryIsLoaded]="rootDirectoryIsLoaded" + (loadRootDirectory)="loadRootDirectory.emit($event)"> + </app-file-select-form-control> + </div> + <div class="custom-control custom-switch mb-2"> + <input class="custom-control-input" type="checkbox" id="search_by_criteria_allowed" name="search_by_criteria_allowed" formControlName="search_by_criteria_allowed" (change)="checkDisableSearchByCriteriaAllowed()"> + <label class="custom-control-label" for="search_by_criteria_allowed">Classic search allowed</label> + </div> + <div class="form-group"> + <label for="search_by_criteria_label">Label</label> + <input type="text" class="form-control" id="search_by_criteria_label" formControlName="search_by_criteria_label"> + </div> + <div class="custom-control custom-switch mb-2"> + <input class="custom-control-input" type="checkbox" id="search_multiple_allowed" name="search_multiple_allowed" formControlName="search_multiple_allowed" (change)="checkDisableAllDatasetsSelected()"> + <label class="custom-control-label" for="search_multiple_allowed">Search multiple allowed</label> + </div> + <div class="form-group"> + <label for="search_multiple_label">Label</label> + <input type="text" class="form-control" id="search_multiple_label" formControlName="search_multiple_label"> + </div> + <div class="custom-control custom-switch"> + <input class="custom-control-input" + type="checkbox" + id="search_multiple_all_datasets_selected" + name="search_multiple_all_datasets_selected" + formControlName="search_multiple_all_datasets_selected"> + <label class="custom-control-label" for="search_multiple_all_datasets_selected">All datasets with cone search enabled selected by default</label> + </div> + <div class="custom-control custom-switch mb-2"> + <input class="custom-control-input" type="checkbox" id="documentation_allowed" name="documentation_allowed" formControlName="documentation_allowed" (change)="checkDisableDocumentationAllowed()"> + <label class="custom-control-label" for="documentation_allowed">Documentation allowed</label> + </div> + <div class="form-group"> + <label for="documentation_label">Label</label> + <input type="text" class="form-control" id="documentation_label" formControlName="documentation_label"> + </div> <div class="form-group pt-4"> <ng-content></ng-content> </div> diff --git a/client/src/app/admin/instance/components/instance-form.component.ts b/client/src/app/admin/instance/components/instance-form.component.ts index 1abbbf85eb5299be44f642686fd4ca8c630e2df9..2b2c5c7623cd2c190882942c209df2d04b970c0c 100644 --- a/client/src/app/admin/instance/components/instance-form.component.ts +++ b/client/src/app/admin/instance/components/instance-form.component.ts @@ -30,6 +30,7 @@ export class InstanceFormComponent implements OnInit { description: new FormControl('', [Validators.required]), display: new FormControl('', [Validators.required]), data_path: new FormControl(''), + portal_logo: new FormControl(''), design_color: new FormControl('#7AC29A', [Validators.required]), design_background_color: new FormControl('#7AC29A', [Validators.required]), design_logo: new FormControl(''), diff --git a/client/src/app/instance/home/components/welcome.component.spec.ts b/client/src/app/instance/home/components/welcome.component.spec.ts index 72a01cbc38d5af0df724044b96b7c2b3dd567457..d3e2b087a54424e2d0ffcb827f210fcb0ec3cdcc 100644 --- a/client/src/app/instance/home/components/welcome.component.spec.ts +++ b/client/src/app/instance/home/components/welcome.component.spec.ts @@ -25,33 +25,26 @@ describe('[Instance][Home][Component] WelcomeComponent', () => { component.instance = { name: 'myInstance', label: 'My Instance', + description: 'My Instance description', + display: 10, data_path: 'data/path', - config: { - design: { - design_color: 'green', - design_background_color: 'darker green', - design_logo: 'path/to/logo', - design_favicon: 'path/to/favicon' - }, - home: { - home_component: 'HomeComponent', - home_config: { - home_component_text: 'Description', - home_component_logo: 'path/to/logo' - } - }, - search: { - search_by_criteria_allowed: true, - search_by_criteria_label: 'Search', - search_multiple_allowed: true, - search_multiple_label: 'Search multiple', - search_multiple_all_datasets_selected: true - }, - documentation: { - documentation_allowed: true, - documentation_label: 'Documentation' - } + portal_logo: 'logo.png', + design_color: 'green', + design_background_color: 'darker green', + design_logo: 'path/to/logo', + design_favicon: 'path/to/favicon', + home_component: 'HomeComponent', + home_component_config: { + home_component_text: 'Description', + home_component_logo: 'path/to/logo' }, + search_by_criteria_allowed: true, + search_by_criteria_label: 'Search', + search_multiple_allowed: true, + search_multiple_label: 'Search multiple', + search_multiple_all_datasets_selected: true, + documentation_allowed: true, + documentation_label: 'Documentation', nb_dataset_families: 1, nb_datasets: 2 }; diff --git a/client/src/app/instance/instance.component.spec.ts b/client/src/app/instance/instance.component.spec.ts index 1922398f3d5886c412179dd62a6e6791ffb3fb94..8547278ff618e9cca4d7baa8b00496b4dfe96f0d 100644 --- a/client/src/app/instance/instance.component.spec.ts +++ b/client/src/app/instance/instance.component.spec.ts @@ -59,33 +59,26 @@ describe('[Instance] InstanceComponent', () => { const instance: Instance = { name: 'myInstance', label: 'My Instance', + description: 'My Instance description', + display: 10, data_path: 'data/path', - config: { - design: { - design_color: 'green', - design_background_color: 'darker green', - design_logo: 'path/to/logo', - design_favicon: 'path/to/favicon' - }, - home: { - home_component: 'HomeComponent', - home_config: { - home_component_text: 'Description', - home_component_logo: 'path/to/logo' - } - }, - search: { - search_by_criteria_allowed: true, - search_by_criteria_label: 'Search', - search_multiple_allowed: true, - search_multiple_label: 'Search multiple', - search_multiple_all_datasets_selected: false - }, - documentation: { - documentation_allowed: true, - documentation_label: 'Documentation' - } + portal_logo: 'logo.png', + design_color: 'green', + design_background_color: 'darker green', + design_logo: 'path/to/logo', + design_favicon: 'path/to/favicon', + home_component: 'HomeComponent', + home_component_config: { + home_component_text: 'Description', + home_component_logo: 'path/to/logo' }, + search_by_criteria_allowed: true, + search_by_criteria_label: 'Search', + search_multiple_allowed: true, + search_multiple_label: 'Search multiple', + search_multiple_all_datasets_selected: false, + documentation_allowed: true, + documentation_label: 'Documentation', nb_dataset_families: 1, nb_datasets: 2 }; diff --git a/client/src/app/instance/search/components/progress-bar.component.spec.ts b/client/src/app/instance/search/components/progress-bar.component.spec.ts index bd02e50964b245a6ac466cb850c41e2ba0c28cd6..40937946eb2f6d2d4519eccfe8c38ed0f68d746b 100644 --- a/client/src/app/instance/search/components/progress-bar.component.spec.ts +++ b/client/src/app/instance/search/components/progress-bar.component.spec.ts @@ -41,33 +41,26 @@ describe('[Instance][Search][Component] ProgressBarComponent', () => { component.instance = { name: 'myInstance', label: 'My Instance', + description: 'My Instance description', + display: 10, data_path: 'data/path', - config: { - design: { - design_color: 'green', - design_background_color: 'darker green', - design_logo: 'path/to/logo', - design_favicon: 'path/to/favicon' - }, - home: { - home_component: 'HomeComponent', - home_config: { - home_component_text: 'Description', - home_component_logo: 'path/to/logo' - } - }, - search: { - search_by_criteria_allowed: true, - search_by_criteria_label: 'Search', - search_multiple_allowed: true, - search_multiple_label: 'Search multiple', - search_multiple_all_datasets_selected: false - }, - documentation: { - documentation_allowed: true, - documentation_label: 'Documentation' - } + portal_logo: 'logo.png', + design_color: 'green', + design_background_color: 'darker green', + design_logo: 'path/to/logo', + design_favicon: 'path/to/favicon', + home_component: 'HomeComponent', + home_component_config: { + home_component_text: 'Description', + home_component_logo: 'path/to/logo' }, + search_by_criteria_allowed: true, + search_by_criteria_label: 'Search', + search_multiple_allowed: true, + search_multiple_label: 'Search multiple', + search_multiple_all_datasets_selected: false, + documentation_allowed: true, + documentation_label: 'Documentation', nb_dataset_families: 1, nb_datasets: 2 }; @@ -80,33 +73,26 @@ describe('[Instance][Search][Component] ProgressBarComponent', () => { component.instance = { name: 'myInstance', label: 'My Instance', + description: 'My Instance description', + display: 10, data_path: 'data/path', - config: { - design: { - design_color: 'green', - design_background_color: 'darker green', - design_logo: 'path/to/logo', - design_favicon: 'path/to/favicon' - }, - home: { - home_component: 'HomeComponent', - home_config: { - home_component_text: 'Description', - home_component_logo: 'path/to/logo' - } - }, - search: { - search_by_criteria_allowed: true, - search_by_criteria_label: 'Search', - search_multiple_allowed: true, - search_multiple_label: 'Search multiple', - search_multiple_all_datasets_selected: false - }, - documentation: { - documentation_allowed: true, - documentation_label: 'Documentation' - } + portal_logo: 'logo.png', + design_color: 'green', + design_background_color: 'darker green', + design_logo: 'path/to/logo', + design_favicon: 'path/to/favicon', + home_component: 'HomeComponent', + home_component_config: { + home_component_text: 'Description', + home_component_logo: 'path/to/logo' }, + search_by_criteria_allowed: true, + search_by_criteria_label: 'Search', + search_multiple_allowed: true, + search_multiple_label: 'Search multiple', + search_multiple_all_datasets_selected: false, + documentation_allowed: true, + documentation_label: 'Documentation', nb_dataset_families: 1, nb_datasets: 2 }; diff --git a/client/src/app/instance/store/effects/search-multiple.effects.spec.ts b/client/src/app/instance/store/effects/search-multiple.effects.spec.ts index 39a5d9706b8c0bb22d3a63a2aed3b04cf93402fa..ca8a91b29eb86ac1c0ba008d8b7a949da4f9a585 100644 --- a/client/src/app/instance/store/effects/search-multiple.effects.spec.ts +++ b/client/src/app/instance/store/effects/search-multiple.effects.spec.ts @@ -132,33 +132,26 @@ describe('[Instance][Store] SearchMultipleEffects', () => { instanceSelector.selectInstanceByRouteName, { name: 'myInstance', label: 'My Instance', + description: 'My Instance description', + display: 10, data_path: 'data/path', - config: { - design: { - design_color: 'green', - design_background_color: 'darker green', - design_logo: 'path/to/logo', - design_favicon: 'path/to/favicon' - }, - home: { - home_component: 'HomeComponent', - home_config: { - home_component_text: 'Description', - home_component_logo: 'path/to/logo' - } - }, - search: { - search_by_criteria_allowed: true, - search_by_criteria_label: 'Search', - search_multiple_allowed: true, - search_multiple_label: 'Search multiple', - search_multiple_all_datasets_selected: false - }, - documentation: { - documentation_allowed: true, - documentation_label: 'Documentation' - } + portal_logo: 'logo.png', + design_color: 'green', + design_background_color: 'darker green', + design_logo: 'path/to/logo', + design_favicon: 'path/to/favicon', + home_component: 'HomeComponent', + home_component_config: { + home_component_text: 'Description', + home_component_logo: 'path/to/logo' }, + search_by_criteria_allowed: true, + search_by_criteria_label: 'Search', + search_multiple_allowed: true, + search_multiple_label: 'Search multiple', + search_multiple_all_datasets_selected: false, + documentation_allowed: true, + documentation_label: 'Documentation', nb_dataset_families: 1, nb_datasets: 2 } @@ -214,33 +207,26 @@ describe('[Instance][Store] SearchMultipleEffects', () => { instanceSelector.selectInstanceByRouteName, { name: 'myInstance', label: 'My Instance', + description: 'My Instance description', + display: 10, data_path: 'data/path', - config: { - design: { - design_color: 'green', - design_background_color: 'darker green', - design_logo: 'path/to/logo', - design_favicon: 'path/to/favicon' - }, - home: { - home_component: 'HomeComponent', - home_config: { - home_component_text: 'Description', - home_component_logo: 'path/to/logo' - } - }, - search: { - search_by_criteria_allowed: true, - search_by_criteria_label: 'Search', - search_multiple_allowed: true, - search_multiple_label: 'Search multiple', - search_multiple_all_datasets_selected: true - }, - documentation: { - documentation_allowed: true, - documentation_label: 'Documentation' - } + portal_logo: 'logo.png', + design_color: 'green', + design_background_color: 'darker green', + design_logo: 'path/to/logo', + design_favicon: 'path/to/favicon', + home_component: 'HomeComponent', + home_component_config: { + home_component_text: 'Description', + home_component_logo: 'path/to/logo' }, + search_by_criteria_allowed: true, + search_by_criteria_label: 'Search', + search_multiple_allowed: true, + search_multiple_label: 'Search multiple', + search_multiple_all_datasets_selected: true, + documentation_allowed: true, + documentation_label: 'Documentation', nb_dataset_families: 1, nb_datasets: 2 } diff --git a/client/src/app/metamodel/models/instance.model.ts b/client/src/app/metamodel/models/instance.model.ts index 8932221f4351e2fabdfc91216063b7271e97b0b2..8e35fa2ebc6435c32c2c26d3ad106896b68b76bb 100644 --- a/client/src/app/metamodel/models/instance.model.ts +++ b/client/src/app/metamodel/models/instance.model.ts @@ -18,6 +18,7 @@ export interface Instance { description: string; display: number; data_path: string; + portal_logo: string; design_color: string; design_background_color: string; design_logo: string; diff --git a/client/src/app/portal/components/instance-card.component.html b/client/src/app/portal/components/instance-card.component.html index d78f9f9214b3d036c99b3e1513dbbd8d26c089bf..67b3233d17a5be57497cab1ec7ab0f91510e2b61 100644 --- a/client/src/app/portal/components/instance-card.component.html +++ b/client/src/app/portal/components/instance-card.component.html @@ -1,7 +1,7 @@ -<div class="card"> - <!-- <img class="card-img-top" src="{{ getLogoSrc() }}" alt="Card image cap"> --> - <div class="card-header letter" [ngStyle]="{'background-color': instance.design_color }">{{ instance.label[0] }}</div> - <div class="card-body body"> +<div class="card card-instance"> + <img *ngIf="instance.portal_logo" class="card-header card-img-top card-instance-img" src="{{ getLogoSrc() }}" alt="Card image cap"> + <div *ngIf="!instance.portal_logo" class="card-header card-instance-letter" [ngStyle]="{'background-color': instance.design_color }">{{ instance.label[0] }}</div> + <div class="card-body card-instance-body"> <h5 class="card-title">{{ instance.label }}</h5> <p class="card-text">{{ instance.description }}</p> </div> diff --git a/client/src/app/portal/components/instance-card.component.scss b/client/src/app/portal/components/instance-card.component.scss index 6e4bdaddcacdab758cb46be6dec98295eaa7e63b..a934c5828048f99c934df30796a32ac0e033972f 100644 --- a/client/src/app/portal/components/instance-card.component.scss +++ b/client/src/app/portal/components/instance-card.component.scss @@ -1,10 +1,18 @@ -.letter { +.card-instance { + width: 300px; +} + +.card-instance-img { + height: 200px; +} + +.card-instance-letter { text-align: center; font-size: 50px; padding-top: 60px; height: 200px; } -.body { +.card-instance-body { height: 200px;; } \ No newline at end of file diff --git a/client/src/app/portal/components/instance-card.component.ts b/client/src/app/portal/components/instance-card.component.ts index 9f4c4f8b7e1a4e48ce2208de12f5720525f00f11..28263dbc3cc940b925ef6e385ffae9b6f482b9f6 100644 --- a/client/src/app/portal/components/instance-card.component.ts +++ b/client/src/app/portal/components/instance-card.component.ts @@ -24,8 +24,7 @@ import { Instance } from 'src/app/metamodel/models'; }) export class InstanceCardComponent { @Input() instance: Instance; - - public constructor(private config: AppConfigService) { } + @Input() apiUrl: string; /** * Returns the logo url. @@ -33,6 +32,6 @@ export class InstanceCardComponent { * @return string */ getLogoSrc(): string { - return `${this.config.apiUrl}/download-instance-file/${this.instance.name}/${this.instance.home_component_config.home_component_logo}`; + return `${this.apiUrl}/download-instance-file/${this.instance.name}/${this.instance.portal_logo}`; } } diff --git a/client/src/app/portal/containers/portal-home.component.html b/client/src/app/portal/containers/portal-home.component.html index 23c25a19dc5c1c0581db9e16288dabeb8b520e86..ed9b40ec610802e661884e0970100380fe001a49 100644 --- a/client/src/app/portal/containers/portal-home.component.html +++ b/client/src/app/portal/containers/portal-home.component.html @@ -15,10 +15,11 @@ </header> <main role="main" class="container-fluid pb-4"> <div class="container"> - <div class="row row-cols-1 row-cols-sm-2 row-cols-md-3"> - <div class="col mb-3" *ngFor="let instance of (instanceList | async)"> + <div class="row justify-content-center"> + <div class="col-auto mb-3" *ngFor="let instance of (instanceList | async)"> <app-instance-card - [instance]="instance"> + [instance]="instance" + [apiUrl]="getApiUrl()"> </app-instance-card> </div> </div> diff --git a/client/src/app/portal/containers/portal-home.component.spec.ts b/client/src/app/portal/containers/portal-home.component.spec.ts index fb23f5a379e8462723f7d537487265220c30b3c9..b0a1ec6ba757b9beedf5bdc040f2fd4b53ed85af 100644 --- a/client/src/app/portal/containers/portal-home.component.spec.ts +++ b/client/src/app/portal/containers/portal-home.component.spec.ts @@ -54,33 +54,6 @@ describe('[Instance][Portal][Container] PortalHomeComponent', () => { expect(component).toBeDefined(); }); - it('should execute ngOnInit lifecycle and add admin link if no authentication', () => { - appConfigServiceStub.authenticationEnabled = false; - component.ngOnInit(); - const expected = [ - { label: 'Home', icon: 'fas fa-home', routerLink: '/portal' }, - { label: 'Admin', icon: 'fas fa-tools', routerLink: '/admin' } - ]; - expect(component.links).toEqual(expected); - expect(component.favIcon.href).toEqual('http://localhost/favicon.ico'); - }); - - it('should execute ngOnInit lifecycle and add admin link depending on user rights', () => { - appConfigServiceStub.authenticationEnabled = true; - appConfigServiceStub.adminRoles = ['admin', 'superuser']; - component.userRoles = of([]); - component.ngOnInit(); - expect(component.links).toEqual([{ label: 'Home', icon: 'fas fa-home', routerLink: '/portal' }]); - component.userRoles = of(['admin']); - component.ngOnInit(); - const expected = [ - { label: 'Home', icon: 'fas fa-home', routerLink: '/portal' }, - { label: 'Admin', icon: 'fas fa-tools', routerLink: '/admin' } - ]; - expect(component.links).toEqual(expected); - - }); - it('#getBaseHref() should return base href config key value', () => { appConfigServiceStub.baseHref = '/my-project'; expect(component.getBaseHref()).toBe('/my-project'); @@ -111,11 +84,4 @@ describe('[Instance][Portal][Container] PortalHomeComponent', () => { expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledWith(authActions.openEditProfile()); }); - - it('should unsubscribe to user roles when component is destroyed', () => { - component.userRolesSubscription = of().subscribe(); - const spy = jest.spyOn(component.userRolesSubscription, 'unsubscribe'); - component.ngOnDestroy(); - expect(spy).toHaveBeenCalledTimes(1); - }); }); diff --git a/client/src/app/portal/containers/portal-home.component.ts b/client/src/app/portal/containers/portal-home.component.ts index 8f2732ae6ac75fa7bc9a4db103295bebfd3af90e..0b6160c891c5b46f31a52eda12c4ab8286f0b9a3 100644 --- a/client/src/app/portal/containers/portal-home.component.ts +++ b/client/src/app/portal/containers/portal-home.component.ts @@ -75,6 +75,10 @@ export class PortalHomeComponent implements OnInit { return this.config.adminRoles; } + getApiUrl(): string { + return this.config.apiUrl; + } + /** * Dispatches action to log in. */ diff --git a/client/src/app/shared/components/navbar.component.spec.ts b/client/src/app/shared/components/navbar.component.spec.ts index e130bac88362f0f9557a851a02d56802218cba83..99d766c3ae015c4888ca1e15dd3aad45c46b0ada 100644 --- a/client/src/app/shared/components/navbar.component.spec.ts +++ b/client/src/app/shared/components/navbar.component.spec.ts @@ -26,7 +26,7 @@ describe('[Shared][Component] NavbarComponent', () => { component.apiUrl = 'http://test.com'; component.instance = INSTANCE; expect(component.getLogoHref()).toEqual('http://test.com/download-instance-file/myInstance/path/to/logo'); - component.instance.config.design.design_logo = ''; + component.instance.design_logo = ''; expect(component.getLogoHref()).toEqual('assets/cesam_anis40.png'); }); }); diff --git a/client/src/test-data.ts b/client/src/test-data.ts index fbde4ef15bbaa951120e5135cb4f1561f9263573..61fdbda41a46f479ccdd1a6d9637370da1b712fe 100644 --- a/client/src/test-data.ts +++ b/client/src/test-data.ts @@ -77,66 +77,52 @@ export const INSTANCE_LIST: Instance[] = [ { name: 'myOtherInstance', label: 'My Other Instance', + description: 'My Other Instance description', + display: 30, data_path: 'data/path', - config: { - design: { - design_color: 'green', - design_background_color: 'darker green', - design_logo: 'path/to/logo', - design_favicon: 'path/to/favicon' - }, - home: { - home_component: 'HomeComponent', - home_config: { - home_component_text: 'Description', - home_component_logo: 'path/to/logo' - } - }, - search: { - search_by_criteria_allowed: false, - search_by_criteria_label: 'Search', - search_multiple_allowed: false, - search_multiple_label: 'Search multiple', - search_multiple_all_datasets_selected: false - }, - documentation: { - documentation_allowed: false, - documentation_label: 'Documentation' - } + portal_logo: '', + design_color: 'green', + design_background_color: 'darker green', + design_logo: 'path/to/logo', + design_favicon: 'path/to/favicon', + home_component: 'HomeComponent', + home_component_config: { + home_component_text: 'Description', + home_component_logo: 'path/to/logo' }, + search_by_criteria_allowed: false, + search_by_criteria_label: 'Search', + search_multiple_allowed: false, + search_multiple_label: 'Search multiple', + search_multiple_all_datasets_selected: false, + documentation_allowed: false, + documentation_label: 'Documentation', nb_dataset_families: 2, nb_datasets: 1 }, { name: 'myInstance', label: 'My Instance', + description: 'My Instance description', + display: 20, data_path: 'data/path', - config: { - design: { - design_color: 'green', - design_background_color: 'darker green', - design_logo: 'path/to/logo', - design_favicon: 'path/to/favicon' - }, - home: { - home_component: 'HomeComponent', - home_config: { - home_component_text: 'Description', - home_component_logo: 'path/to/logo' - } - }, - search: { - search_by_criteria_allowed: false, - search_by_criteria_label: 'Search', - search_multiple_allowed: false, - search_multiple_label: 'Search multiple', - search_multiple_all_datasets_selected: false - }, - documentation: { - documentation_allowed: false, - documentation_label: 'Documentation' - } + portal_logo: 'logo.png', + design_color: 'green', + design_background_color: 'darker green', + design_logo: 'path/to/logo', + design_favicon: 'path/to/favicon', + home_component: 'HomeComponent', + home_component_config: { + home_component_text: 'Description', + home_component_logo: 'path/to/logo' }, + search_by_criteria_allowed: false, + search_by_criteria_label: 'Search', + search_multiple_allowed: false, + search_multiple_label: 'Search multiple', + search_multiple_all_datasets_selected: false, + documentation_allowed: false, + documentation_label: 'Documentation', nb_dataset_families: 1, nb_datasets: 2 } @@ -145,33 +131,26 @@ export const INSTANCE_LIST: Instance[] = [ export const INSTANCE: Instance = { name: 'myInstance', label: 'My Instance', + description: 'My Instance description', + display: 10, data_path: 'data/path', - config: { - design: { - design_color: 'green', - design_background_color: 'darker green', - design_logo: 'path/to/logo', - design_favicon: 'path/to/favicon' - }, - home: { - home_component: 'HomeComponent', - home_config: { - home_component_text: 'Description', - home_component_logo: 'path/to/logo' - } - }, - search: { - search_by_criteria_allowed: false, - search_by_criteria_label: 'Search', - search_multiple_allowed: false, - search_multiple_label: 'Search multiple', - search_multiple_all_datasets_selected: false - }, - documentation: { - documentation_allowed: false, - documentation_label: 'Documentation' - } + portal_logo: 'logo.png', + design_color: 'green', + design_background_color: 'darker green', + design_logo: 'path/to/logo', + design_favicon: 'path/to/favicon', + home_component: 'HomeComponent', + home_component_config: { + home_component_text: 'Description', + home_component_logo: 'path/to/logo' }, + search_by_criteria_allowed: false, + search_by_criteria_label: 'Search', + search_multiple_allowed: false, + search_multiple_label: 'Search multiple', + search_multiple_all_datasets_selected: false, + documentation_allowed: false, + documentation_label: 'Documentation', nb_dataset_families: 1, nb_datasets: 2 }; diff --git a/conf-dev/create-db.sh b/conf-dev/create-db.sh index e414111ea0dd1f9574859376b6d43ea7594b9ddc..3c9463a9b13e70046988c075a935dced204652fc 100644 --- a/conf-dev/create-db.sh +++ b/conf-dev/create-db.sh @@ -60,7 +60,7 @@ curl -d '{"label":"Spectra graph","value":"spectra_graph","display":20,"select_n curl -d '{"label":"Test","dbname":"anis_test","dbtype":"pdo_pgsql","dbhost":"db","dbport":5432,"dblogin":"anis","dbpassword":"anis"}' --header 'Content-Type: application/json' -X POST http://localhost/database # Add default instance -curl -d '{"name":"default","label":"Default instance","description":"Instance for the test","display":10,"data_path":"\/DEFAULT","design_color":"#7AC29A","design_background_color":"#ffffff","design_logo":"logo.png","design_favicon":"favicon.ico","home_component":"WelcomeComponent","home_component_config":{"home_component_text":"AstroNomical Information System","home_component_logo":"home_component_logo.png"},"search_by_criteria_allowed":true,"search_by_criteria_label":"Search","search_multiple_allowed":false,"search_multiple_label":"Search multiple","search_multiple_all_datasets_selected":false,"documentation_allowed":false,"documentation_label":"Documentation"}' --header 'Content-Type: application/json' -X POST http://localhost/instance +curl -d '{"name":"default","label":"Default instance","description":"Instance for the test","display":10,"data_path":"\/DEFAULT","portal_logo":"","design_color":"#7AC29A","design_background_color":"#ffffff","design_logo":"logo.png","design_favicon":"favicon.ico","home_component":"WelcomeComponent","home_component_config":{"home_component_text":"AstroNomical Information System","home_component_logo":"home_component_logo.png"},"search_by_criteria_allowed":true,"search_by_criteria_label":"Search","search_multiple_allowed":false,"search_multiple_label":"Search multiple","search_multiple_all_datasets_selected":false,"documentation_allowed":false,"documentation_label":"Documentation"}' --header 'Content-Type: application/json' -X POST http://localhost/instance # Add ANIS, SVOM and IRIS surveys curl -d '{"name":"anis_survey","label":"ANIS survey","description":"Survey used for testing","link":"https://anis.lam.fr","manager":"F. Agneray","id_database":1}' --header 'Content-Type: application/json' -X POST http://localhost/survey diff --git a/server/doctrine-proxy/__CG__AppEntityInstance.php b/server/doctrine-proxy/__CG__AppEntityInstance.php index 106a754127d35392c714b3060593425c1f799f37..1a1fb7714f864b8e88e88952bb3f609d60d55e82 100644 --- a/server/doctrine-proxy/__CG__AppEntityInstance.php +++ b/server/doctrine-proxy/__CG__AppEntityInstance.php @@ -67,10 +67,10 @@ class Instance extends \App\Entity\Instance implements \Doctrine\ORM\Proxy\Proxy public function __sleep() { if ($this->__isInitialized__) { - return ['__isInitialized__', 'name', 'label', 'description', 'display', 'dataPath', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'homeComponent', 'homeComponentConfig', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies']; + return ['__isInitialized__', 'name', 'label', 'description', 'display', 'dataPath', 'portalLogo', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'homeComponent', 'homeComponentConfig', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies']; } - return ['__isInitialized__', 'name', 'label', 'description', 'display', 'dataPath', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'homeComponent', 'homeComponentConfig', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies']; + return ['__isInitialized__', 'name', 'label', 'description', 'display', 'dataPath', 'portalLogo', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'homeComponent', 'homeComponentConfig', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies']; } /** @@ -250,12 +250,12 @@ class Instance extends \App\Entity\Instance implements \Doctrine\ORM\Proxy\Proxy /** * {@inheritDoc} */ - public function setDislplay($display) + public function setDisplay($display) { - $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDislplay', [$display]); + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDisplay', [$display]); - return parent::setDislplay($display); + return parent::setDisplay($display); } /** @@ -280,6 +280,28 @@ class Instance extends \App\Entity\Instance implements \Doctrine\ORM\Proxy\Proxy return parent::setDataPath($dataPath); } + /** + * {@inheritDoc} + */ + public function getPortalLogo() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getPortalLogo', []); + + return parent::getPortalLogo(); + } + + /** + * {@inheritDoc} + */ + public function setPortalLogo($portalLogo) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setPortalLogo', [$portalLogo]); + + return parent::setPortalLogo($portalLogo); + } + /** * {@inheritDoc} */ diff --git a/server/src/Action/InstanceAction.php b/server/src/Action/InstanceAction.php index d757ce9b85e2af79519a2125f54e7e0773772515..a55a8d3abd4aa1d43a03870f8c40afbabde329b5 100644 --- a/server/src/Action/InstanceAction.php +++ b/server/src/Action/InstanceAction.php @@ -96,6 +96,7 @@ final class InstanceAction extends AbstractAction $instance->setDescription($parsedBody['description']); $instance->setDisplay($parsedBody['display']); $instance->setDataPath($parsedBody['data_path']); + $instance->setPortalLogo($parsedBody['portal_logo']); $instance->setDesignColor($parsedBody['design_color']); $instance->setDesignBackgroundColor($parsedBody['design_background_color']); $instance->setDesignLogo($parsedBody['design_logo']); @@ -109,7 +110,7 @@ final class InstanceAction extends AbstractAction $instance->setSearchMultipleAllDatasetsSelected($parsedBody['search_multiple_all_datasets_selected']); $instance->setDocumentationAllowed($parsedBody['documentation_allowed']); $instance->setDocumentationLabel($parsedBody['documentation_label']); - + $this->em->flush(); } } diff --git a/server/src/Action/InstanceListAction.php b/server/src/Action/InstanceListAction.php index b067d84039535775e5e9af6da30dac5ec01daf68..a5813a1df679ef2e7ad3c71f701b4728709d9cc5 100644 --- a/server/src/Action/InstanceListAction.php +++ b/server/src/Action/InstanceListAction.php @@ -79,6 +79,7 @@ final class InstanceListAction extends AbstractAction $instance->setDescription($parsedBody['description']); $instance->setDisplay($parsedBody['display']); $instance->setDataPath($parsedBody['data_path']); + $instance->setPortalLogo($parsedBody['portal_logo']); $instance->setDesignColor($parsedBody['design_color']); $instance->setDesignBackgroundColor($parsedBody['design_background_color']); $instance->setDesignLogo($parsedBody['design_logo']); diff --git a/server/src/Entity/Instance.php b/server/src/Entity/Instance.php index 307c42a8e5171e3a7b0cf13f4e4e3934179e4d11..9786c1380f72e613c5f3831c7826bc2e558a2617 100644 --- a/server/src/Entity/Instance.php +++ b/server/src/Entity/Instance.php @@ -59,6 +59,13 @@ class Instance implements \JsonSerializable */ protected $dataPath; + /** + * @var string + * + * @Column(type="string", name="portal_logo", nullable=true) + */ + protected $portalLogo; + /** * @var string * @@ -209,6 +216,16 @@ class Instance implements \JsonSerializable $this->dataPath = $dataPath; } + public function getPortalLogo() + { + return $this->portalLogo; + } + + public function setPortalLogo($portalLogo) + { + $this->portalLogo = $portalLogo; + } + public function getDesignColor() { return $this->designColor; @@ -361,6 +378,7 @@ class Instance implements \JsonSerializable 'description' => $this->getDescription(), 'display' => $this->getDisplay(), 'data_path' => $this->getDataPath(), + 'portal_logo' => $this->getPortalLogo(), 'design_color' => $this->getDesignColor(), 'design_background_color' => $this->getDesignBackgroundColor(), 'design_logo' => $this->getDesignLogo(), diff --git a/server/tests/Action/InstanceActionTest.php b/server/tests/Action/InstanceActionTest.php index 5b717a3a2dd358c5e8b38e160f66b430c55a6870..4410243c40d121b0a6d9ae7b3f5ccae6f4f048c4 100644 --- a/server/tests/Action/InstanceActionTest.php +++ b/server/tests/Action/InstanceActionTest.php @@ -77,9 +77,25 @@ final class InstanceActionTest extends TestCase $this->entityManager->expects($this->once())->method('flush'); $fields = array( - 'label' => 'AspiC', + 'name' => 'aspic', + 'label' => 'Aspic', + 'description' => 'Test', + 'display' => 10, 'data_path' => '/DEFAULT', - 'config' => '{}' + 'portal_logo' => '', + 'design_color' => '#7AC29A', + 'design_background_color' => '#FFFFFF', + 'design_logo' => 'logo.png', + 'design_favicon' => 'favicon.ico', + 'home_component' => 'WelcomeComponent', + 'home_component_config' => '{}', + 'search_by_criteria_allowed' => true, + 'search_by_criteria_label' => 'Search', + 'search_multiple_allowed' => false, + 'search_multiple_label' => 'Search multiple', + 'search_multiple_all_datasets_selected' => false, + 'documentation_allowed' => false, + 'documentation_label' => '' ); $request = $this->getRequest('PUT')->withParsedBody($fields); diff --git a/server/tests/Action/InstanceListActionTest.php b/server/tests/Action/InstanceListActionTest.php index 81c86466500f8515caccb29bbd7de4cb70e3a11e..3b4ad00027c8828923d052c33c4bb556324b2388 100644 --- a/server/tests/Action/InstanceListActionTest.php +++ b/server/tests/Action/InstanceListActionTest.php @@ -63,8 +63,23 @@ final class InstanceListActionTest extends TestCase $fields = array( 'name' => 'aspic', 'label' => 'Aspic', + 'description' => 'Test', + 'display' => 10, 'data_path' => '/DEFAULT', - 'config' => '{}' + 'portal_logo' => '', + 'design_color' => '#7AC29A', + 'design_background_color' => '#FFFFFF', + 'design_logo' => 'logo.png', + 'design_favicon' => 'favicon.ico', + 'home_component' => 'WelcomeComponent', + 'home_component_config' => '{}', + 'search_by_criteria_allowed' => true, + 'search_by_criteria_label' => 'Search', + 'search_multiple_allowed' => false, + 'search_multiple_label' => 'Search multiple', + 'search_multiple_all_datasets_selected' => false, + 'documentation_allowed' => false, + 'documentation_label' => '' ); $request = $this->getRequest('POST')->withParsedBody($fields);