[ACA-1115] Quick Share (#492)

* share file

* fix

* fix test dependency

* experimental guard
This commit is contained in:
Cilibiu Bogdan
2018-07-06 12:42:13 +03:00
committed by Denys Vuika
parent e5bc3bb755
commit 3e123bee62
21 changed files with 175 additions and 6 deletions

View File

@@ -11,7 +11,8 @@
"experimental": {
"libraries": false,
"comments": false,
"cardview": false
"cardview": false,
"share": false
},
"headerColor": "#2196F3",
"languagePicker": false,

View File

@@ -30,7 +30,13 @@ import {
AuthenticationService, AlfrescoApiService } from '@alfresco/adf-core';
import { Store } from '@ngrx/store';
import { AppStore } from './store/states/app.state';
import { SetHeaderColorAction, SetAppNameAction, SetLogoPathAction, SetLanguagePickerAction } from './store/actions';
import {
SetHeaderColorAction,
SetAppNameAction,
SetLogoPathAction,
SetLanguagePickerAction,
SetSharedUrlAction
} from './store/actions';
@Component({
selector: 'app-root',
@@ -94,5 +100,8 @@ export class AppComponent implements OnInit {
}
const languagePicker = this.config.get<boolean>('languagePicker');
this.store.dispatch(new SetLanguagePickerAction(languagePicker));
const sharedPreviewUrl = this.config.get<string>('ecmHost') + '/#/preview/s/';
this.store.dispatch(new SetSharedUrlAction(sharedPreviewUrl));
}
}

View File

@@ -53,6 +53,7 @@ import { SidenavComponent } from './components/sidenav/sidenav.component';
import { AboutComponent } from './components/about/about.component';
import { LocationLinkComponent } from './components/location-link/location-link.component';
import { CustomDlRowComponent } from './components/custom-dl-row/custom-dl-row.component';
import { SharedLinkViewComponent } from './components/shared-link-view/shared-link-view.component';
import { NodeCopyDirective } from './common/directives/node-copy.directive';
import { NodeDeleteDirective } from './common/directives/node-delete.directive';
import { NodeMoveDirective } from './common/directives/node-move.directive';
@@ -69,6 +70,7 @@ import { SearchComponent } from './components/search/search.component';
import { SettingsComponent } from './components/settings/settings.component';
import { PageTitleService as AcaPageTitleService } from './common/services/page-title.service';
import { ProfileResolver } from './common/services/profile.resolver';
import { ExperimentalGuard } from './common/services/experimental-guard.service';
import { InfoDrawerComponent } from './components/info-drawer/info-drawer.component';
import { EditFolderDirective } from './directives/edit-folder.directive';
@@ -128,6 +130,7 @@ import { ContentApiService } from './services/content-api.service';
SearchComponent,
SettingsComponent,
InfoDrawerComponent,
SharedLinkViewComponent,
EditFolderDirective,
CreateFolderDirective,
DownloadNodesDirective,
@@ -151,6 +154,7 @@ import { ContentApiService } from './services/content-api.service';
NodeActionsService,
NodePermissionService,
ProfileResolver,
ExperimentalGuard,
ContentApiService
],
entryComponents: [

View File

@@ -25,6 +25,7 @@
import { Routes } from '@angular/router';
import { AuthGuardEcm } from '@alfresco/adf-core';
import { SharedLinkViewComponent } from './components/shared-link-view/shared-link-view.component';
import { LayoutComponent } from './components/layout/layout.component';
@@ -43,6 +44,7 @@ import { SearchComponent } from './components/search/search.component';
import { SettingsComponent } from './components/settings/settings.component';
import { ProfileResolver } from './common/services/profile.resolver';
import { ExperimentalGuard } from './common/services/experimental-guard.service';
export const APP_ROUTES: Routes = [
{
@@ -59,6 +61,15 @@ export const APP_ROUTES: Routes = [
title: 'Settings'
}
},
{
path: 'preview/s/:id',
component: SharedLinkViewComponent,
canActivate: [ ExperimentalGuard ],
data: {
ifExperimentalKey: 'share',
title: 'APP.PREVIEW.TITLE',
}
},
{
path: '',
component: LayoutComponent,

View File

@@ -0,0 +1,20 @@
import { CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { Injectable } from '@angular/core';
import { AppConfigService } from '@alfresco/adf-core';
import { environment } from '../../../environments/environment';
@Injectable()
export class ExperimentalGuard implements CanActivate {
constructor(private config: AppConfigService) {}
canActivate(route: ActivatedRouteSnapshot) {
const key = `experimental.${route.data.ifExperimentalKey}`;
const value = this.config.get(key);
if (!environment.production) {
return value === true || value === 'true';
}
return false;
}
}

View File

@@ -44,6 +44,17 @@
<mat-icon>info_outline</mat-icon>
</button>
<ng-container *ifExperimental="'share'">
<button mat-icon-button
color="primary"
title="{{ 'APP.ACTIONS.SHARE' | translate }}"
*ngIf="selection.file"
[baseShareUrl]="sharedPreviewUrl$ | async"
[adf-share]="selection.file">
<mat-icon>share</mat-icon>
</button>
</ng-container>
<button
color="primary"
mat-icon-button

View File

@@ -46,6 +46,17 @@
<mat-icon>info_outline</mat-icon>
</button>
<ng-container *ifExperimental="'share'">
<button mat-icon-button
color="primary"
title="{{ 'APP.ACTIONS.SHARE' | translate }}"
*ngIf="selection.file"
[baseShareUrl]="sharedPreviewUrl$ | async"
[adf-share]="selection.file">
<mat-icon>share</mat-icon>
</button>
</ng-container>
<button
color="primary"
mat-icon-button

View File

@@ -31,9 +31,10 @@ import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api';
import { takeUntil } from 'rxjs/operators';
import { Subject, Subscription } from 'rxjs/Rx';
import { SnackbarErrorAction, ViewNodeAction, SetSelectedNodesAction } from '../store/actions';
import { appSelection } from '../store/selectors/app.selectors';
import { appSelection, sharedUrl } from '../store/selectors/app.selectors';
import { AppStore } from '../store/states/app.state';
import { SelectionState } from '../store/states/selection.state';
import { Observable } from 'rxjs/Rx';
export abstract class PageComponent implements OnInit, OnDestroy {
@@ -47,6 +48,7 @@ export abstract class PageComponent implements OnInit, OnDestroy {
node: MinimalNodeEntryEntity;
selection: SelectionState;
displayMode = DisplayMode.List;
sharedPreviewUrl$: Observable<string>;
protected subscriptions: Subscription[] = [];
@@ -57,6 +59,8 @@ export abstract class PageComponent implements OnInit, OnDestroy {
constructor(protected store: Store<AppStore>) {}
ngOnInit() {
this.sharedPreviewUrl$ = this.store.select(sharedUrl);
this.store
.select(appSelection)
.pipe(takeUntil(this.onDestroy$))

View File

@@ -46,6 +46,16 @@
<span>{{ 'APP.ACTIONS.FAVORITE' | translate }}</span>
</button>
<ng-container *ifExperimental="'share'">
<button mat-menu-item
color="primary"
[baseShareUrl]="sharedPreviewUrl$ | async"
[adf-share]="selectedEntities[0]">
<mat-icon>share</mat-icon>
<span>{{ 'APP.ACTIONS.SHARE' | translate }}</span>
</button>
</ng-container>
<button
mat-menu-item
[acaCopyNode]="selectedEntities">

View File

@@ -30,6 +30,7 @@ import { UserPreferencesService, AppConfigPipe, NodeFavoriteDirective } from '@a
import { PreviewComponent } from './preview.component';
import { Observable } from 'rxjs/Rx';
import { EffectsModule } from '@ngrx/effects';
import { ExperimentalDirective } from '../../directives/experimental.directive';
import { NodeEffects } from '../../store/effects/node.effects';
import { AppTestingModule } from '../../testing/app-testing.module';
import { ContentApiService } from '../../services/content-api.service';
@@ -52,7 +53,8 @@ describe('PreviewComponent', () => {
declarations: [
AppConfigPipe,
PreviewComponent,
NodeFavoriteDirective
NodeFavoriteDirective,
ExperimentalDirective
],
schemas: [ NO_ERRORS_SCHEMA ]
});

View File

@@ -35,6 +35,16 @@
<mat-icon>info_outline</mat-icon>
</button>
<ng-container *ifExperimental="'share'">
<button mat-icon-button
title="{{ 'APP.ACTIONS.SHARE' | translate }}"
*ngIf="selection.file"
[baseShareUrl]="sharedPreviewUrl$ | async"
[adf-share]="selection.file">
<mat-icon>share</mat-icon>
</button>
</ng-container>
<button
color="primary"
mat-icon-button

View File

@@ -80,5 +80,13 @@
Cardview
</mat-checkbox>
</div>
<div>
<mat-checkbox
[(ngModel)]="share"
(change)="onChangeShareFeature($event)">
Share
</mat-checkbox>
</div>
</mat-expansion-panel>
</mat-accordion>

View File

@@ -51,6 +51,7 @@ export class SettingsComponent implements OnInit {
libraries: boolean;
comments: boolean;
cardview: boolean;
share: boolean;
constructor(
private store: Store<AppStore>,
@@ -82,6 +83,9 @@ export class SettingsComponent implements OnInit {
const cardview = this.appConfig.get('experimental.cardview');
this.cardview = (cardview === true || cardview === 'true');
const share = this.appConfig.get('experimental.share');
this.share = (share === true || share === 'true');
}
apply(model: any, isValid: boolean) {
@@ -113,4 +117,8 @@ export class SettingsComponent implements OnInit {
onChangeCardviewFeature(event: MatCheckboxChange) {
this.storage.setItem('experimental.cardview', event.checked.toString());
}
onChangeShareFeature(event: MatCheckboxChange) {
this.storage.setItem('experimental.share', event.checked.toString());
}
}

View File

@@ -0,0 +1,6 @@
<ng-container *ngIf="sharedLinkId">
<adf-viewer
[sharedLinkId]="sharedLinkId"
[allowGoBack]="false">
</adf-viewer>
</ng-container>

View File

@@ -0,0 +1,4 @@
.app-shared-link-view {
width: 100%;
height: 100%;
}

View File

@@ -0,0 +1,24 @@
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-shared-link-view',
templateUrl: 'shared-link-view.component.html',
styleUrls: [ 'shared-link-view.component.scss' ],
encapsulation: ViewEncapsulation.None,
// tslint:disable-next-line:use-host-property-decorator
host: { 'class': 'app-shared-link-view' }
})
export class SharedLinkViewComponent implements OnInit {
sharedLinkId: string = null;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route.params.subscribe(params => {
this.sharedLinkId = params.id;
});
}
}

View File

@@ -29,6 +29,7 @@ export const SET_APP_NAME = 'SET_APP_NAME';
export const SET_HEADER_COLOR = 'SET_HEADER_COLOR';
export const SET_LOGO_PATH = 'SET_LOGO_PATH';
export const SET_LANGUAGE_PICKER = 'SET_LANGUAGE_PICKER';
export const SET_SHARED_URL = 'SET_SHARED_URL';
export class SetAppNameAction implements Action {
readonly type = SET_APP_NAME;
@@ -49,3 +50,8 @@ export class SetLanguagePickerAction implements Action {
readonly type = SET_LANGUAGE_PICKER;
constructor(public payload: boolean) {}
}
export class SetSharedUrlAction implements Action {
readonly type = SET_SHARED_URL;
constructor(public payload: string) {}
}

View File

@@ -39,7 +39,9 @@ import {
} from '../actions';
import {
SET_LANGUAGE_PICKER,
SetLanguagePickerAction
SetLanguagePickerAction,
SET_SHARED_URL,
SetSharedUrlAction
} from '../actions/app.actions';
export function appReducer(
@@ -71,6 +73,11 @@ export function appReducer(
action
));
break;
case SET_SHARED_URL:
newState = updateSharedUrl(state, <SetSharedUrlAction>(
action
));
break;
default:
newState = Object.assign({}, state);
}
@@ -108,6 +115,15 @@ function updateLogoPath(state: AppState, action: SetLogoPathAction): AppState {
return newState;
}
function updateSharedUrl(
state: AppState,
action: SetSharedUrlAction
): AppState {
const newState = Object.assign({}, state);
newState.sharedUrl = action.payload;
return newState;
}
function updateUser(state: AppState, action: SetUserAction): AppState {
const newState = Object.assign({}, state);
const user = action.payload;

View File

@@ -33,3 +33,4 @@ export const selectLogoPath = createSelector(selectApp, state => state.logoPath)
export const appSelection = createSelector(selectApp, state => state.selection);
export const appLanguagePicker = createSelector(selectApp, state => state.languagePicker);
export const selectUser = createSelector(selectApp, state => state.user);
export const sharedUrl = createSelector(selectApp, state => state.sharedUrl);

View File

@@ -31,6 +31,7 @@ export interface AppState {
headerColor: string;
logoPath: string;
languagePicker: boolean;
sharedUrl: string;
selection: SelectionState;
user: ProfileState;
}
@@ -40,6 +41,7 @@ export const INITIAL_APP_STATE: AppState = {
headerColor: '#2196F3',
logoPath: 'assets/images/alfresco-logo-white.svg',
languagePicker: false,
sharedUrl: '',
user: {
isAdmin: true, // 5.2.x
id: null,

View File

@@ -124,7 +124,8 @@
"UNSHARE": "Unshare",
"DETAILS": "View details",
"VERSIONS": "Manage Versions",
"TOGGLE-SIDENAV": "Toggle side navigation bar"
"TOGGLE-SIDENAV": "Toggle side navigation bar",
"SHARE": "Share"
},
"DIALOGS": {
"CONFIRM_PURGE": {