diff --git a/client/src/app/admin/admin.component.html b/client/src/app/admin/admin.component.html index 61101934f1e33d3d27823eb8998cedcf423d891b..bd1e260acf97f000884a585cceef5991791c07e7 100644 --- a/client/src/app/admin/admin.component.html +++ b/client/src/app/admin/admin.component.html @@ -3,8 +3,11 @@ [links]="links" [isAuthenticated]="isAuthenticated | async" [userProfile]="userProfile | async" + [userRoles]="userRoles | async" [baseHref]="getBaseHref()" [authenticationEnabled]="getAuthenticationEnabled()" + [adminRoles]="getAdminRoles()" + [url]="url | async" (login)="login()" (logout)="logout()" (openEditProfile)="openEditProfile()"> diff --git a/client/src/app/admin/admin.component.ts b/client/src/app/admin/admin.component.ts index 2885ae4b6044d59ec72bcf3b8f126317965d6f3d..cce79cb11375e191e73845bfdb89937784e059a0 100644 --- a/client/src/app/admin/admin.component.ts +++ b/client/src/app/admin/admin.component.ts @@ -8,8 +8,10 @@ */ import { Component, OnInit } from '@angular/core'; + import { Observable } from 'rxjs'; import { Store } from '@ngrx/store'; +import * as fromRouter from '@ngrx/router-store'; import { UserProfile } from 'src/app/auth/user-profile.model'; import * as authActions from 'src/app/auth/auth.actions'; @@ -41,11 +43,13 @@ export class AdminComponent implements OnInit { public isAuthenticated: Observable<boolean>; public userProfile: Observable<UserProfile>; public userRoles: Observable<string[]>; + public url: Observable<string>; constructor(private store: Store<{ }>, private config: AppConfigService) { this.isAuthenticated = store.select(authSelector.selectIsAuthenticated); this.userProfile = store.select(authSelector.selectUserProfile); this.userRoles = store.select(authSelector.selectUserRoles); + this.url = store.select(fromRouter.getSelectors().selectUrl); } ngOnInit() { @@ -64,6 +68,10 @@ export class AdminComponent implements OnInit { return this.config.authenticationEnabled; } + getAdminRoles(): string[] { + return this.config.adminRoles; + } + login(): void { this.store.dispatch(authActions.login()); } diff --git a/client/src/app/admin/instance/components/design-form-group.component.html b/client/src/app/admin/instance/components/design-form-group.component.html deleted file mode 100644 index 7acdef818abaf83e53e31bbf92d84e168bc120ef..0000000000000000000000000000000000000000 --- a/client/src/app/admin/instance/components/design-form-group.component.html +++ /dev/null @@ -1,34 +0,0 @@ -<form [formGroup]="form" novalidate> - <accordion-group heading="Design"> - <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> - <app-file-select-form-control - [form]="form" - [disabled]="dataPathEmpty" - [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]="dataPathEmpty" - [controlName]="'design_favicon'" - [controlLabel]="'Favicon'" - [rootDirectory]="rootDirectory" - [rootDirectoryIsLoading]="rootDirectoryIsLoading" - [rootDirectoryIsLoaded]="rootDirectoryIsLoaded" - (loadRootDirectory)="loadRootDirectory.emit($event)"> - </app-file-select-form-control> - </accordion-group> -</form> diff --git a/client/src/app/admin/instance/components/design-form-group.component.ts b/client/src/app/admin/instance/components/design-form-group.component.ts deleted file mode 100644 index aa233db08a9269146caae2d9a77fbc74de94596b..0000000000000000000000000000000000000000 --- a/client/src/app/admin/instance/components/design-form-group.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * 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, Output, EventEmitter } from '@angular/core'; -import { FormGroup } from '@angular/forms'; - -import { FileInfo } from 'src/app/metamodel/models'; - -@Component({ - selector: 'app-design-form-group', - templateUrl: 'design-form-group.component.html' -}) -export class DesignFormGroupComponent { - @Input() form: FormGroup; - @Input() dataPathEmpty: boolean; - @Input() rootDirectory: FileInfo[]; - @Input() rootDirectoryIsLoading: boolean; - @Input() rootDirectoryIsLoaded: boolean; - @Output() loadRootDirectory: EventEmitter<string> = new EventEmitter(); -} diff --git a/client/src/app/admin/instance/components/documentation-form-group.component.html b/client/src/app/admin/instance/components/documentation-form-group.component.html deleted file mode 100644 index 4af970bf0aaff013360b5a39392a01d3e5961b80..0000000000000000000000000000000000000000 --- a/client/src/app/admin/instance/components/documentation-form-group.component.html +++ /dev/null @@ -1,12 +0,0 @@ -<form [formGroup]="form" novalidate> - <accordion-group heading="Documentation"> - <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> -</form> \ No newline at end of file diff --git a/client/src/app/admin/instance/components/documentation-form-group.component.ts b/client/src/app/admin/instance/components/documentation-form-group.component.ts deleted file mode 100644 index 3355e39992fb470a29080bde244c33f9df32b144..0000000000000000000000000000000000000000 --- a/client/src/app/admin/instance/components/documentation-form-group.component.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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'; -import { FormGroup } from '@angular/forms'; - -@Component({ - selector: 'app-documentation-form-group', - templateUrl: 'documentation-form-group.component.html' -}) -export class DocumentationFormGroupComponent { - @Input() form: FormGroup; - - checkDisableDocumentationAllowed() { - if (this.form.controls.documentation_allowed.value) { - this.form.controls.documentation_label.enable(); - } else { - this.form.controls.documentation_label.disable(); - } - } -} diff --git a/client/src/app/admin/instance/components/home-form-group.component.html b/client/src/app/admin/instance/components/home-form-group.component.html deleted file mode 100644 index 8ceb5c69277bd6f0727c0f481f0aa61f49d6bf33..0000000000000000000000000000000000000000 --- a/client/src/app/admin/instance/components/home-form-group.component.html +++ /dev/null @@ -1,25 +0,0 @@ -<form [formGroup]="form" novalidate> - <accordion-group heading="Home"> - <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_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> - </accordion-group> -</form> diff --git a/client/src/app/admin/instance/components/home-form-group.component.ts b/client/src/app/admin/instance/components/home-form-group.component.ts deleted file mode 100644 index df09361e62d91271ad60b5ec0b94579deeebfd48..0000000000000000000000000000000000000000 --- a/client/src/app/admin/instance/components/home-form-group.component.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * 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, Output, EventEmitter } from '@angular/core'; -import { FormGroup } from '@angular/forms'; - -import { FileInfo } from 'src/app/metamodel/models'; - -@Component({ - selector: 'app-home-form-group', - templateUrl: 'home-form-group.component.html' -}) -export class HomeFormGroupComponent { - @Input() form: FormGroup; - @Input() rootDirectory: FileInfo[]; - @Input() rootDirectoryIsLoading: boolean; - @Input() rootDirectoryIsLoaded: boolean; - @Output() loadRootDirectory: EventEmitter<string> = new EventEmitter(); - - getHomeConfigFormGroup() { - return this.form.controls.home_config as FormGroup; - } -} diff --git a/client/src/app/admin/instance/components/index.ts b/client/src/app/admin/instance/components/index.ts index 7dc39ff5ba6b4dedde8a7b374a59b1c0a2f987af..dda1856a82d5461b40dacdee91d4550b5dbca454 100644 --- a/client/src/app/admin/instance/components/index.ts +++ b/client/src/app/admin/instance/components/index.ts @@ -9,16 +9,8 @@ import { InstanceCardComponent } from './instance-card.component'; import { InstanceFormComponent } from './instance-form.component'; -import { DesignFormGroupComponent } from './design-form-group.component'; -import { HomeFormGroupComponent } from './home-form-group.component'; -import { SearchFormGroupComponent } from './search-form-group.component'; -import { DocumentationFormGroupComponent } from './documentation-form-group.component'; export const dummiesComponents = [ InstanceCardComponent, - InstanceFormComponent, - DesignFormGroupComponent, - HomeFormGroupComponent, - SearchFormGroupComponent, - DocumentationFormGroupComponent + InstanceFormComponent ]; 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 bf9b591dfd0280ef119cdb89144d90c5f7247af5..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,40 +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> - <app-data-path-form-control - [form]="form" - [rootDirectory]="rootDirectory" - [rootDirectoryIsLoading]="rootDirectoryIsLoading" - [rootDirectoryIsLoaded]="rootDirectoryIsLoaded" - (loadRootDirectory)="loadRootDirectory.emit($event)"> - </app-data-path-form-control> - </accordion-group> - <app-design-form-group - [form]="designFormGroup" - [dataPathEmpty]="isDataPathEmpty()" - [rootDirectory]="rootDirectory" - [rootDirectoryIsLoading]="rootDirectoryIsLoading" - [rootDirectoryIsLoaded]="rootDirectoryIsLoaded" - (loadRootDirectory)="onChangeSelectFile($event)"> - </app-design-form-group> - <app-home-form-group - [form]="homeFormGroup" + <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)="onChangeSelectFile($event)"> - </app-home-form-group> - <app-search-form-group [form]="searchFormGroup"></app-search-form-group> - <app-documentation-form-group [form]="documentationFormGroup"></app-documentation-form-group> - </accordion> + (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 d93bb0bd4080684338696921ffd07af8d9ddeebc..2b2c5c7623cd2c190882942c209df2d04b970c0c 100644 --- a/client/src/app/admin/instance/components/instance-form.component.ts +++ b/client/src/app/admin/instance/components/instance-form.component.ts @@ -24,80 +24,93 @@ export class InstanceFormComponent implements OnInit { @Output() loadRootDirectory: EventEmitter<string> = new EventEmitter(); @Output() onSubmit: EventEmitter<Instance> = new EventEmitter(); - public designFormGroup = new FormGroup({ + public form = new FormGroup({ + name: new FormControl('', [Validators.required]), + label: new FormControl('', [Validators.required]), + 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(''), - design_favicon: new FormControl('') - }); - - public homeFormGroup = new FormGroup({ + design_favicon: new FormControl(''), home_component: new FormControl('WelcomeComponent', [Validators.required]), - home_config: new FormGroup({ + home_component_config: new FormGroup({ home_component_text: new FormControl(`AstroNomical Information System is a generic web tool aimed at facilitating and homogenizing the implementation of astronomical data. It allows the fast implementation of a project data exchange platform in a dedicated information system.`, [Validators.required]), home_component_logo: new FormControl('home_component_logo.png', [Validators.required]) - }) - }); - - public searchFormGroup = new FormGroup({ + }), search_by_criteria_allowed: new FormControl(true), search_by_criteria_label: new FormControl({value: 'Search', disabled: false}), search_multiple_allowed: new FormControl(false), search_multiple_label: new FormControl({value: 'Search multiple', disabled: true}), - search_multiple_all_datasets_selected: new FormControl({value: false, disabled: true}) - }); - - public documentationFormGroup = new FormGroup({ + search_multiple_all_datasets_selected: new FormControl({value: false, disabled: true}), documentation_allowed: new FormControl(false), documentation_label: new FormControl({value: 'Documentation', disabled: true}) }); - public form = new FormGroup({ - name: new FormControl('', [Validators.required]), - label: new FormControl('', [Validators.required]), - data_path: new FormControl(''), - config: new FormGroup({ - design: this.designFormGroup, - home: this.homeFormGroup, - search: this.searchFormGroup, - documentation: this.documentationFormGroup - }) - }); - ngOnInit() { if (this.instance) { this.form.patchValue(this.instance); this.form.controls.name.disable(); - if (this.searchFormGroup.controls.search_multiple_allowed.value) { - this.searchFormGroup.controls.search_multiple_label.enable(); - this.searchFormGroup.controls.search_multiple_all_datasets_selected.enable(); + if (this.form.controls.search_multiple_allowed.value) { + this.form.controls.search_multiple_label.enable(); + this.form.controls.search_multiple_all_datasets_selected.enable(); } - if (this.searchFormGroup.controls.search_by_criteria_allowed.value) { - this.searchFormGroup.controls.search_by_criteria_label.enable(); + if (this.form.controls.search_by_criteria_allowed.value) { + this.form.controls.search_by_criteria_label.enable(); } - if (this.documentationFormGroup.controls.documentation_allowed.value) { - this.documentationFormGroup.controls.documentation_label.enable(); + if (this.form.controls.documentation_allowed.value) { + this.form.controls.documentation_label.enable(); } } } - onChangeSelectFile(path: string) { - this.loadRootDirectory.emit(`${this.form.controls.data_path.value}${path}`); - } - isDataPathEmpty() { return this.form.controls.data_path.value == ''; } + getHomeConfigFormGroup() { + return this.form.controls.home_component_config as FormGroup; + } + + checkDisableSearchByCriteriaAllowed() { + if (this.form.controls.search_by_criteria_allowed.value) { + this.form.controls.search_by_criteria_label.enable(); + } else { + this.form.controls.search_by_criteria_label.disable(); + } + } + + checkDisableAllDatasetsSelected() { + if (this.form.controls.search_multiple_allowed.value) { + this.form.controls.search_multiple_label.enable(); + this.form.controls.search_multiple_all_datasets_selected.enable(); + } else { + this.form.controls.search_multiple_label.disable(); + this.form.controls.search_multiple_all_datasets_selected.setValue(false); + this.form.controls.search_multiple_all_datasets_selected.disable(); + } + } + + checkDisableDocumentationAllowed() { + if (this.form.controls.documentation_allowed.value) { + this.form.controls.documentation_label.enable(); + } else { + this.form.controls.documentation_label.disable(); + } + } + submit() { if (this.instance) { this.onSubmit.emit({ ...this.instance, - ...this.form.value + ...this.form.getRawValue() }); } else { - this.onSubmit.emit(this.form.value); + this.onSubmit.emit(this.form.getRawValue()); } } } diff --git a/client/src/app/admin/instance/components/search-form-group.component.html b/client/src/app/admin/instance/components/search-form-group.component.html deleted file mode 100644 index 1c12343c9f1747b887de2f015f3ad760a90bf962..0000000000000000000000000000000000000000 --- a/client/src/app/admin/instance/components/search-form-group.component.html +++ /dev/null @@ -1,28 +0,0 @@ -<form [formGroup]="form" novalidate> - <accordion-group heading="Search"> - <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> - </accordion-group> -</form> diff --git a/client/src/app/admin/instance/components/search-form-group.component.ts b/client/src/app/admin/instance/components/search-form-group.component.ts deleted file mode 100644 index 4a96c1bfed521b6097ff19b9ee355bde36f22cb2..0000000000000000000000000000000000000000 --- a/client/src/app/admin/instance/components/search-form-group.component.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * 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'; -import { FormGroup } from '@angular/forms'; - -@Component({ - selector: 'app-search-form-group', - templateUrl: 'search-form-group.component.html' -}) -export class SearchFormGroupComponent { - @Input() form: FormGroup; - - checkDisableSearchByCriteriaAllowed() { - if (this.form.controls.search_by_criteria_allowed.value) { - this.form.controls.search_by_criteria_label.enable(); - } else { - this.form.controls.search_by_criteria_label.disable(); - } - } - - checkDisableAllDatasetsSelected() { - if (this.form.controls.search_multiple_allowed.value) { - this.form.controls.search_multiple_label.enable(); - this.form.controls.search_multiple_all_datasets_selected.enable(); - } else { - this.form.controls.search_multiple_label.disable(); - this.form.controls.search_multiple_all_datasets_selected.setValue(false); - this.form.controls.search_multiple_all_datasets_selected.disable(); - } - } -} diff --git a/client/src/app/core/containers/app.component.html b/client/src/app/core/containers/app.component.html index f2a02fb4e0ba8d88fbcec86d5ffbb05878082b7a..77e2f50660e633707463b9ec5b5cb7570bb1fc82 100644 --- a/client/src/app/core/containers/app.component.html +++ b/client/src/app/core/containers/app.component.html @@ -5,11 +5,11 @@ <router-outlet *ngIf="(instanceListIsLoaded | async)"></router-outlet> <footer class="footer mt-auto bg-light"> <div class="container my-3"> - <div class="row justify-content-center mb-3"> - <small>© ANIS 2014 - {{ year }}</small> + <div class="row justify-content-center font-weight-bold mb-1"> + © ANIS 2014 - {{ year }} </div> - <div class="row justify-content-center mb-4"> - <small>Currently based on anis-client v{{ anisClientVersion }}. Code licensed CeCILL.</small> + <div class="row justify-content-center font-weight-bold mb-4"> + Currently based on anis-client v{{ anisClientVersion }}. Code licensed CeCILL. </div> <div class="row justify-content-around"> <div class="col mb-3 text-center"> diff --git a/client/src/app/instance/home/components/welcome.component.html b/client/src/app/instance/home/components/welcome.component.html index b4132609fa7fc4db2e9e41022217580ed6c0222d..4413a0155a6a05ad2b662469dbee20ffa3982a4c 100644 --- a/client/src/app/instance/home/components/welcome.component.html +++ b/client/src/app/instance/home/components/welcome.component.html @@ -2,5 +2,5 @@ <div class="col-6 col-md-4 order-md-2 mx-auto text-center"> <img class="img-fluid mb-3 mb-md-0" src="{{ getLogoSrc() }}" alt="Instance logo"> </div> - <div class="col-md-8 order-md-1 text-justify pr-md-5" [innerHtml]="instance.config.home.home_config.home_component_text"></div> + <div class="col-md-8 order-md-1 text-justify pr-md-5" [innerHtml]="instance.home_component_config.home_component_text"></div> </div> 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/home/components/welcome.component.ts b/client/src/app/instance/home/components/welcome.component.ts index 8f54362d32ebd7cfc09bb19e39c16361a6193ab3..6eaf4c53a14d15805687e9a3901f78df9c56a4a6 100644 --- a/client/src/app/instance/home/components/welcome.component.ts +++ b/client/src/app/instance/home/components/welcome.component.ts @@ -30,6 +30,6 @@ export class WelcomeComponent { * @return string */ getLogoSrc(): string { - return `${this.apiUrl}/download-instance-file/${this.instance.name}/${this.instance.config.home.home_config.home_component_logo}`; + return `${this.apiUrl}/download-instance-file/${this.instance.name}/${this.instance.home_component_config.home_component_logo}`; } } diff --git a/client/src/app/instance/instance.component.html b/client/src/app/instance/instance.component.html index ef03a4e2a31e4b464ad0ca7c12ac0d95aa5ea0c8..e31861eec51d537e3f662d6054c19336ddd0c0da 100644 --- a/client/src/app/instance/instance.component.html +++ b/client/src/app/instance/instance.component.html @@ -3,8 +3,11 @@ [links]="links" [isAuthenticated]="isAuthenticated | async" [userProfile]="userProfile | async" + [userRoles]="userRoles | async" [baseHref]="getBaseHref()" [authenticationEnabled]="getAuthenticationEnabled()" + [adminRoles]="getAdminRoles()" + [url]="url | async" [apiUrl]="getApiUrl()" [instance]="instance | async" (login)="login()" 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/instance.component.ts b/client/src/app/instance/instance.component.ts index bb78d58ce124b33a795c7e5f88dc0fee2a80bc7a..ed464740b7ec3076326b25e487e8800fbc0e6cf9 100644 --- a/client/src/app/instance/instance.component.ts +++ b/client/src/app/instance/instance.component.ts @@ -11,6 +11,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable, Subscription } from 'rxjs'; +import * as fromRouter from '@ngrx/router-store'; import { UserProfile } from 'src/app/auth/user-profile.model'; import { Instance } from 'src/app/metamodel/models'; @@ -36,11 +37,14 @@ import { AppConfigService } from 'src/app/app-config.service'; export class InstanceComponent implements OnInit, OnDestroy { public favIcon: HTMLLinkElement = document.querySelector('#favicon'); public title: HTMLLinkElement = document.querySelector('#title'); - public links = [{ label: 'Home', icon: 'fas fa-home', routerLink: 'home' }]; + public links = [ + { label: 'Home', icon: 'fas fa-home', routerLink: 'home' } + ]; public instance: Observable<Instance>; public isAuthenticated: Observable<boolean>; public userProfile: Observable<UserProfile>; public userRoles: Observable<string[]>; + public url: Observable<string>; public instanceSubscription: Subscription; constructor(private store: Store<{ }>, private config: AppConfigService) { @@ -48,6 +52,7 @@ export class InstanceComponent implements OnInit, OnDestroy { this.isAuthenticated = store.select(authSelector.selectIsAuthenticated); this.userProfile = store.select(authSelector.selectUserProfile); this.userRoles = store.select(authSelector.selectUserRoles); + this.url = store.select(fromRouter.getSelectors().selectUrl); } ngOnInit() { @@ -57,19 +62,21 @@ export class InstanceComponent implements OnInit, OnDestroy { Promise.resolve(null).then(() => this.store.dispatch(datasetActions.loadDatasetList())); Promise.resolve(null).then(() => this.store.dispatch(surveyActions.loadSurveyList())); this.instanceSubscription = this.instance.subscribe(instance => { - if (instance.config.search.search_by_criteria_allowed) { - this.links.push({ label: instance.config.search.search_by_criteria_label, icon: 'fas fa-search', routerLink: 'search' }); + if (instance) { + if (instance.search_by_criteria_allowed) { + this.links.push({ label: instance.search_by_criteria_label, icon: 'fas fa-search', routerLink: 'search' }); + } + if (instance.search_multiple_allowed) { + this.links.push({ label: instance.search_multiple_label, icon: 'fas fa-search-plus', routerLink: 'search-multiple' }); + } + if (instance.documentation_allowed) { + this.links.push({ label: instance.documentation_label, icon: 'fas fa-question', routerLink: 'documentation' }); + } + if (instance.design_favicon !== '') { + this.favIcon.href = `${this.config.apiUrl}/download-instance-file/${instance.name}/${instance.design_favicon}`; + } + this.title.innerHTML = instance.label; } - if (instance.config.search.search_multiple_allowed) { - this.links.push({ label: instance.config.search.search_multiple_label, icon: 'fas fa-search-plus', routerLink: 'search-multiple' }); - } - if (instance.config.documentation.documentation_allowed) { - this.links.push({ label: instance.config.documentation.documentation_label, icon: 'fas fa-question', routerLink: 'documentation' }); - } - if (instance.config.design.design_favicon !== '') { - this.favIcon.href = `${this.config.apiUrl}/download-instance-file/${instance.name}/${instance.config.design.design_favicon}`; - } - this.title.innerHTML = instance.label; }) } @@ -91,6 +98,10 @@ export class InstanceComponent implements OnInit, OnDestroy { return this.config.authenticationEnabled; } + getAdminRoles(): string[] { + return this.config.adminRoles; + } + /** * Returns API URL. * diff --git a/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.html b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.html index 7ac8fc5b28b1f1ba5aea2ee70bc3f431787446ef..54904e5ecb171fded00a42d506b5e104c8e5d2da 100644 --- a/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.html +++ b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.html @@ -8,7 +8,7 @@ <div class="progress progress-with-circle"> <div class="progress-bar" [ngClass]="getStepClass()" - [ngStyle]="{'background-color': instance.config.design.design_color }" + [ngStyle]="{'background-color': instance.design_color }" role="progressbar" aria-valuenow="1" aria-valuemin="1" diff --git a/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.ts b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.ts index 0fbeafa0d654dac7fc133ccde1ee597140fbc43a..9a09a721236ea1f314b9958270f1b9b9690b77e7 100644 --- a/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.ts +++ b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.ts @@ -60,7 +60,7 @@ export class ProgressBarMultipleComponent { */ getNavItemAStyle(currentStep: string, checked: boolean): { color: string } | null { if (this.currentStep === currentStep || checked) { - return { 'color': this.instance.config.design.design_color } + return { 'color': this.instance.design_color } } return null; } @@ -76,12 +76,12 @@ export class ProgressBarMultipleComponent { getNavItemIconCircleStyle(currentStep: string, checked: boolean): any { let style = {}; if (this.currentStep === currentStep) { - style['border-color'] = this.instance.config.design.design_color; - style['background-color'] = this.instance.config.design.design_color; + style['border-color'] = this.instance.design_color; + style['background-color'] = this.instance.design_color; } if (checked) { - style['border-color'] = this.instance.config.design.design_color; - style['color'] = this.instance.config.design.design_color; + style['border-color'] = this.instance.design_color; + style['color'] = this.instance.design_color; } return style; } diff --git a/client/src/app/instance/search/components/progress-bar.component.html b/client/src/app/instance/search/components/progress-bar.component.html index b248b98ca39a6d168c490a0d93ee6e375aa01b19..797513487ceca35b94deac0f758a336468008e51 100644 --- a/client/src/app/instance/search/components/progress-bar.component.html +++ b/client/src/app/instance/search/components/progress-bar.component.html @@ -8,7 +8,7 @@ <div class="progress progress-with-circle"> <div class="progress-bar" [ngClass]="getStepClass()" - [ngStyle]="{'background-color': instance.config.design.design_color }" + [ngStyle]="{'background-color': instance.design_color }" role="progressbar" aria-valuenow="1" aria-valuemin="1" 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/search/components/progress-bar.component.ts b/client/src/app/instance/search/components/progress-bar.component.ts index 64a727878469177543983997f63934430c9d057b..ed20b92f0361354ad8723378f8709a56c795466f 100644 --- a/client/src/app/instance/search/components/progress-bar.component.ts +++ b/client/src/app/instance/search/components/progress-bar.component.ts @@ -60,7 +60,7 @@ export class ProgressBarComponent { getNavItemAStyle(currentStep: string, checked: boolean): { color: string } | null { if (this.currentStep === currentStep || checked) { return { - 'color': this.instance.config.design.design_color + 'color': this.instance.design_color } } else { return null; @@ -75,12 +75,12 @@ export class ProgressBarComponent { getNavItemIconCircleStyle(currentStep: string, checked: boolean): {} { let style = {}; if (this.currentStep === currentStep) { - style['border-color'] = this.instance.config.design.design_color; - style['background-color'] = this.instance.config.design.design_color; + style['border-color'] = this.instance.design_color; + style['background-color'] = this.instance.design_color; } if (checked) { - style['border-color'] = this.instance.config.design.design_color; - style['color'] = this.instance.config.design.design_color; + style['border-color'] = this.instance.design_color; + style['color'] = this.instance.design_color; } return style; } diff --git a/client/src/app/instance/search/components/result/datatable.component.html b/client/src/app/instance/search/components/result/datatable.component.html index 0647cae6aa7c479d26a4a022839dca28464509f0..587d19ee4cfa75a059af8ca2cd55704eadd3e6cf 100644 --- a/client/src/app/instance/search/components/result/datatable.component.html +++ b/client/src/app/instance/search/components/result/datatable.component.html @@ -35,7 +35,7 @@ <span class="far fa-square fa-lg text-secondary"></span> </span> <span *ngIf="isSelected(datum)"> - <span class="fas fa-check-square fa-lg" [ngStyle]="{ 'color': instance.config.design.design_color }"></span> + <span class="fas fa-check-square fa-lg" [ngStyle]="{ 'color': instance.design_color }"></span> </span> </button> </td> diff --git a/client/src/app/instance/search/containers/output.component.html b/client/src/app/instance/search/containers/output.component.html index 4e68b9b9cc56631b056a6459f61a8283a91094f8..a5ecb6dadc1fd1a5579fa7aee35520db9a3b37c0 100644 --- a/client/src/app/instance/search/containers/output.component.html +++ b/client/src/app/instance/search/containers/output.component.html @@ -12,7 +12,7 @@ [outputFamilyList]="outputFamilyList | async" [outputCategoryList]="outputCategoryList | async" [outputList]="outputList | async" - [designColor]="(instance | async).config.design.design_color" + [designColor]="(instance | async).design_color" (change)="updateOutputList($event)"> </app-output-tabs> </div> 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/instance/store/effects/search-multiple.effects.ts b/client/src/app/instance/store/effects/search-multiple.effects.ts index 129727b1be6ec10ef13edab17cbb4e49947e947e..bfdf3a1bf9aa7732e14d6665c8f50d9b9393ccc0 100644 --- a/client/src/app/instance/store/effects/search-multiple.effects.ts +++ b/client/src/app/instance/store/effects/search-multiple.effects.ts @@ -77,7 +77,7 @@ export class SearchMultipleEffects { searchMultipleActions.updateSelectedDatasets({ selectedDatasets }), searchMultipleActions.checkDatasets() ); - } else if (instance.config.search.search_multiple_all_datasets_selected) { + } else if (instance.search_multiple_all_datasets_selected) { const selectedDatasets = datasetList.map(dataset => dataset.name); actions.push( searchMultipleActions.updateSelectedDatasets({ selectedDatasets }) diff --git a/client/src/app/metamodel/models/instance.model.ts b/client/src/app/metamodel/models/instance.model.ts index bbb5436413cfed03eb5fe121d83183fab8d11246..8e35fa2ebc6435c32c2c26d3ad106896b68b76bb 100644 --- a/client/src/app/metamodel/models/instance.model.ts +++ b/client/src/app/metamodel/models/instance.model.ts @@ -15,33 +15,26 @@ export interface Instance { name: string; label: string; + description: string; + display: number; data_path: string; - config: { - design: { - design_color: string; - design_background_color: string; - design_logo: string; - design_favicon: string; - }; - home: { - home_component: string; - home_config: { - home_component_text: string; - home_component_logo: string; - }; - }; - search: { - search_by_criteria_allowed: boolean; - search_by_criteria_label: string; - search_multiple_allowed: boolean; - search_multiple_label: string; - search_multiple_all_datasets_selected: boolean; - }; - documentation: { - documentation_allowed: boolean; - documentation_label: string; - }; + portal_logo: string; + design_color: string; + design_background_color: string; + design_logo: string; + design_favicon: string; + home_component: string; + home_component_config: { + home_component_text: string; + home_component_logo: string; }; + search_by_criteria_allowed: boolean; + search_by_criteria_label: string; + search_multiple_allowed: boolean; + search_multiple_label: string; + search_multiple_all_datasets_selected: boolean; + documentation_allowed: boolean; + documentation_label: string; nb_dataset_families: number; nb_datasets: number; } diff --git a/client/src/app/metamodel/reducers/instance.reducer.ts b/client/src/app/metamodel/reducers/instance.reducer.ts index e9f454ef2dae9be6d92023c64e4a30ef7ac6baf0..5b5d0ff9c1b5af181b1108bc06b12b5539daa82a 100644 --- a/client/src/app/metamodel/reducers/instance.reducer.ts +++ b/client/src/app/metamodel/reducers/instance.reducer.ts @@ -25,7 +25,7 @@ export interface State extends EntityState<Instance> { export const adapter: EntityAdapter<Instance> = createEntityAdapter<Instance>({ selectId: (instance: Instance) => instance.name, - sortComparer: (a: Instance, b: Instance) => a.name.localeCompare(b.name) + sortComparer: (a: Instance, b: Instance) => a.display - b.display }); export const initialState: State = adapter.getInitialState({ diff --git a/client/src/app/portal/components/instance-card.component.html b/client/src/app/portal/components/instance-card.component.html index 2916864f55780973f006196bb77f59c6c89c1eb7..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,9 @@ -<div class="card" style="width: 18rem;"> - <div class="card-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">Some quick example text to build on the card title and make up the bulk of the card's content.</p> + <p class="card-text">{{ instance.description }}</p> </div> <div class="card-footer bg-transparent text-right"> <a routerLink="/instance/{{ instance.name }}" class="btn btn-outline-primary" title="Go to instance"> diff --git a/client/src/app/portal/components/instance-card.component.scss b/client/src/app/portal/components/instance-card.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..a934c5828048f99c934df30796a32ac0e033972f --- /dev/null +++ b/client/src/app/portal/components/instance-card.component.scss @@ -0,0 +1,18 @@ +.card-instance { + width: 300px; +} + +.card-instance-img { + height: 200px; +} + +.card-instance-letter { + text-align: center; + font-size: 50px; + padding-top: 60px; + height: 200px; +} + +.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 c50e4b734d74a0e6c02d73430db6a8bedeb4af01..28263dbc3cc940b925ef6e385ffae9b6f482b9f6 100644 --- a/client/src/app/portal/components/instance-card.component.ts +++ b/client/src/app/portal/components/instance-card.component.ts @@ -9,6 +9,7 @@ import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; +import { AppConfigService } from 'src/app/app-config.service'; import { Instance } from 'src/app/metamodel/models'; /** @@ -18,8 +19,19 @@ import { Instance } from 'src/app/metamodel/models'; @Component({ selector: 'app-instance-card', templateUrl: 'instance-card.component.html', + styleUrls: ['instance-card.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class InstanceCardComponent { @Input() instance: Instance; + @Input() apiUrl: string; + + /** + * Returns the logo url. + * + * @return string + */ + getLogoSrc(): string { + 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 5d6bf9146dec27e20d822b19578f7a4d7eb801c9..ed9b40ec610802e661884e0970100380fe001a49 100644 --- a/client/src/app/portal/containers/portal-home.component.html +++ b/client/src/app/portal/containers/portal-home.component.html @@ -3,8 +3,11 @@ [links]="links" [isAuthenticated]="isAuthenticated | async" [userProfile]="userProfile | async" + [userRoles]="userRoles | async" [baseHref]="getBaseHref()" [authenticationEnabled]="getAuthenticationEnabled()" + [adminRoles]="getAdminRoles()" + [url]="url | async" (login)="login()" (logout)="logout()" (openEditProfile)="openEditProfile()"> @@ -12,12 +15,13 @@ </header> <main role="main" class="container-fluid pb-4"> <div class="container"> - <div class="row"> - <app-instance-card - *ngFor="let instance of (instanceList | async)" - [instance]="instance" - class="pointer"> - </app-instance-card> + <div class="row justify-content-center"> + <div class="col-auto mb-3" *ngFor="let instance of (instanceList | async)"> + <app-instance-card + [instance]="instance" + [apiUrl]="getApiUrl()"> + </app-instance-card> + </div> </div> </div> </main> 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 37fcb45986a4045283b1c7842737c0e5e93fd610..0b6160c891c5b46f31a52eda12c4ab8286f0b9a3 100644 --- a/client/src/app/portal/containers/portal-home.component.ts +++ b/client/src/app/portal/containers/portal-home.component.ts @@ -7,10 +7,11 @@ * file that was distributed with this source code. */ -import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { Observable, Subscription } from 'rxjs'; import { Store } from '@ngrx/store'; +import * as fromRouter from '@ngrx/router-store'; import { UserProfile } from 'src/app/auth/user-profile.model'; import { Instance } from 'src/app/metamodel/models'; @@ -30,13 +31,14 @@ import { AppConfigService } from 'src/app/app-config.service'; selector: 'app-portal-home', templateUrl: 'portal-home.component.html' }) -export class PortalHomeComponent implements OnInit, OnDestroy { +export class PortalHomeComponent implements OnInit { public favIcon: HTMLLinkElement = document.querySelector('#favicon'); - public links = [{ label: 'Home', icon: 'fas fa-home', routerLink: '/portal' }]; + public links = []; public isAuthenticated: Observable<boolean>; public userProfile: Observable<UserProfile>; public userRoles: Observable<string[]>; public instanceList: Observable<Instance[]>; + public url: Observable<string>; public userRolesSubscription: Subscription; constructor(private store: Store<{ }>, private config: AppConfigService) { @@ -44,26 +46,11 @@ export class PortalHomeComponent implements OnInit, OnDestroy { this.userProfile = store.select(authSelector.selectUserProfile); this.userRoles = store.select(authSelector.selectUserRoles); this.instanceList = store.select(instanceSelector.selectAllInstances); + this.url = store.select(fromRouter.getSelectors().selectUrl); } ngOnInit() { this.favIcon.href = 'favicon.ico'; - const adminLink = { label: 'Admin', icon: 'fas fa-tools', routerLink: '/admin' }; - if (!this.config.authenticationEnabled) { - this.links.push(adminLink); - } else { - this.userRolesSubscription = this.userRoles.subscribe(userRoles => { - let admin = false; - for (let i = 0; i < this.config.adminRoles.length; i++) { - admin = userRoles.includes(this.config.adminRoles[i]); - if (admin) break; - } - - if (admin) { - this.links.push(adminLink); - } - }); - } } /** @@ -84,6 +71,14 @@ export class PortalHomeComponent implements OnInit, OnDestroy { return this.config.authenticationEnabled; } + getAdminRoles(): string[] { + return this.config.adminRoles; + } + + getApiUrl(): string { + return this.config.apiUrl; + } + /** * Dispatches action to log in. */ @@ -104,11 +99,4 @@ export class PortalHomeComponent implements OnInit, OnDestroy { openEditProfile(): void { this.store.dispatch(authActions.openEditProfile()); } - - /** - * Unsubscribes to user roles when component is destroyed. - */ - ngOnDestroy(): void { - if (this.userRolesSubscription) this.userRolesSubscription.unsubscribe(); - } } diff --git a/client/src/app/shared/components/navbar.component.html b/client/src/app/shared/components/navbar.component.html index 6213927093e79526d7ccd9dc4ea7b77d689c2297..fd2da6ba9d12ab06e39d6857cac1b1f0cb2f7574 100644 --- a/client/src/app/shared/components/navbar.component.html +++ b/client/src/app/shared/components/navbar.component.html @@ -17,6 +17,18 @@ </a> </li> </ul> + <ul class="navbar-nav justify-content-end"> + <li class="nav-item pr-3"> + <a *ngIf="!isPortalRoute()" class="nav-link" routerLink="/portal" routerLinkActive="active"> + <span class="fa-solid fa-right-to-bracket"></span> Back to portal + </a> + </li> + <li *ngIf="!authenticationEnabled && !isAdminRoute()" class="nav-item pr-3"> + <a class="nav-link" routerLink="/admin" routerLinkActive="active"> + <span class="fas fa-tools"></span> Admin + </a> + </li> + </ul> <button *ngIf="authenticationEnabled && !isAuthenticated" class="btn btn-outline-success my-2 my-sm-0" id="button-sign-in" @@ -25,7 +37,7 @@ </button> <span *ngIf="isAuthenticated" id="dropdown-menu" dropdown> <button id="button-basic" dropdownToggle type="button" class="btn btn-light" aria-controls="dropdown-basic"> - <span class="fa-stack" [ngStyle]="{ color: instance ? instance.config.design.design_color : '#7AC29A' }"> + <span class="fa-stack" [ngStyle]="{ color: instance ? instance.design_color : '#7AC29A' }"> <span class="fas fa-circle fa-2x"></span> <span class="fas fa-user fa-stack-1x fa-inverse"></span> </span> @@ -38,6 +50,9 @@ </li> <li class="divider dropdown-divider"></li> <li role="menuitem"> + <a *ngIf="isAdmin() && !isAdminRoute()" class="dropdown-item pointer" routerLink="/admin"> + <span class="fas fa-tools"></span> Admin + </a> <a class="dropdown-item pointer" (click)="openEditProfile.emit()"> <span class="fas fa-id-card"></span> Edit profile </a> @@ -62,14 +77,22 @@ <li *ngIf="isAuthenticated" role="menuitem"> <span class="dropdown-item font-italic">{{ userProfile.email }}</span> </li> - <li *ngIf="isAuthenticated" class="divider dropdown-divider"></li> + <li *ngIf="isAuthenticated && links.length > 0" class="divider dropdown-divider"></li> <li *ngFor="let link of links" role="menuitem"> <a class="dropdown-item" [routerLink]="link.routerLink"> <span [ngClass]="link.icon" class="fa-fw"></span> {{ link.label }} </a> </li> + <li role="menuitem"> + <a *ngIf="!isPortalRoute()" class="dropdown-item" routerLink="/portal"> + <span class="fa-solid fa-right-to-bracket fa-fw"></span> Back to portal + </a> + </li> <li *ngIf="isAuthenticated" class="divider dropdown-divider"></li> <li *ngIf="isAuthenticated" role="menuitem"> + <a *ngIf="isAdmin() && !isAdminRoute()" class="dropdown-item pointer" routerLink="/admin"> + <span class="fas fa-tools"></span> Admin + </a> <a class="dropdown-item pointer" (click)="openEditProfile.emit()"> <span class="fas fa-id-card"></span> Edit profile </a> 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/app/shared/components/navbar.component.ts b/client/src/app/shared/components/navbar.component.ts index 6dd71ea2ad04614e4056163940b62c58a9807c77..24d37cb2c53e6ff57e512a96bcecbe81fd247f1f 100644 --- a/client/src/app/shared/components/navbar.component.ts +++ b/client/src/app/shared/components/navbar.component.ts @@ -26,22 +26,48 @@ export class NavbarComponent { @Input() links: {label: string, icon: string, routerLink: string}[]; @Input() isAuthenticated: boolean; @Input() userProfile: UserProfile = null; + @Input() userRoles: string[]; @Input() baseHref: string; @Input() authenticationEnabled: boolean; @Input() apiUrl: string; + @Input() adminRoles: string[]; + @Input() url: string; @Input() instance: Instance; @Output() login: EventEmitter<any> = new EventEmitter(); @Output() logout: EventEmitter<any> = new EventEmitter(); @Output() openEditProfile: EventEmitter<any> = new EventEmitter(); + /** + * Returns true if user is admin + * + * @returns boolean + */ + isAdmin() { + let admin = false; + for (let i = 0; i < this.adminRoles.length; i++) { + admin = this.userRoles.includes(this.adminRoles[i]); + if (admin) break; + } + + return admin; + } + + isPortalRoute() { + return this.url.includes('portal'); + } + + isAdminRoute() { + return this.url.includes('admin'); + } + /** * Returns logo href. * * @return string */ getLogoHref(): string { - if (this.instance.config.design.design_logo) { - return `${this.apiUrl}/download-instance-file/${this.instance.name}/${this.instance.config.design.design_logo}`; + if (this.instance.design_logo) { + return `${this.apiUrl}/download-instance-file/${this.instance.name}/${this.instance.design_logo}`; } return '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 9d007ea5ebfee2df17a8ea0629c777ac335c8a89..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","data_path":"\/DEFAULT","config":{"design":{"design_color":"#7AC29A","design_logo":"logo.png","design_favicon":"favicon.ico"},"home":{"home_component":"WelcomeComponent","home_config":{"home_component_text":"AstroNomical Information System","home_component_logo":"home_component_logo.png"}},"search":{"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":{"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/cli-config.php b/server/cli-config.php index 6ad8fe5b787a83b0369c37ada6168e6ff64c8df1..d0351e855acb15e434fe25bff11bd0ccd160b1e4 100644 --- a/server/cli-config.php +++ b/server/cli-config.php @@ -27,9 +27,4 @@ if ($devMode) { $em = \Doctrine\ORM\EntityManager::create($database['connection_options'], $c); -$helpers = new Symfony\Component\Console\Helper\HelperSet(array( - 'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()), - 'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em) -)); - return \Doctrine\ORM\Tools\Console\ConsoleRunner::createHelperSet($em); diff --git a/server/doctrine-proxy/__CG__AppEntityAttribute.php b/server/doctrine-proxy/__CG__AppEntityAttribute.php index fecb1e943901737c21d88981d28e32bffa5614d9..f2c804ff7c8fa36ccb39646e673ab270dbe21789 100644 --- a/server/doctrine-proxy/__CG__AppEntityAttribute.php +++ b/server/doctrine-proxy/__CG__AppEntityAttribute.php @@ -2,6 +2,7 @@ namespace DoctrineProxies\__CG__\App\Entity; + /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR */ diff --git a/server/doctrine-proxy/__CG__AppEntityCriteriaFamily.php b/server/doctrine-proxy/__CG__AppEntityCriteriaFamily.php index f8c224adcdc3e9cb0079bb72e5482eb4abed8d0d..f872b7607c23c4273c75572033bf78e371c989a8 100644 --- a/server/doctrine-proxy/__CG__AppEntityCriteriaFamily.php +++ b/server/doctrine-proxy/__CG__AppEntityCriteriaFamily.php @@ -2,6 +2,7 @@ namespace DoctrineProxies\__CG__\App\Entity; + /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR */ diff --git a/server/doctrine-proxy/__CG__AppEntityDatabase.php b/server/doctrine-proxy/__CG__AppEntityDatabase.php index 29820260186af5992872186a4e379937fde60181..f700d2ed73f86ad1733d93c46265370ae6627a44 100644 --- a/server/doctrine-proxy/__CG__AppEntityDatabase.php +++ b/server/doctrine-proxy/__CG__AppEntityDatabase.php @@ -2,6 +2,7 @@ namespace DoctrineProxies\__CG__\App\Entity; + /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR */ diff --git a/server/doctrine-proxy/__CG__AppEntityDataset.php b/server/doctrine-proxy/__CG__AppEntityDataset.php index b4ef9b32f1f00f6bcd5228cc6e839d55547062b3..857d284e684341cef7497494ffbcf8b580a3323a 100644 --- a/server/doctrine-proxy/__CG__AppEntityDataset.php +++ b/server/doctrine-proxy/__CG__AppEntityDataset.php @@ -2,6 +2,7 @@ namespace DoctrineProxies\__CG__\App\Entity; + /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR */ diff --git a/server/doctrine-proxy/__CG__AppEntityDatasetFamily.php b/server/doctrine-proxy/__CG__AppEntityDatasetFamily.php index c933fe64e4f65af53d3d2caaa6c1f7bff0212c5e..1654475b0584bcb9bfe6449590bf906e20ce1f57 100644 --- a/server/doctrine-proxy/__CG__AppEntityDatasetFamily.php +++ b/server/doctrine-proxy/__CG__AppEntityDatasetFamily.php @@ -2,6 +2,7 @@ namespace DoctrineProxies\__CG__\App\Entity; + /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR */ diff --git a/server/doctrine-proxy/__CG__AppEntityGroup.php b/server/doctrine-proxy/__CG__AppEntityGroup.php index c8e25db74b26f3c60f4a144f5a9342662e127567..d416c30c0f006686a5d2631cd7bc379ca7650492 100644 --- a/server/doctrine-proxy/__CG__AppEntityGroup.php +++ b/server/doctrine-proxy/__CG__AppEntityGroup.php @@ -2,6 +2,7 @@ namespace DoctrineProxies\__CG__\App\Entity; + /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR */ diff --git a/server/doctrine-proxy/__CG__AppEntityInstance.php b/server/doctrine-proxy/__CG__AppEntityInstance.php index 1c792170673c2f0ae369dbd195300054c86522c1..1a1fb7714f864b8e88e88952bb3f609d60d55e82 100644 --- a/server/doctrine-proxy/__CG__AppEntityInstance.php +++ b/server/doctrine-proxy/__CG__AppEntityInstance.php @@ -2,6 +2,7 @@ namespace DoctrineProxies\__CG__\App\Entity; + /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR */ @@ -66,10 +67,10 @@ class Instance extends \App\Entity\Instance implements \Doctrine\ORM\Proxy\Proxy public function __sleep() { if ($this->__isInitialized__) { - return ['__isInitialized__', 'name', 'label', 'dataPath', 'config', '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', 'dataPath', 'config', 'datasetFamilies']; + return ['__isInitialized__', 'name', 'label', 'description', 'display', 'dataPath', 'portalLogo', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'homeComponent', 'homeComponentConfig', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies']; } /** @@ -213,6 +214,50 @@ class Instance extends \App\Entity\Instance implements \Doctrine\ORM\Proxy\Proxy return parent::setLabel($label); } + /** + * {@inheritDoc} + */ + public function getDescription() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getDescription', []); + + return parent::getDescription(); + } + + /** + * {@inheritDoc} + */ + public function setDescription($description) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDescription', [$description]); + + return parent::setDescription($description); + } + + /** + * {@inheritDoc} + */ + public function getDisplay() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getDisplay', []); + + return parent::getDisplay(); + } + + /** + * {@inheritDoc} + */ + public function setDisplay($display) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDisplay', [$display]); + + return parent::setDisplay($display); + } + /** * {@inheritDoc} */ @@ -238,23 +283,309 @@ class Instance extends \App\Entity\Instance implements \Doctrine\ORM\Proxy\Proxy /** * {@inheritDoc} */ - public function getConfig() + 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} + */ + public function getDesignColor() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getDesignColor', []); + + return parent::getDesignColor(); + } + + /** + * {@inheritDoc} + */ + public function setDesignColor($designColor) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDesignColor', [$designColor]); + + return parent::setDesignColor($designColor); + } + + /** + * {@inheritDoc} + */ + public function getDesignBackgroundColor() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getDesignBackgroundColor', []); + + return parent::getDesignBackgroundColor(); + } + + /** + * {@inheritDoc} + */ + public function setDesignBackgroundColor($designBackgroundColor) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDesignBackgroundColor', [$designBackgroundColor]); + + return parent::setDesignBackgroundColor($designBackgroundColor); + } + + /** + * {@inheritDoc} + */ + public function getDesignLogo() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getDesignLogo', []); + + return parent::getDesignLogo(); + } + + /** + * {@inheritDoc} + */ + public function setDesignLogo($designLogo) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDesignLogo', [$designLogo]); + + return parent::setDesignLogo($designLogo); + } + + /** + * {@inheritDoc} + */ + public function getDesignFavicon() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getDesignFavicon', []); + + return parent::getDesignFavicon(); + } + + /** + * {@inheritDoc} + */ + public function setDesignFavicon($designFavicon) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDesignFavicon', [$designFavicon]); + + return parent::setDesignFavicon($designFavicon); + } + + /** + * {@inheritDoc} + */ + public function getHomeComponent() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getHomeComponent', []); + + return parent::getHomeComponent(); + } + + /** + * {@inheritDoc} + */ + public function setHomeComponent($homeComponent) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setHomeComponent', [$homeComponent]); + + return parent::setHomeComponent($homeComponent); + } + + /** + * {@inheritDoc} + */ + public function getHomeComponentConfig() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getHomeComponentConfig', []); + + return parent::getHomeComponentConfig(); + } + + /** + * {@inheritDoc} + */ + public function setHomeComponentConfig($homeComponentConfig) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setHomeComponentConfig', [$homeComponentConfig]); + + return parent::setHomeComponentConfig($homeComponentConfig); + } + + /** + * {@inheritDoc} + */ + public function getSearchByCriteriaAllowed() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getSearchByCriteriaAllowed', []); + + return parent::getSearchByCriteriaAllowed(); + } + + /** + * {@inheritDoc} + */ + public function setSearchByCriteriaAllowed($searchByCriteriaAllowed) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setSearchByCriteriaAllowed', [$searchByCriteriaAllowed]); + + return parent::setSearchByCriteriaAllowed($searchByCriteriaAllowed); + } + + /** + * {@inheritDoc} + */ + public function getSearchByCriteriaLabel() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getSearchByCriteriaLabel', []); + + return parent::getSearchByCriteriaLabel(); + } + + /** + * {@inheritDoc} + */ + public function setSearchByCriteriaLabel($searchByCriteriaLabel) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setSearchByCriteriaLabel', [$searchByCriteriaLabel]); + + return parent::setSearchByCriteriaLabel($searchByCriteriaLabel); + } + + /** + * {@inheritDoc} + */ + public function getSearchMultipleAllowed() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getSearchMultipleAllowed', []); + + return parent::getSearchMultipleAllowed(); + } + + /** + * {@inheritDoc} + */ + public function setSearchMultipleAllowed($searchMultipleAllowed) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setSearchMultipleAllowed', [$searchMultipleAllowed]); + + return parent::setSearchMultipleAllowed($searchMultipleAllowed); + } + + /** + * {@inheritDoc} + */ + public function getSearchMultipleLabel() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getSearchMultipleLabel', []); + + return parent::getSearchMultipleLabel(); + } + + /** + * {@inheritDoc} + */ + public function setSearchMultipleLabel($searchMultipleLabel) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setSearchMultipleLabel', [$searchMultipleLabel]); + + return parent::setSearchMultipleLabel($searchMultipleLabel); + } + + /** + * {@inheritDoc} + */ + public function getSearchMultipleAllDatasetsSelected() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getSearchMultipleAllDatasetsSelected', []); + + return parent::getSearchMultipleAllDatasetsSelected(); + } + + /** + * {@inheritDoc} + */ + public function setSearchMultipleAllDatasetsSelected($searchMultipleAllDatasetsSelected) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setSearchMultipleAllDatasetsSelected', [$searchMultipleAllDatasetsSelected]); + + return parent::setSearchMultipleAllDatasetsSelected($searchMultipleAllDatasetsSelected); + } + + /** + * {@inheritDoc} + */ + public function getDocumentationAllowed() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getDocumentationAllowed', []); + + return parent::getDocumentationAllowed(); + } + + /** + * {@inheritDoc} + */ + public function setDocumentationAllowed($documentationAllowed) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDocumentationAllowed', [$documentationAllowed]); + + return parent::setDocumentationAllowed($documentationAllowed); + } + + /** + * {@inheritDoc} + */ + public function getDocumentationLabel() { - $this->__initializer__ && $this->__initializer__->__invoke($this, 'getConfig', []); + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getDocumentationLabel', []); - return parent::getConfig(); + return parent::getDocumentationLabel(); } /** * {@inheritDoc} */ - public function setConfig($config) + public function setDocumentationLabel($documentationLabel) { - $this->__initializer__ && $this->__initializer__->__invoke($this, 'setConfig', [$config]); + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDocumentationLabel', [$documentationLabel]); - return parent::setConfig($config); + return parent::setDocumentationLabel($documentationLabel); } /** diff --git a/server/doctrine-proxy/__CG__AppEntityOption.php b/server/doctrine-proxy/__CG__AppEntityOption.php index 10bf9bfcc96a44a50804f98ac73cf182428953f3..f101582d195f2863b3aeefd1c9ee2c28e664ad4b 100644 --- a/server/doctrine-proxy/__CG__AppEntityOption.php +++ b/server/doctrine-proxy/__CG__AppEntityOption.php @@ -2,6 +2,7 @@ namespace DoctrineProxies\__CG__\App\Entity; + /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR */ diff --git a/server/doctrine-proxy/__CG__AppEntityOutputCategory.php b/server/doctrine-proxy/__CG__AppEntityOutputCategory.php index 697217f516e344e8cf30ee837d935c8af6325ace..95d24126b098dbe59843f52f5704c2a4f1fdb258 100644 --- a/server/doctrine-proxy/__CG__AppEntityOutputCategory.php +++ b/server/doctrine-proxy/__CG__AppEntityOutputCategory.php @@ -2,6 +2,7 @@ namespace DoctrineProxies\__CG__\App\Entity; + /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR */ diff --git a/server/doctrine-proxy/__CG__AppEntityOutputFamily.php b/server/doctrine-proxy/__CG__AppEntityOutputFamily.php index 0faa5bac9862991679f0344787bc83b1a3ed9b7d..14fe15d5431a6f084cde701469a42bbce8121480 100644 --- a/server/doctrine-proxy/__CG__AppEntityOutputFamily.php +++ b/server/doctrine-proxy/__CG__AppEntityOutputFamily.php @@ -2,6 +2,7 @@ namespace DoctrineProxies\__CG__\App\Entity; + /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR */ diff --git a/server/doctrine-proxy/__CG__AppEntitySelect.php b/server/doctrine-proxy/__CG__AppEntitySelect.php index 88871e3465157f23680686957f07c70ad68960cc..00df23065298acf482a35cc3a1685f7eb5badc2c 100644 --- a/server/doctrine-proxy/__CG__AppEntitySelect.php +++ b/server/doctrine-proxy/__CG__AppEntitySelect.php @@ -2,6 +2,7 @@ namespace DoctrineProxies\__CG__\App\Entity; + /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR */ diff --git a/server/doctrine-proxy/__CG__AppEntitySurvey.php b/server/doctrine-proxy/__CG__AppEntitySurvey.php index 75107381de1471b664480b62b8713b1816833f38..aa09365115e9cb3c363ca1792b65ff15a75f62f0 100644 --- a/server/doctrine-proxy/__CG__AppEntitySurvey.php +++ b/server/doctrine-proxy/__CG__AppEntitySurvey.php @@ -2,6 +2,7 @@ namespace DoctrineProxies\__CG__\App\Entity; + /** * DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR */ diff --git a/server/src/Action/InstanceAction.php b/server/src/Action/InstanceAction.php index 82442eb8881917e3e9b2c9292758a7c513ec383c..a55a8d3abd4aa1d43a03870f8c40afbabde329b5 100644 --- a/server/src/Action/InstanceAction.php +++ b/server/src/Action/InstanceAction.php @@ -60,7 +60,7 @@ final class InstanceAction extends AbstractAction $parsedBody = $request->getParsedBody(); // If mandatories empty fields 400 - foreach (array('label', 'data_path') as $a) { + foreach (array('label') as $a) { if ($this->isEmptyField($a, $parsedBody)) { throw new HttpBadRequestException( $request, @@ -93,8 +93,24 @@ final class InstanceAction extends AbstractAction private function editInstance(Instance $instance, array $parsedBody): void { $instance->setLabel($parsedBody['label']); - $instance->setConfig($parsedBody['config']); + $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']); + $instance->setDesignFavicon($parsedBody['design_favicon']); + $instance->setHomeComponent($parsedBody['home_component']); + $instance->setHomeComponentConfig($parsedBody['home_component_config']); + $instance->setSearchByCriteriaAllowed($parsedBody['search_by_criteria_allowed']); + $instance->setSearchByCriteriaLabel($parsedBody['search_by_criteria_label']); + $instance->setSearchMultipleAllowed($parsedBody['search_multiple_allowed']); + $instance->setSearchMultipleLabel($parsedBody['search_multiple_label']); + $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 9e226441a04659f0e18a5ae2b3ce00c08ef3c6a6..a5813a1df679ef2e7ad3c71f701b4728709d9cc5 100644 --- a/server/src/Action/InstanceListAction.php +++ b/server/src/Action/InstanceListAction.php @@ -48,7 +48,7 @@ final class InstanceListAction extends AbstractAction $parsedBody = $request->getParsedBody(); // To work this action needs user information to update - foreach (array('name', 'label', 'data_path') as $a) { + foreach (array('name', 'label') as $a) { if ($this->isEmptyField($a, $parsedBody)) { throw new HttpBadRequestException( $request, @@ -76,8 +76,23 @@ final class InstanceListAction extends AbstractAction private function postInstance(array $parsedBody): Instance { $instance = new Instance($parsedBody['name'], $parsedBody['label']); - $instance->setConfig($parsedBody['config']); + $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']); + $instance->setDesignFavicon($parsedBody['design_favicon']); + $instance->setHomeComponent($parsedBody['home_component']); + $instance->setHomeComponentConfig($parsedBody['home_component_config']); + $instance->setSearchByCriteriaAllowed($parsedBody['search_by_criteria_allowed']); + $instance->setSearchByCriteriaLabel($parsedBody['search_by_criteria_label']); + $instance->setSearchMultipleAllowed($parsedBody['search_multiple_allowed']); + $instance->setSearchMultipleLabel($parsedBody['search_multiple_label']); + $instance->setSearchMultipleAllDatasetsSelected($parsedBody['search_multiple_all_datasets_selected']); + $instance->setDocumentationAllowed($parsedBody['documentation_allowed']); + $instance->setDocumentationLabel($parsedBody['documentation_label']); $this->em->persist($instance); $this->em->flush(); diff --git a/server/src/Entity/Instance.php b/server/src/Entity/Instance.php index e0e6f3850bd74aa4acdfb06d29d70ca17773cd1c..9786c1380f72e613c5f3831c7826bc2e558a2617 100644 --- a/server/src/Entity/Instance.php +++ b/server/src/Entity/Instance.php @@ -38,6 +38,20 @@ class Instance implements \JsonSerializable */ protected $label; + /** + * @var string + * + * @Column(type="text", nullable=true) + */ + protected $description; + + /** + * @var int + * + * @Column(type="integer", nullable=false) + */ + protected $display; + /** * @var string * @@ -48,9 +62,100 @@ class Instance implements \JsonSerializable /** * @var string * - * @Column(type="json", nullable=true) + * @Column(type="string", name="portal_logo", nullable=true) + */ + protected $portalLogo; + + /** + * @var string + * + * @Column(type="string", name="design_color", nullable=true) + */ + protected $designColor; + + /** + * @var string + * + * @Column(type="string", name="design_background_color", nullable=true) + */ + protected $designBackgroundColor; + + /** + * @var string + * + * @Column(type="string", name="design_logo", nullable=true) + */ + protected $designLogo; + + /** + * @var string + * + * @Column(type="string", name="design_favicon", nullable=true) + */ + protected $designFavicon; + + /** + * @var string + * + * @Column(type="string", name="home_component", nullable=true) + */ + protected $homeComponent; + + /** + * @var array + * + * @Column(type="json", name="home_component_config", nullable=true) + */ + protected $homeComponentConfig; + + /** + * @var bool + * + * @Column(type="boolean", name="search_by_criteria_allowed", nullable=false) + */ + protected $searchByCriteriaAllowed; + + /** + * @var string + * + * @Column(type="string", name="search_by_criteria_label", nullable=false) + */ + protected $searchByCriteriaLabel; + + /** + * @var bool + * + * @Column(type="boolean", name="search_multiple_allowed", nullable=false) + */ + protected $searchMultipleAllowed; + + /** + * @var string + * + * @Column(type="string", name="search_multiple_label", nullable=false) + */ + protected $searchMultipleLabel; + + /** + * @var bool + * + * @Column(type="boolean", name="search_multiple_all_datasets_selected", nullable=false) + */ + protected $searchMultipleAllDatasetsSelected; + + /** + * @var bool + * + * @Column(type="boolean", name="documentation_allowed", nullable=false) + */ + protected $documentationAllowed; + + /** + * @var string + * + * @Column(type="string", name="documentation_label", nullable=false) */ - protected $config; + protected $documentationLabel; /** * @var DatasetFamily[] @@ -81,6 +186,26 @@ class Instance implements \JsonSerializable $this->label = $label; } + public function getDescription() + { + return $this->description; + } + + public function setDescription($description) + { + $this->description = $description; + } + + public function getDisplay() + { + return $this->display; + } + + public function setDisplay($display) + { + $this->display = $display; + } + public function getDataPath() { return $this->dataPath; @@ -91,14 +216,144 @@ class Instance implements \JsonSerializable $this->dataPath = $dataPath; } - public function getConfig() + public function getPortalLogo() + { + return $this->portalLogo; + } + + public function setPortalLogo($portalLogo) + { + $this->portalLogo = $portalLogo; + } + + public function getDesignColor() + { + return $this->designColor; + } + + public function setDesignColor($designColor) + { + $this->designColor = $designColor; + } + + public function getDesignBackgroundColor() + { + return $this->designBackgroundColor; + } + + public function setDesignBackgroundColor($designBackgroundColor) + { + $this->designBackgroundColor = $designBackgroundColor; + } + + public function getDesignLogo() + { + return $this->designLogo; + } + + public function setDesignLogo($designLogo) + { + $this->designLogo = $designLogo; + } + + public function getDesignFavicon() + { + return $this->designFavicon; + } + + public function setDesignFavicon($designFavicon) + { + $this->designFavicon = $designFavicon; + } + + public function getHomeComponent() + { + return $this->homeComponent; + } + + public function setHomeComponent($homeComponent) + { + $this->homeComponent = $homeComponent; + } + + public function getHomeComponentConfig() + { + return $this->homeComponentConfig; + } + + public function setHomeComponentConfig($homeComponentConfig) + { + $this->homeComponentConfig = $homeComponentConfig; + } + + public function getSearchByCriteriaAllowed() + { + return $this->searchByCriteriaAllowed; + } + + public function setSearchByCriteriaAllowed($searchByCriteriaAllowed) + { + $this->searchByCriteriaAllowed = $searchByCriteriaAllowed; + } + + public function getSearchByCriteriaLabel() + { + return $this->searchByCriteriaLabel; + } + + public function setSearchByCriteriaLabel($searchByCriteriaLabel) + { + $this->searchByCriteriaLabel = $searchByCriteriaLabel; + } + + public function getSearchMultipleAllowed() + { + return $this->searchMultipleAllowed; + } + + public function setSearchMultipleAllowed($searchMultipleAllowed) + { + $this->searchMultipleAllowed = $searchMultipleAllowed; + } + + public function getSearchMultipleLabel() + { + return $this->searchMultipleLabel; + } + + public function setSearchMultipleLabel($searchMultipleLabel) + { + $this->searchMultipleLabel = $searchMultipleLabel; + } + + public function getSearchMultipleAllDatasetsSelected() + { + return $this->searchMultipleAllDatasetsSelected; + } + + public function setSearchMultipleAllDatasetsSelected($searchMultipleAllDatasetsSelected) + { + $this->searchMultipleAllDatasetsSelected = $searchMultipleAllDatasetsSelected; + } + + public function getDocumentationAllowed() + { + return $this->documentationAllowed; + } + + public function setDocumentationAllowed($documentationAllowed) + { + $this->documentationAllowed = $documentationAllowed; + } + + public function getDocumentationLabel() { - return $this->config; + return $this->documentationLabel; } - public function setConfig($config) + public function setDocumentationLabel($documentationLabel) { - $this->config = $config; + $this->documentationLabel = $documentationLabel; } public function getDatasetFamilies() @@ -120,8 +375,23 @@ class Instance implements \JsonSerializable return [ 'name' => $this->getName(), 'label' => $this->getLabel(), + 'description' => $this->getDescription(), + 'display' => $this->getDisplay(), 'data_path' => $this->getDataPath(), - 'config' => $this->getConfig(), + 'portal_logo' => $this->getPortalLogo(), + 'design_color' => $this->getDesignColor(), + 'design_background_color' => $this->getDesignBackgroundColor(), + 'design_logo' => $this->getDesignLogo(), + 'design_favicon' => $this->getDesignFavicon(), + 'home_component' => $this->getHomeComponent(), + 'home_component_config' => $this->getHomeComponentConfig(), + 'search_by_criteria_allowed' => $this->getSearchByCriteriaAllowed(), + 'search_by_criteria_label' => $this->getSearchByCriteriaLabel(), + 'search_multiple_allowed' => $this->getSearchMultipleAllowed(), + 'search_multiple_label' => $this->getSearchMultipleLabel(), + 'search_multiple_all_datasets_selected' => $this->getSearchMultipleAllDatasetsSelected(), + 'documentation_allowed' => $this->getDocumentationAllowed(), + 'documentation_label' => $this->getDocumentationLabel(), 'nb_dataset_families' => count($this->getDatasetFamilies()), 'nb_datasets' => $this->getNbDatasets() ]; 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);