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 604a1d433ce7e9b9f2a198587061997f40115a33..cfed0c6a9f7a37bef86543a6dd5b79fb9cf92c41 100644 --- a/client/src/app/admin/instance/components/instance-form.component.html +++ b/client/src/app/admin/instance/components/instance-form.component.html @@ -169,6 +169,10 @@ <input class="custom-control-input" type="checkbox" id="back_to_portal" name="back_to_portal" formControlName="back_to_portal"> <label class="custom-control-label" for="back_to_portal">Back to portal</label> </div> + <div class="custom-control custom-switch mb-2"> + <input class="custom-control-input" type="checkbox" id="user_menu_enabled" name="user_menu_enabled" formControlName="user_menu_enabled"> + <label class="custom-control-label" for="user_menu_enabled">User menu enabled</label> + </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> 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 2dd39b3bbdbf88c677557f0721d76fe064f4db3d..7bba768b7660ec90d1720c008f1fe2e85d124486 100644 --- a/client/src/app/admin/instance/components/instance-form.component.ts +++ b/client/src/app/admin/instance/components/instance-form.component.ts @@ -48,6 +48,7 @@ export class InstanceFormComponent implements OnInit { family_color: new UntypedFormControl('#212529'), samp_enabled: new UntypedFormControl(true), back_to_portal: new UntypedFormControl(true), + user_menu_enabled: new UntypedFormControl(true), search_by_criteria_allowed: new UntypedFormControl(true), search_by_criteria_label: new UntypedFormControl({value: 'Search', disabled: false}), search_multiple_allowed: new UntypedFormControl(false), diff --git a/client/src/app/instance/components/instance-navbar.component.html b/client/src/app/instance/components/instance-navbar.component.html index aa363e918416c11f084d6389b9c79af751c4c6e4..4ebd6d996f46395fa94ab96cf19e86f652fba085 100644 --- a/client/src/app/instance/components/instance-navbar.component.html +++ b/client/src/app/instance/components/instance-navbar.component.html @@ -43,42 +43,44 @@ </li> </ul> <!-- sign in / sign out --> - <button *ngIf="authenticationEnabled && !isAuthenticated" - class="btn btn-outline-success my-2 my-sm-0" - id="button-sign-in" - (click)="login.emit()"> - Sign In / Register - </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.design_color }"> - <span class="fas fa-circle fa-2x"></span> - <span class="fas fa-user fa-stack-1x fa-inverse"></span> - </span> - - <span class="fas fa-chevron-down text-secondary"></span> + <ng-container *ngIf="instance.user_menu_enabled"> + <button *ngIf="authenticationEnabled && !isAuthenticated" + class="btn btn-outline-success my-2 my-sm-0" + id="button-sign-in" + (click)="login.emit()"> + Sign In / Register </button> - <ul id="basic-link-dropdown" *dropdownMenu class="dropdown-menu dropdown-menu-right dropdown-up" role="menu" aria-labelledby="basic-link"> - <li id="li-email" role="menuitem"> - <span class="dropdown-item font-italic">{{ userProfile.email }}</span> - </li> - <li class="divider dropdown-divider"></li> - <li role="menuitem"> - <a *ngIf="isAdmin()" 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> - </li> - <li class="divider dropdown-divider"></li> - <li role="menuitem"> - <a class="dropdown-item text-danger pointer" (click)="logout.emit()"> - <span class="fas fa-sign-out-alt fa-fw"></span> Sign Out - </a> - </li> - </ul> - </span> + <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.design_color }"> + <span class="fas fa-circle fa-2x"></span> + <span class="fas fa-user fa-stack-1x fa-inverse"></span> + </span> + + <span class="fas fa-chevron-down text-secondary"></span> + </button> + <ul id="basic-link-dropdown" *dropdownMenu class="dropdown-menu dropdown-menu-right dropdown-up" role="menu" aria-labelledby="basic-link"> + <li id="li-email" role="menuitem"> + <span class="dropdown-item font-italic">{{ userProfile.email }}</span> + </li> + <li class="divider dropdown-divider"></li> + <li role="menuitem"> + <a *ngIf="isAdmin()" 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> + </li> + <li class="divider dropdown-divider"></li> + <li role="menuitem"> + <a class="dropdown-item text-danger pointer" (click)="logout.emit()"> + <span class="fas fa-sign-out-alt fa-fw"></span> Sign Out + </a> + </li> + </ul> + </span> + </ng-container> </div> <!-- Navigation Mobile --> @@ -117,31 +119,33 @@ <span class="fa-solid fa-right-to-bracket fa-fw"></span> Back to portal </a> </li> - <li *ngIf="isAuthenticated || !authenticationEnabled" class="divider dropdown-divider"></li> - <li *ngIf="!authenticationEnabled" role="menuitem"> - <a class="dropdown-item pointer" routerLink="/admin"> - <span class="fas fa-tools"></span> Admin - </a> - </li> - <li *ngIf="isAuthenticated" role="menuitem"> - <a *ngIf="isAdmin()" 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> - </li> - <li *ngIf="authenticationEnabled" class="divider dropdown-divider"></li> - <li *ngIf="authenticationEnabled && !isAuthenticated" role="menuitem"> - <a class="dropdown-item pointer text-success" (click)="login.emit()"> - <span class="fas fa-sign-in-alt fa-fw"></span> Sign In / Register - </a> - </li> - <li *ngIf="isAuthenticated" role="menuitem"> - <a class="dropdown-item pointer text-danger" (click)="logout.emit()"> - <span class="fas fa-sign-out-alt fa-fw"></span> Sign Out - </a> - </li> + <ng-container *ngIf="instance.user_menu_enabled"> + <li *ngIf="isAuthenticated || !authenticationEnabled" class="divider dropdown-divider"></li> + <li *ngIf="!authenticationEnabled" role="menuitem"> + <a class="dropdown-item pointer" routerLink="/admin"> + <span class="fas fa-tools"></span> Admin + </a> + </li> + <li *ngIf="isAuthenticated" role="menuitem"> + <a *ngIf="isAdmin()" 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> + </li> + <li *ngIf="authenticationEnabled" class="divider dropdown-divider"></li> + <li *ngIf="authenticationEnabled && !isAuthenticated" role="menuitem"> + <a class="dropdown-item pointer text-success" (click)="login.emit()"> + <span class="fas fa-sign-in-alt fa-fw"></span> Sign In / Register + </a> + </li> + <li *ngIf="isAuthenticated" role="menuitem"> + <a class="dropdown-item pointer text-danger" (click)="logout.emit()"> + <span class="fas fa-sign-out-alt fa-fw"></span> Sign Out + </a> + </li> + </ng-container> </ul> </span> </nav> diff --git a/client/src/app/instance/instance.component.spec.ts b/client/src/app/instance/instance.component.spec.ts index f7ba23e2d5538073192f93849ff344893af00c69..d42a946602dd22cfb3bda516c06f0f3a7489b2b2 100644 --- a/client/src/app/instance/instance.component.spec.ts +++ b/client/src/app/instance/instance.component.spec.ts @@ -97,6 +97,7 @@ describe('[Instance] InstanceComponent', () => { family_color: '#212529', samp_enabled: true, back_to_portal: true, + user_menu_enabled: true, search_by_criteria_allowed: true, search_by_criteria_label: 'Search', search_multiple_allowed: true, 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 f50af2db65c5056211980a2d26935b4a482d2a8d..d75a70216454b2b90a4ab4f86f960fdc9aa11baf 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 @@ -70,6 +70,7 @@ describe('[Instance][Search][Component] ProgressBarComponent', () => { family_color: '#212529', samp_enabled: true, back_to_portal: true, + user_menu_enabled: true, search_by_criteria_allowed: true, search_by_criteria_label: 'Search', search_multiple_allowed: true, @@ -109,6 +110,7 @@ describe('[Instance][Search][Component] ProgressBarComponent', () => { family_color: '#212529', samp_enabled: true, back_to_portal: true, + user_menu_enabled: true, search_by_criteria_allowed: true, search_by_criteria_label: 'Search', search_multiple_allowed: true, 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 b95c1cc974e9aea4f97394ac668097c215bc8a26..2879c2003d7561639eae6bab4eccf8c51e7513ff 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 @@ -152,6 +152,7 @@ describe('[Instance][Store] SearchMultipleEffects', () => { family_color: '#212529', samp_enabled: true, back_to_portal: true, + user_menu_enabled: true, search_by_criteria_allowed: true, search_by_criteria_label: 'Search', search_multiple_allowed: true, @@ -234,6 +235,7 @@ describe('[Instance][Store] SearchMultipleEffects', () => { family_color: '#212529', samp_enabled: true, back_to_portal: true, + user_menu_enabled: true, search_by_criteria_allowed: true, search_by_criteria_label: 'Search', search_multiple_allowed: true, diff --git a/client/src/app/metamodel/models/instance.model.ts b/client/src/app/metamodel/models/instance.model.ts index a0ea62dbb3feee6bae220b8f2961ecb1d59b3430..88d7093808ff9931347cdeede2ac81d48361bc96 100644 --- a/client/src/app/metamodel/models/instance.model.ts +++ b/client/src/app/metamodel/models/instance.model.ts @@ -35,6 +35,7 @@ export interface Instance { family_color: string; samp_enabled: boolean; back_to_portal: boolean; + user_menu_enabled: boolean; search_by_criteria_allowed: boolean; search_by_criteria_label: string; search_multiple_allowed: boolean; diff --git a/client/src/test-data.ts b/client/src/test-data.ts index 3f4b0354836ec188e176cf475842094c68c1ea1a..2ee794d54f722c112bb46820759fca00b8ef7eae 100644 --- a/client/src/test-data.ts +++ b/client/src/test-data.ts @@ -67,6 +67,7 @@ export const INSTANCE_LIST: Instance[] = [ family_color: '#212529', samp_enabled: true, back_to_portal: true, + user_menu_enabled: true, search_by_criteria_allowed: false, search_by_criteria_label: 'Search', search_multiple_allowed: false, @@ -100,6 +101,7 @@ export const INSTANCE_LIST: Instance[] = [ family_color: '#212529', samp_enabled: true, back_to_portal: true, + user_menu_enabled: true, search_by_criteria_allowed: false, search_by_criteria_label: 'Search', search_multiple_allowed: false, @@ -135,6 +137,7 @@ export const INSTANCE: Instance = { family_color: '#212529', samp_enabled: true, back_to_portal: true, + user_menu_enabled: true, search_by_criteria_allowed: false, search_by_criteria_label: 'Search', search_multiple_allowed: false, diff --git a/docker-compose.yml b/docker-compose.yml index 4ef7a61bfbfbaf4a22a163ddcaad2290bedbcb07..dcb400ff7fbf5c27a53b0a72a4dde7da5d883dea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -35,7 +35,7 @@ services: SSO_AUTH_URL: "http://localhost:8180" SSO_REALM: "anis" SSO_CLIENT_ID: "anis-client" - TOKEN_ENABLED: 0 + TOKEN_ENABLED: 1 TOKEN_JWKS_URL: "http://keycloak:8180/realms/anis/protocol/openid-connect/certs" TOKEN_ADMIN_ROLES: anis_admin,superuser RMQ_HOST: rmq diff --git a/server/doctrine-proxy/__CG__AppEntityInstance.php b/server/doctrine-proxy/__CG__AppEntityInstance.php index d830aa783fffa0049ce473727d2cdc6efc3a9f01..4a88f09ac8c33c827e70775cfc54376f53ffa696 100644 --- a/server/doctrine-proxy/__CG__AppEntityInstance.php +++ b/server/doctrine-proxy/__CG__AppEntityInstance.php @@ -67,10 +67,10 @@ class Instance extends \App\Entity\Instance implements \Doctrine\ORM\Proxy\Proxy public function __sleep() { if ($this->__isInitialized__) { - return ['__isInitialized__', 'name', 'label', 'description', 'scientificManager', 'instrument', 'wavelengthDomain', 'display', 'dataPath', 'filesPath', 'public', 'portalLogo', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'familyBorderColor', 'familyHeaderBackgroundColor', 'familyTitleColor', 'familyTitleBold', 'familyColor', 'sampEnabled', 'backToPortal', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies']; + return ['__isInitialized__', 'name', 'label', 'description', 'scientificManager', 'instrument', 'wavelengthDomain', 'display', 'dataPath', 'filesPath', 'public', 'portalLogo', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'familyBorderColor', 'familyHeaderBackgroundColor', 'familyTitleColor', 'familyTitleBold', 'familyColor', 'sampEnabled', 'backToPortal', 'userMenuEnabled', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies']; } - return ['__isInitialized__', 'name', 'label', 'description', 'scientificManager', 'instrument', 'wavelengthDomain', 'display', 'dataPath', 'filesPath', 'public', 'portalLogo', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'familyBorderColor', 'familyHeaderBackgroundColor', 'familyTitleColor', 'familyTitleBold', 'familyColor', 'sampEnabled', 'backToPortal', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies']; + return ['__isInitialized__', 'name', 'label', 'description', 'scientificManager', 'instrument', 'wavelengthDomain', 'display', 'dataPath', 'filesPath', 'public', 'portalLogo', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'familyBorderColor', 'familyHeaderBackgroundColor', 'familyTitleColor', 'familyTitleBold', 'familyColor', 'sampEnabled', 'backToPortal', 'userMenuEnabled', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies']; } /** @@ -654,6 +654,28 @@ class Instance extends \App\Entity\Instance implements \Doctrine\ORM\Proxy\Proxy return parent::setBackToPortal($backToPortal); } + /** + * {@inheritDoc} + */ + public function getUserMenuEnabled() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getUserMenuEnabled', []); + + return parent::getUserMenuEnabled(); + } + + /** + * {@inheritDoc} + */ + public function setUserMenuEnabled($userMenuEnabled) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setUserMenuEnabled', [$userMenuEnabled]); + + return parent::setUserMenuEnabled($userMenuEnabled); + } + /** * {@inheritDoc} */ diff --git a/server/src/Action/InstanceAction.php b/server/src/Action/InstanceAction.php index dd4d14d747fce4f4254dab996d2b738497451d6c..269a4c5b7e3896e780a2df548e41af3e5a8c429f 100644 --- a/server/src/Action/InstanceAction.php +++ b/server/src/Action/InstanceAction.php @@ -85,6 +85,7 @@ final class InstanceAction extends AbstractAction 'family_color', 'samp_enabled', 'back_to_portal', + 'user_menu_enabled', 'search_by_criteria_allowed', 'search_by_criteria_label', 'search_multiple_allowed', @@ -147,6 +148,7 @@ final class InstanceAction extends AbstractAction $instance->setFamilyTitleBold($parsedBody['family_title_bold']); $instance->setFamilyColor($parsedBody['family_color']); $instance->setSampEnabled($parsedBody['samp_enabled']); + $instance->setUserMenuEnabled($parsedBody['user_menu_enabled']); $instance->setBackToPortal($parsedBody['back_to_portal']); $instance->setSearchByCriteriaAllowed($parsedBody['search_by_criteria_allowed']); $instance->setSearchByCriteriaLabel($parsedBody['search_by_criteria_label']); diff --git a/server/src/Action/InstanceListAction.php b/server/src/Action/InstanceListAction.php index 4ba09706a8289def8def1153ee812acf9c7d6c66..c1e94a2da765c2a2d9d44f47ba23f7d637fc52d8 100644 --- a/server/src/Action/InstanceListAction.php +++ b/server/src/Action/InstanceListAction.php @@ -85,6 +85,7 @@ final class InstanceListAction extends AbstractAction 'family_color', 'samp_enabled', 'back_to_portal', + 'user_menu_enabled', 'search_by_criteria_allowed', 'search_by_criteria_label', 'search_multiple_allowed', @@ -142,6 +143,7 @@ final class InstanceListAction extends AbstractAction $instance->setFamilyColor($parsedBody['family_color']); $instance->setSampEnabled($parsedBody['samp_enabled']); $instance->setBackToPortal($parsedBody['back_to_portal']); + $instance->setUserMenuEnabled($parsedBody['user_menu_enabled']); $instance->setSearchByCriteriaAllowed($parsedBody['search_by_criteria_allowed']); $instance->setSearchByCriteriaLabel($parsedBody['search_by_criteria_label']); $instance->setSearchMultipleAllowed($parsedBody['search_multiple_allowed']); diff --git a/server/src/Entity/Instance.php b/server/src/Entity/Instance.php index bed8205d2cc61168ec12b33cb911536fe03cdd90..e320d1e971fa59e11287673f480ee14295aa3fe8 100644 --- a/server/src/Entity/Instance.php +++ b/server/src/Entity/Instance.php @@ -178,6 +178,13 @@ class Instance implements \JsonSerializable */ protected $backToPortal; + /** + * @var bool + * + * @Column(type="boolean", name="user_menu_enabled", nullable=false, options={"default" : true}) + */ + protected $userMenuEnabled; + /** * @var bool * @@ -456,6 +463,16 @@ class Instance implements \JsonSerializable $this->backToPortal = $backToPortal; } + public function getUserMenuEnabled() + { + return $this->userMenuEnabled; + } + + public function setUserMenuEnabled($userMenuEnabled) + { + $this->userMenuEnabled = $userMenuEnabled; + } + public function getSearchByCriteriaAllowed() { return $this->searchByCriteriaAllowed; @@ -565,6 +582,7 @@ class Instance implements \JsonSerializable 'family_color' => $this->getFamilyColor(), 'samp_enabled' => $this->getSampEnabled(), 'back_to_portal' => $this->getBackToPortal(), + 'user_menu_enabled' => $this->getUserMenuEnabled(), 'search_by_criteria_allowed' => $this->getSearchByCriteriaAllowed(), 'search_by_criteria_label' => $this->getSearchByCriteriaLabel(), 'search_multiple_allowed' => $this->getSearchMultipleAllowed(), diff --git a/server/tests/Action/InstanceActionTest.php b/server/tests/Action/InstanceActionTest.php index 577c10a3c4f7c99b653f83ffd4986397f221dc99..1f4fececdfad5e9e8a66879ac25acc13bf39cff4 100644 --- a/server/tests/Action/InstanceActionTest.php +++ b/server/tests/Action/InstanceActionTest.php @@ -101,6 +101,7 @@ final class InstanceActionTest extends TestCase 'home_component_config' => '{}', 'samp_enabled' => true, 'back_to_portal' => true, + 'user_menu_enabled' => true, 'search_by_criteria_allowed' => true, 'search_by_criteria_label' => 'Search', 'search_multiple_allowed' => false, diff --git a/server/tests/Action/InstanceListActionTest.php b/server/tests/Action/InstanceListActionTest.php index 7fad3b7887e785eb3cc24eee8f2b183b4fdbc45e..f631169924673b8827cb3572f489c85db039abe0 100644 --- a/server/tests/Action/InstanceListActionTest.php +++ b/server/tests/Action/InstanceListActionTest.php @@ -85,6 +85,7 @@ final class InstanceListActionTest extends TestCase 'home_component_config' => '{}', 'samp_enabled' => true, 'back_to_portal' => true, + 'user_menu_enabled' => true, 'search_by_criteria_allowed' => true, 'search_by_criteria_label' => 'Search', 'search_multiple_allowed' => false,