From 8d9d3dbc45c5df0c3c6affea461f0b759e350ad8 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Fri, 28 Sep 2018 12:32:36 +0300 Subject: [PATCH] [ACA-543] Disable Share feature based on repository property (#658) * add visibility type to navigation schema * repository data model * add repository state * add repository state * add repository evaluator * allot navigation elements to called again * AppRuleContext extends * repository status resolver * map repository evaluator * reevaluate navigation elements * generic route evaluator * add route guard on Share * evaluate guard based on data property * changed old imports * add Action suffix * set state false by default * tree shakable services to simplify rebase * fix rebase * isQuickShareEnabled initial null state * repository store effects * repository store actions * refactored * refactored --- extension.schema.json | 24 ++++-- src/app/app.routes.ts | 11 ++- .../components/sidenav/sidenav.component.ts | 40 +++++++++- src/app/extensions/app.interface.ts | 31 ++++++++ src/app/extensions/core.extensions.module.ts | 5 +- .../evaluators/repository.evaluators.ts | 34 ++++++++ src/app/extensions/extension.service.ts | 15 ++-- src/app/guards/shared.guard.ts | 79 +++++++++++++++++++ .../services/repository-status.resolver.ts | 70 ++++++++++++++++ src/app/store/actions.ts | 1 + src/app/store/actions/repository.actions.ts | 38 +++++++++ src/app/store/app-store.module.ts | 6 +- src/app/store/effects.ts | 1 + src/app/store/effects/repository.effects.ts | 67 ++++++++++++++++ src/app/store/reducers/app.reducer.ts | 16 ++++ src/app/store/selectors/app.selectors.ts | 10 ++- src/app/store/states.ts | 1 + src/app/store/states/app.state.ts | 7 +- src/app/store/states/repository.state.ts | 31 ++++++++ src/assets/app.extensions.json | 45 ++++++++--- src/assets/extension.schema.json | 24 ++++-- 21 files changed, 517 insertions(+), 39 deletions(-) create mode 100644 src/app/extensions/app.interface.ts create mode 100644 src/app/extensions/evaluators/repository.evaluators.ts create mode 100644 src/app/guards/shared.guard.ts create mode 100644 src/app/services/repository-status.resolver.ts create mode 100644 src/app/store/actions/repository.actions.ts create mode 100644 src/app/store/effects/repository.effects.ts create mode 100644 src/app/store/states/repository.state.ts diff --git a/extension.schema.json b/extension.schema.json index e801b081f..b7bc80d95 100644 --- a/extension.schema.json +++ b/extension.schema.json @@ -199,9 +199,15 @@ "description": "Element order", "type": "number" }, - "disabled": { - "description": "Toggles the disabled state", - "type": "boolean" + "rules": { + "description": "Element rules", + "type": "object", + "properties": { + "visible": { + "description": "Rule to evaluate the visibility state", + "type": "string" + } + } } } }, @@ -223,9 +229,15 @@ "description": "Group order", "type": "number" }, - "disabled": { - "description": "Toggles the disabled state", - "type": "boolean" + "rules": { + "description": "Element rules", + "type": "object", + "properties": { + "visible": { + "description": "Rule to evaluate the visibility state", + "type": "string" + } + } } } }, diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 5542ae1a3..0e754dcac 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -30,8 +30,10 @@ import { LibrariesComponent } from './components/libraries/libraries.component'; import { GenericErrorComponent } from './components/common/generic-error/generic-error.component'; import { SearchResultsComponent } from './components/search/search-results/search-results.component'; import { ProfileResolver } from './services/profile.resolver'; +import { RepositoryStatusResolver } from './services/repository-status.resolver'; import { LoginComponent } from './components/login/login.component'; import { AppAuthGuard } from './guards/auth.guard'; +import { AppSharedRuleGuard } from './guards/shared.guard'; export const APP_ROUTES: Routes = [ { @@ -54,7 +56,10 @@ export const APP_ROUTES: Routes = [ { path: '', component: LayoutComponent, - resolve: { profile: ProfileResolver }, + resolve: { + profile: ProfileResolver, + repository: RepositoryStatusResolver + }, children: [ { path: '', @@ -196,7 +201,9 @@ export const APP_ROUTES: Routes = [ navigateSource: 'shared' } } - ] + ], + canActivateChild: [AppSharedRuleGuard], + canActivate: [AppSharedRuleGuard] }, { path: 'trashcan', diff --git a/src/app/components/sidenav/sidenav.component.ts b/src/app/components/sidenav/sidenav.component.ts index f56cdc2b5..5cc26bfb2 100644 --- a/src/app/components/sidenav/sidenav.component.ts +++ b/src/app/components/sidenav/sidenav.component.ts @@ -23,9 +23,20 @@ * along with Alfresco. If not, see . */ -import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { + Component, + Input, + OnInit, + ViewEncapsulation, + OnDestroy +} from '@angular/core'; import { AppExtensionService } from '../../extensions/extension.service'; import { NavBarGroupRef } from '@alfresco/adf-extensions'; +import { Store } from '@ngrx/store'; +import { AppStore } from '../../store/states'; +import { ruleContext } from '../../store/selectors/app.selectors'; +import { Subject } from 'rxjs'; +import { takeUntil, distinctUntilChanged, map } from 'rxjs/operators'; @Component({ selector: 'app-sidenav', @@ -34,19 +45,40 @@ import { NavBarGroupRef } from '@alfresco/adf-extensions'; encapsulation: ViewEncapsulation.None, host: { class: 'app-sidenav' } }) -export class SidenavComponent implements OnInit { +export class SidenavComponent implements OnInit, OnDestroy { + private onDestroy$: Subject = new Subject(); + @Input() showLabel: boolean; groups: Array = []; - constructor(private extensions: AppExtensionService) {} + constructor( + private store: Store, + private extensions: AppExtensionService + ) {} ngOnInit() { - this.groups = this.extensions.getNavigationGroups(); + this.store + .select(ruleContext) + .pipe( + takeUntil(this.onDestroy$), + map(rules => rules.repository), + distinctUntilChanged() + ) + .subscribe(() => { + this.groups = this.extensions.getApplicationNavigation( + this.extensions.navbar + ); + }); } trackById(index: number, obj: { id: string }) { return obj.id; } + + ngOnDestroy() { + this.onDestroy$.next(true); + this.onDestroy$.complete(); + } } diff --git a/src/app/extensions/app.interface.ts b/src/app/extensions/app.interface.ts new file mode 100644 index 000000000..5d60f4773 --- /dev/null +++ b/src/app/extensions/app.interface.ts @@ -0,0 +1,31 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { RuleContext } from '@alfresco/adf-extensions'; +import { RepositoryState } from '../store/states'; + +export interface AppRuleContext extends RuleContext { + repository: RepositoryState; +} diff --git a/src/app/extensions/core.extensions.module.ts b/src/app/extensions/core.extensions.module.ts index 9248122fb..76e01d4b1 100644 --- a/src/app/extensions/core.extensions.module.ts +++ b/src/app/extensions/core.extensions.module.ts @@ -27,6 +27,7 @@ import { CoreModule } from '@alfresco/adf-core'; import { CommonModule } from '@angular/common'; import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core'; import { LayoutComponent } from '../components/layout/layout.component'; +import * as repository from './evaluators/repository.evaluators'; import * as app from './evaluators/app.evaluators'; import * as nav from './evaluators/navigation.evaluators'; import { AppExtensionService } from './extension.service'; @@ -109,7 +110,9 @@ export class CoreExtensionsModule { 'app.navigation.isNotRecentFiles': nav.isNotRecentFiles, 'app.navigation.isSearchResults': nav.isSearchResults, 'app.navigation.isNotSearchResults': nav.isNotSearchResults, - 'app.navigation.isPreview': nav.isPreview + 'app.navigation.isPreview': nav.isPreview, + + 'repository.isQuickShareEnabled': repository.hasQuickShareEnabled }); } } diff --git a/src/app/extensions/evaluators/repository.evaluators.ts b/src/app/extensions/evaluators/repository.evaluators.ts new file mode 100644 index 000000000..4799146ab --- /dev/null +++ b/src/app/extensions/evaluators/repository.evaluators.ts @@ -0,0 +1,34 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { RuleParameter } from '@alfresco/adf-extensions'; +import { AppRuleContext } from '../app.interface'; + +export function hasQuickShareEnabled( + context: AppRuleContext, + ...args: RuleParameter[] +): boolean { + return context.repository.isQuickShareEnabled; +} diff --git a/src/app/extensions/extension.service.ts b/src/app/extensions/extension.service.ts index d83fe79ba..daa7865a8 100644 --- a/src/app/extensions/extension.service.ts +++ b/src/app/extensions/extension.service.ts @@ -26,7 +26,7 @@ import { Injectable, Type } from '@angular/core'; import { Store } from '@ngrx/store'; import { Route } from '@angular/router'; -import { AppStore } from '../store/states'; +import { AppStore, RepositoryState } from '../store/states'; import { ruleContext } from '../store/selectors/app.selectors'; import { NodePermissionService } from '../services/node-permission.service'; import { ProfileResolver } from '../services/profile.resolver'; @@ -75,6 +75,7 @@ export class AppExtensionService implements RuleContext { selection: SelectionState; navigation: NavigationState; profile: ProfileState; + repository: RepositoryState; constructor( private store: Store, @@ -87,6 +88,7 @@ export class AppExtensionService implements RuleContext { this.selection = result.selection; this.navigation = result.navigation; this.profile = result.profile; + this.repository = result.repository; }); } @@ -141,16 +143,17 @@ export class AppExtensionService implements RuleContext { } protected loadNavBar(config: ExtensionConfig): Array { - const elements = this.loader.getElements( - config, - 'features.navbar' - ); + return this.loader.getElements(config, 'features.navbar'); + } + getApplicationNavigation(elements) { return elements.map(group => { return { ...group, items: (group.items || []) - .filter(item => !item.disabled) + .filter(item => { + return this.filterByRules(item); + }) .sort(sortByOrder) .map(item => { const routeRef = this.extensions.getRouteById(item.route); diff --git a/src/app/guards/shared.guard.ts b/src/app/guards/shared.guard.ts new file mode 100644 index 000000000..5ff6f0943 --- /dev/null +++ b/src/app/guards/shared.guard.ts @@ -0,0 +1,79 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { Injectable } from '@angular/core'; +import { CanActivate } from '@angular/router'; +import { Observable } from 'rxjs'; +import { ActivatedRouteSnapshot } from '@angular/router'; +import { tap, map, filter, take } from 'rxjs/operators'; +import { Router } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { AppStore } from '../store/states/app.state'; +import { GetRepositoryStatusAction } from '../store/actions'; +import { repositoryStatus } from '../store/selectors/app.selectors'; + +@Injectable({ + providedIn: 'root' +}) +export class AppSharedRuleGuard implements CanActivate { + constructor(private store: Store, private router: Router) {} + + canActivate( + route: ActivatedRouteSnapshot + ): Observable | Promise | boolean { + this.init(); + return this.wait(); + } + + canActivateChild( + route: ActivatedRouteSnapshot + ): Observable | Promise | boolean { + return this.canActivate(route); + } + + wait(): Observable { + return this.store.select(repositoryStatus).pipe( + map(state => state.isQuickShareEnabled), + filter(value => value !== null), + tap(value => { + if (value === false) { + this.router.navigate(['']); + } + }), + take(1) + ); + } + + init() { + this.store + .select(repositoryStatus) + .pipe(take(1)) + .subscribe(state => { + if (state.isQuickShareEnabled === null) { + this.store.dispatch(new GetRepositoryStatusAction()); + } + }); + } +} diff --git a/src/app/services/repository-status.resolver.ts b/src/app/services/repository-status.resolver.ts new file mode 100644 index 000000000..107f3ad3a --- /dev/null +++ b/src/app/services/repository-status.resolver.ts @@ -0,0 +1,70 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { Store } from '@ngrx/store'; +import { Injectable } from '@angular/core'; +import { Resolve } from '@angular/router'; +import { Observable } from 'rxjs'; +import { AppStore } from '../store/states/app.state'; +import { RepositoryState } from '../store/states'; +import { repositoryStatus } from '../store/selectors/app.selectors'; +import { filter, take } from 'rxjs/operators'; +import { GetRepositoryStatusAction } from '../store/actions'; + +@Injectable({ + providedIn: 'root' +}) +export class RepositoryStatusResolver implements Resolve { + constructor(private store: Store) {} + + resolve(): Observable { + this.init(); + return this.wait(); + } + + wait(): Observable { + return this.store.select(repositoryStatus).pipe( + filter(state => this.hasValuesSet(state)), + take(1) + ); + } + + init() { + this.store + .select(repositoryStatus) + .pipe(take(1)) + .subscribe(state => { + if (!this.hasValuesSet(state)) { + this.store.dispatch(new GetRepositoryStatusAction()); + } + }); + } + + private hasValuesSet(object): boolean { + return Object.keys(object) + .map(key => object[key]) + .every(value => value !== null); + } +} diff --git a/src/app/store/actions.ts b/src/app/store/actions.ts index 3116ec10e..54c344865 100644 --- a/src/app/store/actions.ts +++ b/src/app/store/actions.ts @@ -33,3 +33,4 @@ export * from './actions/search.actions'; export * from './actions/library.actions'; export * from './actions/upload.actions'; export * from './actions/modals.actions'; +export * from './actions/repository.actions'; diff --git a/src/app/store/actions/repository.actions.ts b/src/app/store/actions/repository.actions.ts new file mode 100644 index 000000000..bdff9e133 --- /dev/null +++ b/src/app/store/actions/repository.actions.ts @@ -0,0 +1,38 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { Action } from '@ngrx/store'; + +export const SET_REPOSITORY_STATUS = 'SET_REPOSITORY_STATUS'; +export const GET_REPOSITORY_STATUS = 'GET_REPOSITORY_STATUS'; + +export class SetRepositoryStatusAction implements Action { + readonly type = SET_REPOSITORY_STATUS; + constructor(public payload: any) {} +} + +export class GetRepositoryStatusAction implements Action { + readonly type = GET_REPOSITORY_STATUS; +} diff --git a/src/app/store/app-store.module.ts b/src/app/store/app-store.module.ts index f2eed74e9..e000759a5 100644 --- a/src/app/store/app-store.module.ts +++ b/src/app/store/app-store.module.ts @@ -42,7 +42,8 @@ import { LibraryEffects, UploadEffects, FavoriteEffects, - ModalsEffects + ModalsEffects, + RepositoryEffects } from './effects'; @NgModule({ @@ -60,7 +61,8 @@ import { LibraryEffects, UploadEffects, FavoriteEffects, - ModalsEffects + ModalsEffects, + RepositoryEffects ]), !environment.production ? StoreDevtoolsModule.instrument({ maxAge: 25 }) diff --git a/src/app/store/effects.ts b/src/app/store/effects.ts index ce4fa76b5..05a64d07f 100644 --- a/src/app/store/effects.ts +++ b/src/app/store/effects.ts @@ -34,3 +34,4 @@ export * from './effects/search.effects'; export * from './effects/library.effects'; export * from './effects/upload.effects'; export * from './effects/modals.effects'; +export * from './effects/repository.effects'; diff --git a/src/app/store/effects/repository.effects.ts b/src/app/store/effects/repository.effects.ts new file mode 100644 index 000000000..64c3d7c82 --- /dev/null +++ b/src/app/store/effects/repository.effects.ts @@ -0,0 +1,67 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { Effect, Actions, ofType } from '@ngrx/effects'; +import { Injectable } from '@angular/core'; +import { DiscoveryEntry } from 'alfresco-js-api'; +import { map, switchMap, catchError } from 'rxjs/operators'; +import { of } from 'rxjs'; +import { + GET_REPOSITORY_STATUS, + GetRepositoryStatusAction +} from '../actions/repository.actions'; +import { Router } from '@angular/router'; +import { ContentApiService } from '../../services/content-api.service'; +import { SetRepositoryStatusAction } from '../actions'; + +@Injectable() +export class RepositoryEffects { + constructor( + private actions$: Actions, + private router: Router, + private contentApi: ContentApiService + ) {} + + @Effect() + getRepositoryStatus$ = this.actions$.pipe( + ofType(GET_REPOSITORY_STATUS), + switchMap(() => { + return this.contentApi.getRepositoryInformation().pipe( + map( + (response: DiscoveryEntry) => + new SetRepositoryStatusAction(response.entry.repository.status) + ), + catchError(error => { + this.redirectToLogin(); + return of(error); + }) + ); + }) + ); + + private redirectToLogin() { + this.router.navigate(['login']); + } +} diff --git a/src/app/store/reducers/app.reducer.ts b/src/app/store/reducers/app.reducer.ts index 4536bc273..219547926 100644 --- a/src/app/store/reducers/app.reducer.ts +++ b/src/app/store/reducers/app.reducer.ts @@ -30,6 +30,8 @@ import { SetSelectedNodesAction, SET_USER_PROFILE, SetUserProfileAction, + SET_REPOSITORY_STATUS, + SetRepositoryStatusAction, SET_LANGUAGE_PICKER, SetLanguagePickerAction, SET_CURRENT_FOLDER, @@ -79,6 +81,11 @@ export function appReducer( action )); break; + case SET_REPOSITORY_STATUS: + newState = updateRepositoryStatus(state, ( + action + )); + break; default: newState = Object.assign({}, state); } @@ -207,3 +214,12 @@ function updateSelectedNodes( }; return newState; } + +function updateRepositoryStatus( + state: AppState, + action: SetRepositoryStatusAction +) { + const newState = Object.assign({}, state); + newState.repository = action.payload; + return newState; +} diff --git a/src/app/store/selectors/app.selectors.ts b/src/app/store/selectors/app.selectors.ts index 77ad71dd6..cbf21c6d4 100644 --- a/src/app/store/selectors/app.selectors.ts +++ b/src/app/store/selectors/app.selectors.ts @@ -59,16 +59,22 @@ export const documentDisplayMode = createSelector( selectApp, state => state.documentDisplayMode ); +export const repositoryStatus = createSelector( + selectApp, + state => state.repository +); export const ruleContext = createSelector( appSelection, appNavigation, selectUser, - (selection, navigation, profile) => { + repositoryStatus, + (selection, navigation, profile, repository) => { return { selection, navigation, - profile + profile, + repository }; } ); diff --git a/src/app/store/states.ts b/src/app/store/states.ts index ccca96164..393a3b17c 100644 --- a/src/app/store/states.ts +++ b/src/app/store/states.ts @@ -24,3 +24,4 @@ */ export * from './states/app.state'; +export * from './states/repository.state'; diff --git a/src/app/store/states/app.state.ts b/src/app/store/states/app.state.ts index 59f8d6d7d..a46a7b679 100644 --- a/src/app/store/states/app.state.ts +++ b/src/app/store/states/app.state.ts @@ -28,6 +28,7 @@ import { ProfileState, NavigationState } from '@alfresco/adf-extensions'; +import { RepositoryState } from '../states'; export interface AppState { appName: string; @@ -40,6 +41,7 @@ export interface AppState { navigation: NavigationState; infoDrawerOpened: boolean; documentDisplayMode: string; + repository: RepositoryState; } export const INITIAL_APP_STATE: AppState = { @@ -64,7 +66,10 @@ export const INITIAL_APP_STATE: AppState = { currentFolder: null }, infoDrawerOpened: false, - documentDisplayMode: 'list' + documentDisplayMode: 'list', + repository: { + isQuickShareEnabled: null + } }; export interface AppStore { diff --git a/src/app/store/states/repository.state.ts b/src/app/store/states/repository.state.ts new file mode 100644 index 000000000..1331f179f --- /dev/null +++ b/src/app/store/states/repository.state.ts @@ -0,0 +1,31 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +export interface RepositoryState { + isAuditEnabled?: boolean; + isQuickShareEnabled?: boolean; + isReadOnly?: boolean; + isThumbnailGenerationEnabled?: boolean; +} diff --git a/src/assets/app.extensions.json b/src/assets/app.extensions.json index 1b581c7ed..5a85ece58 100644 --- a/src/assets/app.extensions.json +++ b/src/assets/app.extensions.json @@ -20,18 +20,36 @@ "type": "rule", "value": "core.some", "parameters": [ - { "type": "rule", "value": "app.selection.canAddFavorite" }, - { "type": "rule", "value": "app.selection.canRemoveFavorite" } + { + "type": "rule", + "value": "app.selection.canAddFavorite" + }, + { + "type": "rule", + "value": "app.selection.canRemoveFavorite" + } ] }, { "type": "rule", "value": "core.some", "parameters": [ - { "type": "rule", "value": "app.navigation.isRecentFiles" }, - { "type": "rule", "value": "app.navigation.isSharedFiles" }, - { "type": "rule", "value": "app.navigation.isSearchResults" }, - { "type": "rule", "value": "app.navigation.isFavorites" } + { + "type": "rule", + "value": "app.navigation.isRecentFiles" + }, + { + "type": "rule", + "value": "app.navigation.isSharedFiles" + }, + { + "type": "rule", + "value": "app.navigation.isSearchResults" + }, + { + "type": "rule", + "value": "app.navigation.isFavorites" + } ] } ] @@ -43,7 +61,10 @@ { "type": "rule", "value": "app.selection.canAddFavorite" }, { "type": "rule", "value": "app.navigation.isNotRecentFiles" }, { "type": "rule", "value": "app.navigation.isNotSharedFiles" }, - { "type": "rule", "value": "app.navigation.isNotSearchResults" }, + { + "type": "rule", + "value": "app.navigation.isNotSearchResults" + }, { "type": "rule", "value": "app.navigation.isNotFavorites" } ] }, @@ -54,7 +75,10 @@ { "type": "rule", "value": "app.selection.canRemoveFavorite" }, { "type": "rule", "value": "app.navigation.isNotRecentFiles" }, { "type": "rule", "value": "app.navigation.isNotSharedFiles" }, - { "type": "rule", "value": "app.navigation.isNotSearchResults" }, + { + "type": "rule", + "value": "app.navigation.isNotSearchResults" + }, { "type": "rule", "value": "app.navigation.isNotFavorites" } ] }, @@ -227,7 +251,10 @@ "icon": "people", "title": "APP.BROWSE.SHARED.SIDENAV_LINK.LABEL", "description": "APP.BROWSE.SHARED.SIDENAV_LINK.TOOLTIP", - "route": "shared" + "route": "shared", + "rules": { + "visible": "repository.isQuickShareEnabled" + } }, { "id": "app.navbar.recentFiles", diff --git a/src/assets/extension.schema.json b/src/assets/extension.schema.json index a8a7011a3..88f15bd9d 100644 --- a/src/assets/extension.schema.json +++ b/src/assets/extension.schema.json @@ -199,9 +199,15 @@ "description": "Element order", "type": "number" }, - "disabled": { - "description": "Toggles the disabled state", - "type": "boolean" + "rules": { + "description": "Element rules", + "type": "object", + "properties": { + "visible": { + "description": "Rule to evaluate the visibility state", + "type": "string" + } + } } } }, @@ -223,9 +229,15 @@ "description": "Group order", "type": "number" }, - "disabled": { - "description": "Toggles the disabled state", - "type": "boolean" + "rules": { + "description": "Element rules", + "type": "object", + "properties": { + "visible": { + "description": "Rule to evaluate the visibility state", + "type": "string" + } + } } } },