mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-12 17:04:46 +00:00
[AAE-10533] Generic App shell for HxP applications (#2679)
* [AAE-10533] Generic App shell for HxP applications * refactor * fix scss mixin path * remove forRoot in content-plugin * remove provided routers * revert router service * revert template usage * Added shell markdown * Move login component to content-plugin * Moved logic from app.component to app.service * remove upload-area from shell * cleaning * cleaning * update md * abstract preferences * allow to set shell parent route * fix preferencesService name * Fix for sidenav * Fix CR comments * [ci:force] * move translation service mock to aca-shared * fix e2e * Fix page title * remove drop area wrapper from whole application * Fix e2e * [ci:force] * Remove blank page from shell * Add upload files dialog * [ci:force] * Remove ExtensionsDataLoaderGuard from shell
This commit is contained in:
parent
3650aff589
commit
456454fee1
@ -36,6 +36,7 @@
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"app/src/app/ui",
|
||||
"app/src/app/content-plugin/ui",
|
||||
"node_modules"
|
||||
]
|
||||
},
|
||||
@ -252,7 +253,7 @@
|
||||
"polyfills": "app/src/polyfills.ts",
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"app/src/app/ui",
|
||||
"app/src/app/content-plugin/ui",
|
||||
"node_modules"
|
||||
]
|
||||
},
|
||||
|
72
app/src/app/app-shell/app-shell.module.ts
Normal file
72
app/src/app/app-shell/app-shell.module.ts
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved.
|
||||
*
|
||||
* License rights for this program may be obtained from Alfresco Software, Ltd.
|
||||
* pursuant to a written agreement and any use of this program without such an
|
||||
* agreement is prohibited.
|
||||
*/
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ModuleWithProviders, NgModule } from '@angular/core';
|
||||
import { Routes, provideRoutes, RouterModule, Route } from '@angular/router';
|
||||
import { SHELL_LAYOUT_ROUTE } from './app-shell.routes';
|
||||
import { SidenavLayoutModule } from '@alfresco/adf-core';
|
||||
import { ExtensionsModule } from '@alfresco/adf-extensions';
|
||||
import { ShellLayoutComponent } from './components/shell/shell.component';
|
||||
|
||||
export interface AppShellRoutesConfig {
|
||||
shellParentRoute?: Route;
|
||||
shellChildren: Routes;
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [SidenavLayoutModule, ExtensionsModule, RouterModule.forChild([]), CommonModule],
|
||||
exports: [ShellLayoutComponent],
|
||||
declarations: [ShellLayoutComponent]
|
||||
})
|
||||
export class AppShellModule {
|
||||
static withRoutes(routes: Routes | AppShellRoutesConfig): ModuleWithProviders<AppShellModule> {
|
||||
if (Array.isArray(routes)) {
|
||||
return getModuleForRoutes(routes);
|
||||
}
|
||||
|
||||
return getModuleForRouteConfig(routes);
|
||||
}
|
||||
}
|
||||
|
||||
function getModuleForRoutes(routes: Routes): ModuleWithProviders<AppShellModule> {
|
||||
const shellLayoutRoute = SHELL_LAYOUT_ROUTE;
|
||||
|
||||
routes.forEach((childRoute) => {
|
||||
shellLayoutRoute.children.push(childRoute);
|
||||
});
|
||||
|
||||
return {
|
||||
ngModule: AppShellModule,
|
||||
providers: provideRoutes([shellLayoutRoute])
|
||||
};
|
||||
}
|
||||
|
||||
function getModuleForRouteConfig(config: AppShellRoutesConfig): ModuleWithProviders<AppShellModule> {
|
||||
const shellLayoutRoute = SHELL_LAYOUT_ROUTE;
|
||||
|
||||
const shellParentRoute = config.shellParentRoute;
|
||||
const shellChildrenRoutes = config.shellChildren;
|
||||
|
||||
shellLayoutRoute.children.push(...shellChildrenRoutes);
|
||||
|
||||
const rootRoute = shellParentRoute ? shellParentRoute : shellLayoutRoute;
|
||||
|
||||
if (config.shellParentRoute) {
|
||||
if (rootRoute.children === undefined) {
|
||||
rootRoute.children = [];
|
||||
}
|
||||
|
||||
rootRoute.children.push(shellLayoutRoute);
|
||||
}
|
||||
|
||||
return {
|
||||
ngModule: AppShellModule,
|
||||
providers: provideRoutes([rootRoute])
|
||||
};
|
||||
}
|
20
app/src/app/app-shell/app-shell.routes.ts
Normal file
20
app/src/app/app-shell/app-shell.routes.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved.
|
||||
*
|
||||
* License rights for this program may be obtained from Alfresco Software, Ltd.
|
||||
* pursuant to a written agreement and any use of this program without such an
|
||||
* agreement is prohibited.
|
||||
*/
|
||||
|
||||
import { InjectionToken } from '@angular/core';
|
||||
import { CanActivate, CanActivateChild, Route } from '@angular/router';
|
||||
import { ShellLayoutComponent } from './components/shell/shell.component';
|
||||
|
||||
export const SHELL_AUTH_TOKEN = new InjectionToken<CanActivate & CanActivateChild>('SHELL_AUTH_TOKEN');
|
||||
|
||||
export const SHELL_LAYOUT_ROUTE: Route = {
|
||||
path: '',
|
||||
component: ShellLayoutComponent,
|
||||
canActivate: [SHELL_AUTH_TOKEN],
|
||||
children: []
|
||||
};
|
48
app/src/app/app-shell/components/shell/shell.component.html
Normal file
48
app/src/app/app-shell/components/shell/shell.component.html
Normal file
@ -0,0 +1,48 @@
|
||||
<adf-sidenav-layout
|
||||
#layout
|
||||
[sidenavMin]="70"
|
||||
[sidenavMax]="320"
|
||||
[stepOver]="600"
|
||||
[hideSidenav]="hideSidenav"
|
||||
[expandedSidenav]="expandedSidenav"
|
||||
(expanded)="onExpanded($event)"
|
||||
>
|
||||
<adf-sidenav-layout-header>
|
||||
<ng-template let-isMenuMinimized="isMenuMinimized">
|
||||
<div
|
||||
role="heading"
|
||||
aria-level="1"
|
||||
*ngIf="!hideSidenav"
|
||||
>
|
||||
<adf-dynamic-component id="app.layout.header" [data]="{ layout }">
|
||||
</adf-dynamic-component>
|
||||
</div>
|
||||
</ng-template>
|
||||
</adf-sidenav-layout-header>
|
||||
|
||||
<adf-sidenav-layout-navigation>
|
||||
<ng-template let-isMenuMinimized="isMenuMinimized">
|
||||
<div
|
||||
(swipeleft)="hideMenu($event)"
|
||||
[attr.data-automation-id]="isMenuMinimized() ? 'collapsed' : 'expanded'"
|
||||
>
|
||||
<adf-dynamic-component
|
||||
id="app.layout.sidenav"
|
||||
[data]="{ mode: layout.isMenuMinimized ? 'collapsed' : 'expanded'}"
|
||||
>
|
||||
</adf-dynamic-component>
|
||||
</div>
|
||||
</ng-template>
|
||||
</adf-sidenav-layout-navigation>
|
||||
|
||||
<adf-sidenav-layout-content>
|
||||
<ng-template>
|
||||
<router-outlet></router-outlet>
|
||||
</ng-template>
|
||||
</adf-sidenav-layout-content>
|
||||
</adf-sidenav-layout>
|
||||
|
||||
<adf-dynamic-component id="app.shell.sibling">
|
||||
</adf-dynamic-component>
|
||||
|
||||
<router-outlet name="viewer"></router-outlet>
|
34
app/src/app/app-shell/components/shell/shell.component.scss
Normal file
34
app/src/app/app-shell/components/shell/shell.component.scss
Normal file
@ -0,0 +1,34 @@
|
||||
.app-shell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
|
||||
router-outlet[name='viewer'] + * {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 999;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
adf-file-uploading-dialog {
|
||||
z-index: 1000;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 599px) {
|
||||
.adf-app-title {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 719px) {
|
||||
.adf-app-logo {
|
||||
display: none;
|
||||
}
|
||||
}
|
169
app/src/app/app-shell/components/shell/shell.component.spec.ts
Normal file
169
app/src/app/app-shell/components/shell/shell.component.spec.ts
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved.
|
||||
*
|
||||
* License rights for this program may be obtained from Alfresco Software, Ltd.
|
||||
* pursuant to a written agreement and any use of this program without such an
|
||||
* agreement is prohibited.
|
||||
*/
|
||||
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||
import { AppConfigService, SidenavLayoutModule } from '@alfresco/adf-core';
|
||||
import { ShellLayoutComponent } from './shell.component';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Router, NavigationStart, RouterModule } from '@angular/router';
|
||||
import { of, Subject } from 'rxjs';
|
||||
import { ExtensionsModule } from '@alfresco/adf-extensions';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ShellAppService, SHELL_APP_SERVICE } from '../../services/shell-app.service';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { TranslateServiceMock } from '@alfresco/aca-shared';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
class MockRouter {
|
||||
private url = 'some-url';
|
||||
private subject = new Subject();
|
||||
events = this.subject.asObservable();
|
||||
routerState = { snapshot: { url: this.url } };
|
||||
|
||||
navigateByUrl(url: string) {
|
||||
const navigationStart = new NavigationStart(0, url);
|
||||
this.subject.next(navigationStart);
|
||||
}
|
||||
}
|
||||
|
||||
describe('AppLayoutComponent', () => {
|
||||
let fixture: ComponentFixture<ShellLayoutComponent>;
|
||||
let component: ShellLayoutComponent;
|
||||
let appConfig: AppConfigService;
|
||||
let shellAppService: ShellAppService;
|
||||
|
||||
beforeEach(() => {
|
||||
const shellService: ShellAppService = {
|
||||
pageHeading$: of('Title'),
|
||||
hideSidenavConditions: [],
|
||||
minimizeSidenavConditions: [],
|
||||
preferencesService: {
|
||||
get: (_key: string) => 'true',
|
||||
set: (_key: string, _value: any) => {}
|
||||
}
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CommonModule, NoopAnimationsModule, HttpClientModule, SidenavLayoutModule, ExtensionsModule, RouterModule.forChild([])],
|
||||
providers: [
|
||||
Store,
|
||||
{
|
||||
provide: Router,
|
||||
useClass: MockRouter
|
||||
},
|
||||
{
|
||||
provide: SHELL_APP_SERVICE,
|
||||
useValue: shellService
|
||||
},
|
||||
{ provide: TranslateService, useClass: TranslateServiceMock }
|
||||
],
|
||||
declarations: [ShellLayoutComponent],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(ShellLayoutComponent);
|
||||
component = fixture.componentInstance;
|
||||
appConfig = TestBed.inject(AppConfigService);
|
||||
shellAppService = TestBed.inject(SHELL_APP_SERVICE);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
appConfig.config.languages = [];
|
||||
appConfig.config.locale = 'en';
|
||||
});
|
||||
|
||||
describe('sidenav state', () => {
|
||||
it('should get state from configuration', () => {
|
||||
appConfig.config.sideNav = {
|
||||
expandedSidenav: false,
|
||||
preserveState: false
|
||||
};
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.expandedSidenav).toBe(false);
|
||||
});
|
||||
|
||||
it('should resolve state to true is no configuration', () => {
|
||||
appConfig.config.sidenav = {};
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.expandedSidenav).toBe(true);
|
||||
});
|
||||
|
||||
it('should get state from user settings as true', () => {
|
||||
appConfig.config.sideNav = {
|
||||
expandedSidenav: false,
|
||||
preserveState: true
|
||||
};
|
||||
|
||||
spyOn(shellAppService.preferencesService, 'get').and.callFake((key) => {
|
||||
if (key === 'expandedSidenav') {
|
||||
return 'true';
|
||||
}
|
||||
return 'false';
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.expandedSidenav).toBe(true);
|
||||
});
|
||||
|
||||
it('should get state from user settings as false', () => {
|
||||
appConfig.config.sidenav = {
|
||||
expandedSidenav: false,
|
||||
preserveState: true
|
||||
};
|
||||
|
||||
spyOn(shellAppService.preferencesService, 'get').and.callFake((key) => {
|
||||
if (key === 'expandedSidenav') {
|
||||
return 'false';
|
||||
}
|
||||
return 'true';
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.expandedSidenav).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('should close menu on mobile screen size', () => {
|
||||
component.minimizeSidenav = false;
|
||||
component.layout.container = {
|
||||
isMobileScreenSize: true,
|
||||
toggleMenu: () => {}
|
||||
};
|
||||
|
||||
spyOn(component.layout.container, 'toggleMenu');
|
||||
fixture.detectChanges();
|
||||
|
||||
component.hideMenu({ preventDefault: () => {} } as any);
|
||||
|
||||
expect(component.layout.container.toggleMenu).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should close menu on mobile screen size also when minimizeSidenav true', () => {
|
||||
fixture.detectChanges();
|
||||
component.minimizeSidenav = true;
|
||||
component.layout.container = {
|
||||
isMobileScreenSize: true,
|
||||
toggleMenu: () => {}
|
||||
};
|
||||
|
||||
spyOn(component.layout.container, 'toggleMenu');
|
||||
fixture.detectChanges();
|
||||
|
||||
component.hideMenu({ preventDefault: () => {} } as any);
|
||||
|
||||
expect(component.layout.container.toggleMenu).toHaveBeenCalled();
|
||||
});
|
||||
});
|
123
app/src/app/app-shell/components/shell/shell.component.ts
Normal file
123
app/src/app/app-shell/components/shell/shell.component.ts
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved.
|
||||
*
|
||||
* License rights for this program may be obtained from Alfresco Software, Ltd.
|
||||
* pursuant to a written agreement and any use of this program without such an
|
||||
* agreement is prohibited.
|
||||
*/
|
||||
|
||||
import { AppConfigService, SidenavLayoutComponent } from '@alfresco/adf-core';
|
||||
import { Component, Inject, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { Subject, Observable } from 'rxjs';
|
||||
import { filter, takeUntil, map, withLatestFrom } from 'rxjs/operators';
|
||||
import { BreakpointObserver } from '@angular/cdk/layout';
|
||||
import { Directionality } from '@angular/cdk/bidi';
|
||||
import { SHELL_APP_SERVICE, ShellAppService } from '../../services/shell-app.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-shell',
|
||||
templateUrl: './shell.component.html',
|
||||
styleUrls: ['./shell.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: { class: 'app-shell' }
|
||||
})
|
||||
export class ShellLayoutComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('layout', { static: true })
|
||||
layout: SidenavLayoutComponent;
|
||||
|
||||
onDestroy$: Subject<boolean> = new Subject<boolean>();
|
||||
isSmallScreen$: Observable<boolean>;
|
||||
|
||||
expandedSidenav: boolean;
|
||||
minimizeSidenav = false;
|
||||
hideSidenav = false;
|
||||
direction: Directionality;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private appConfigService: AppConfigService,
|
||||
private breakpointObserver: BreakpointObserver,
|
||||
@Inject(SHELL_APP_SERVICE) private shellService: ShellAppService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.isSmallScreen$ = this.breakpointObserver.observe(['(max-width: 600px)']).pipe(map((result) => result.matches));
|
||||
|
||||
this.hideSidenav = this.shellService.hideSidenavConditions.some((el) => this.router.routerState.snapshot.url.includes(el));
|
||||
this.minimizeSidenav = this.shellService.minimizeSidenavConditions.some((el) => this.router.routerState.snapshot.url.includes(el));
|
||||
|
||||
if (!this.minimizeSidenav) {
|
||||
this.expandedSidenav = this.getSidenavState();
|
||||
} else {
|
||||
this.expandedSidenav = false;
|
||||
}
|
||||
|
||||
this.router.events
|
||||
.pipe(
|
||||
withLatestFrom(this.isSmallScreen$),
|
||||
filter(([event, isSmallScreen]) => isSmallScreen && event instanceof NavigationEnd),
|
||||
takeUntil(this.onDestroy$)
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.layout.container.sidenav.close();
|
||||
});
|
||||
|
||||
this.router.events
|
||||
.pipe(
|
||||
filter((event) => event instanceof NavigationEnd),
|
||||
takeUntil(this.onDestroy$)
|
||||
)
|
||||
.subscribe((event: NavigationEnd) => {
|
||||
this.minimizeSidenav = this.shellService.minimizeSidenavConditions.some((el) => event.urlAfterRedirects.includes(el));
|
||||
this.hideSidenav = this.shellService.hideSidenavConditions.some((el) => event.urlAfterRedirects.includes(el));
|
||||
|
||||
this.updateState();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
hideMenu(event: Event) {
|
||||
if (this.layout.container.isMobileScreenSize) {
|
||||
event.preventDefault();
|
||||
this.layout.container.toggleMenu();
|
||||
}
|
||||
}
|
||||
|
||||
private updateState() {
|
||||
if (this.minimizeSidenav && !this.layout.isMenuMinimized) {
|
||||
this.layout.isMenuMinimized = true;
|
||||
if (!this.layout.container.isMobileScreenSize) {
|
||||
this.layout.container.toggleMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.minimizeSidenav) {
|
||||
if (this.getSidenavState() && this.layout.isMenuMinimized) {
|
||||
this.layout.isMenuMinimized = false;
|
||||
this.layout.container.toggleMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onExpanded(state: boolean) {
|
||||
if (!this.minimizeSidenav && this.appConfigService.get('sideNav.preserveState')) {
|
||||
this.shellService.preferencesService.set('expandedSidenav', state);
|
||||
}
|
||||
}
|
||||
|
||||
private getSidenavState(): boolean {
|
||||
const expand = this.appConfigService.get<boolean>('sideNav.expandedSidenav', true);
|
||||
const preserveState = this.appConfigService.get<boolean>('sideNav.preserveState', true);
|
||||
|
||||
if (preserveState) {
|
||||
return this.shellService.preferencesService.get('expandedSidenav', expand.toString()) === 'true';
|
||||
}
|
||||
|
||||
return expand;
|
||||
}
|
||||
}
|
10
app/src/app/app-shell/index.ts
Normal file
10
app/src/app/app-shell/index.ts
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved.
|
||||
*
|
||||
* License rights for this program may be obtained from Alfresco Software, Ltd.
|
||||
* pursuant to a written agreement and any use of this program without such an
|
||||
* agreement is prohibited.
|
||||
*/
|
||||
|
||||
export * from './app-shell.module';
|
||||
export * from './services/shell-app.service';
|
24
app/src/app/app-shell/services/shell-app.service.ts
Normal file
24
app/src/app/app-shell/services/shell-app.service.ts
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved.
|
||||
*
|
||||
* License rights for this program may be obtained from Alfresco Software, Ltd.
|
||||
* pursuant to a written agreement and any use of this program without such an
|
||||
* agreement is prohibited.
|
||||
*/
|
||||
|
||||
import { InjectionToken } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface ShellPreferencesService {
|
||||
set(preferenceKey: string, value: any): void;
|
||||
get(preferenceKey: string, defaultValue: string): string;
|
||||
}
|
||||
|
||||
export interface ShellAppService {
|
||||
pageHeading$: Observable<string>;
|
||||
hideSidenavConditions: string[];
|
||||
minimizeSidenavConditions: string[];
|
||||
preferencesService: ShellPreferencesService;
|
||||
}
|
||||
|
||||
export const SHELL_APP_SERVICE = new InjectionToken<ShellAppService>('SHELL_APP_SERVICE');
|
@ -1,2 +1,2 @@
|
||||
<h1 class="sr-only" title="{{pageHeading | translate}}">{{ pageHeading | translate }}</h1>
|
||||
<h1 class="sr-only" title="{{pageHeading | async | translate}}">{{ pageHeading | async | translate }}</h1>
|
||||
<router-outlet></router-outlet>
|
||||
|
@ -1,105 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2020 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { SetInitialStateAction } from '@alfresco/aca-shared/store';
|
||||
import { Router } from '@angular/router';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
let component: AppComponent;
|
||||
let router: Router;
|
||||
|
||||
const storeMock: any = {
|
||||
dispatch: jasmine.createSpy('dispatch')
|
||||
};
|
||||
|
||||
const overlayContainerMock: any = {
|
||||
getContainerElement: jasmine.createSpy('getContainerElement')
|
||||
};
|
||||
|
||||
const configMock: any = {
|
||||
get: (key: string) => {
|
||||
if (key === 'baseShareUrl') {
|
||||
return 'http://localhost:4200/#/preview/s';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [RouterTestingModule.withRoutes([{ path: 'fake-path', children: [] }])]
|
||||
});
|
||||
|
||||
router = TestBed.inject(Router);
|
||||
|
||||
component = new AppComponent(null, router, null, storeMock, configMock, null, null, null, null, null, null, null, null, overlayContainerMock);
|
||||
|
||||
storeMock.dispatch = jasmine.createSpy('dispatch');
|
||||
});
|
||||
|
||||
it('should setup baseShareUrl as per config', (done) => {
|
||||
storeMock.dispatch.and.callFake((action: SetInitialStateAction) => {
|
||||
expect(action.payload.sharedUrl).toBe('http://localhost:4200/#/preview/s/');
|
||||
done();
|
||||
});
|
||||
|
||||
component.loadAppSettings();
|
||||
});
|
||||
|
||||
describe('onFileUploadedError', () => {
|
||||
it('should dispatch 403 error message', () => {
|
||||
component.onFileUploadedError({ error: { status: 403 } } as any);
|
||||
expect(storeMock.dispatch['calls'].argsFor(0)[0].payload).toBe('APP.MESSAGES.UPLOAD.ERROR.403');
|
||||
});
|
||||
|
||||
it('should dispatch 404 error message', () => {
|
||||
component.onFileUploadedError({ error: { status: 404 } } as any);
|
||||
expect(storeMock.dispatch['calls'].argsFor(0)[0].payload).toBe('APP.MESSAGES.UPLOAD.ERROR.404');
|
||||
});
|
||||
|
||||
it('should dispatch 409 error message', () => {
|
||||
component.onFileUploadedError({ error: { status: 409 } } as any);
|
||||
expect(storeMock.dispatch['calls'].argsFor(0)[0].payload).toBe('APP.MESSAGES.UPLOAD.ERROR.CONFLICT');
|
||||
});
|
||||
|
||||
it('should dispatch 500 error message', () => {
|
||||
component.onFileUploadedError({ error: { status: 500 } } as any);
|
||||
expect(storeMock.dispatch['calls'].argsFor(0)[0].payload).toBe('APP.MESSAGES.UPLOAD.ERROR.500');
|
||||
});
|
||||
|
||||
it('should dispatch 504 error message', () => {
|
||||
component.onFileUploadedError({ error: { status: 504 } } as any);
|
||||
expect(storeMock.dispatch['calls'].argsFor(0)[0].payload).toBe('APP.MESSAGES.UPLOAD.ERROR.504');
|
||||
});
|
||||
|
||||
it('should dispatch generic error message', () => {
|
||||
component.onFileUploadedError({ error: { status: 999 } } as any);
|
||||
expect(storeMock.dispatch['calls'].argsFor(0)[0].payload).toBe('APP.MESSAGES.UPLOAD.ERROR.GENERIC');
|
||||
});
|
||||
});
|
||||
});
|
@ -1,233 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2020 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
AlfrescoApiService,
|
||||
AppConfigService,
|
||||
AuthenticationService,
|
||||
FileUploadErrorEvent,
|
||||
PageTitleService,
|
||||
UploadService,
|
||||
SharedLinksApiService
|
||||
} from '@alfresco/adf-core';
|
||||
import { GroupService } from '@alfresco/adf-content-services';
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { ActivatedRoute, Router, ActivationEnd } from '@angular/router';
|
||||
import { Store } from '@ngrx/store';
|
||||
import {
|
||||
AppStore,
|
||||
AppState,
|
||||
SetCurrentUrlAction,
|
||||
SetInitialStateAction,
|
||||
SetUserProfileAction,
|
||||
SnackbarErrorAction,
|
||||
CloseModalDialogsAction,
|
||||
SetRepositoryInfoAction,
|
||||
getCustomCssPath,
|
||||
getCustomWebFontPath
|
||||
} from '@alfresco/aca-shared/store';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
import { RouterExtensionService, AppService, ContentApiService } from '@alfresco/aca-shared';
|
||||
import { DiscoveryEntry, GroupEntry, Group } from '@alfresco/js-api';
|
||||
import { Subject } from 'rxjs';
|
||||
import { INITIAL_APP_STATE } from './store/initial-state';
|
||||
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss']
|
||||
})
|
||||
export class AppComponent implements OnInit, OnDestroy {
|
||||
onDestroy$: Subject<boolean> = new Subject<boolean>();
|
||||
pageHeading = '';
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private pageTitle: PageTitleService,
|
||||
private store: Store<AppStore>,
|
||||
private config: AppConfigService,
|
||||
private alfrescoApiService: AlfrescoApiService,
|
||||
private authenticationService: AuthenticationService,
|
||||
private uploadService: UploadService,
|
||||
private routerExtensionService: RouterExtensionService,
|
||||
private contentApi: ContentApiService,
|
||||
private appService: AppService,
|
||||
private sharedLinksApiService: SharedLinksApiService,
|
||||
private groupService: GroupService,
|
||||
private overlayContainer: OverlayContainer
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.alfrescoApiService.getInstance().on('error', (error: { status: number; response: any }) => {
|
||||
if (error.status === 401 && !this.alfrescoApiService.isExcludedErrorListener(error?.response?.req?.url)) {
|
||||
if (!this.authenticationService.isLoggedIn()) {
|
||||
this.store.dispatch(new CloseModalDialogsAction());
|
||||
|
||||
let redirectUrl = this.route.snapshot.queryParams['redirectUrl'];
|
||||
if (!redirectUrl) {
|
||||
redirectUrl = this.router.url;
|
||||
}
|
||||
|
||||
this.router.navigate(['/login'], {
|
||||
queryParams: { redirectUrl }
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.loadAppSettings();
|
||||
|
||||
this.loadCustomCss();
|
||||
this.loadCustomWebFont();
|
||||
|
||||
const { router, pageTitle } = this;
|
||||
|
||||
this.router.events
|
||||
.pipe(filter((event) => event instanceof ActivationEnd && event.snapshot.children.length === 0))
|
||||
.subscribe((event: ActivationEnd) => {
|
||||
const snapshot: any = event.snapshot || {};
|
||||
const data: any = snapshot.data || {};
|
||||
|
||||
this.pageHeading = data.title || '';
|
||||
pageTitle.setTitle(data.title || '');
|
||||
this.store.dispatch(new SetCurrentUrlAction(router.url));
|
||||
});
|
||||
|
||||
this.routerExtensionService.mapExtensionRoutes();
|
||||
|
||||
this.uploadService.fileUploadError.subscribe((error) => this.onFileUploadedError(error));
|
||||
|
||||
this.sharedLinksApiService.error.pipe(takeUntil(this.onDestroy$)).subscribe((err: { message: string }) => {
|
||||
this.store.dispatch(new SnackbarErrorAction(err.message));
|
||||
});
|
||||
|
||||
this.appService.ready$.pipe(takeUntil(this.onDestroy$)).subscribe((isReady) => {
|
||||
if (isReady) {
|
||||
this.loadRepositoryStatus();
|
||||
this.loadUserProfile();
|
||||
}
|
||||
});
|
||||
|
||||
this.overlayContainer.getContainerElement().setAttribute('role', 'region');
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
private loadRepositoryStatus() {
|
||||
this.contentApi.getRepositoryInformation().subscribe((response: DiscoveryEntry) => {
|
||||
this.store.dispatch(new SetRepositoryInfoAction(response.entry.repository));
|
||||
});
|
||||
}
|
||||
|
||||
private async loadUserProfile() {
|
||||
const groupsEntries: GroupEntry[] = await this.groupService.listAllGroupMembershipsForPerson('-me-', { maxItems: 250 });
|
||||
|
||||
const groups: Group[] = [];
|
||||
|
||||
if (groupsEntries) {
|
||||
groups.push(...groupsEntries.map((obj) => obj.entry));
|
||||
}
|
||||
|
||||
this.contentApi.getPerson('-me-').subscribe((person) => {
|
||||
this.store.dispatch(new SetUserProfileAction({ person: person.entry, groups }));
|
||||
});
|
||||
}
|
||||
|
||||
loadAppSettings() {
|
||||
let baseShareUrl = this.config.get<string>('baseShareUrl');
|
||||
if (!baseShareUrl.endsWith('/')) {
|
||||
baseShareUrl += '/';
|
||||
}
|
||||
|
||||
const state: AppState = {
|
||||
...INITIAL_APP_STATE,
|
||||
appName: this.config.get<string>('application.name'),
|
||||
headerColor: this.config.get<string>('headerColor'),
|
||||
headerTextColor: this.config.get<string>('headerTextColor', '#000000'),
|
||||
logoPath: this.config.get<string>('application.logo'),
|
||||
headerImagePath: this.config.get<string>('application.headerImagePath'),
|
||||
customCssPath: this.config.get<string>('customCssPath'),
|
||||
webFontPath: this.config.get<string>('webFontPath'),
|
||||
sharedUrl: baseShareUrl
|
||||
};
|
||||
|
||||
this.store.dispatch(new SetInitialStateAction(state));
|
||||
}
|
||||
|
||||
onFileUploadedError(error: FileUploadErrorEvent) {
|
||||
let message = 'APP.MESSAGES.UPLOAD.ERROR.GENERIC';
|
||||
|
||||
if (error.error.status === 403) {
|
||||
message = 'APP.MESSAGES.UPLOAD.ERROR.403';
|
||||
}
|
||||
|
||||
if (error.error.status === 404) {
|
||||
message = 'APP.MESSAGES.UPLOAD.ERROR.404';
|
||||
}
|
||||
|
||||
if (error.error.status === 409) {
|
||||
message = 'APP.MESSAGES.UPLOAD.ERROR.CONFLICT';
|
||||
}
|
||||
|
||||
if (error.error.status === 500) {
|
||||
message = 'APP.MESSAGES.UPLOAD.ERROR.500';
|
||||
}
|
||||
|
||||
if (error.error.status === 504) {
|
||||
message = 'APP.MESSAGES.UPLOAD.ERROR.504';
|
||||
}
|
||||
|
||||
this.store.dispatch(new SnackbarErrorAction(message));
|
||||
}
|
||||
|
||||
private loadCustomCss(): void {
|
||||
this.store.select(getCustomCssPath).subscribe((cssPath) => {
|
||||
if (cssPath) {
|
||||
this.createLink(cssPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private loadCustomWebFont(): void {
|
||||
this.store.select(getCustomWebFontPath).subscribe((fontUrl) => {
|
||||
if (fontUrl) {
|
||||
this.createLink(fontUrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private createLink(url: string): void {
|
||||
const cssLinkElement = document.createElement('link');
|
||||
cssLinkElement.setAttribute('rel', 'stylesheet');
|
||||
cssLinkElement.setAttribute('type', 'text/css');
|
||||
cssLinkElement.setAttribute('href', url);
|
||||
document.head.appendChild(cssLinkElement);
|
||||
}
|
||||
}
|
43
app/src/app/app.components.ts
Normal file
43
app/src/app/app.components.ts
Normal file
@ -0,0 +1,43 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2020 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { AppService } from '@alfresco/aca-shared';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss']
|
||||
})
|
||||
export class AppComponent {
|
||||
onDestroy$: Subject<boolean> = new Subject<boolean>();
|
||||
pageHeading: Observable<string>;
|
||||
|
||||
constructor(private appService: AppService) {
|
||||
this.pageHeading = this.appService.pageHeading$;
|
||||
this.appService.init();
|
||||
}
|
||||
}
|
@ -23,50 +23,15 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { BrowserModule, HammerModule } from '@angular/platform-browser';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { TRANSLATION_PROVIDER, CoreModule, AppConfigService, DebugAppConfigService } from '@alfresco/adf-core';
|
||||
import { ContentModule, ContentVersionService } from '@alfresco/adf-content-services';
|
||||
import { SharedModule } from '@alfresco/aca-shared';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { APP_ROUTES } from './app.routes';
|
||||
import { TRANSLATION_PROVIDER, AppConfigService, DebugAppConfigService, CoreModule, AuthGuard } from '@alfresco/adf-core';
|
||||
import { AppService, SharedModule } from '@alfresco/aca-shared';
|
||||
|
||||
import { FilesComponent } from './components/files/files.component';
|
||||
import { LibrariesComponent } from './components/libraries/libraries.component';
|
||||
import { FavoriteLibrariesComponent } from './components/favorite-libraries/favorite-libraries.component';
|
||||
import { ViewProfileModule } from './components/view-profile/view-profile.module';
|
||||
|
||||
import { AppStoreModule } from './store/app-store.module';
|
||||
import { MaterialModule } from './material.module';
|
||||
import { AppExtensionsModule } from './extensions.module';
|
||||
import { CoreExtensionsModule } from './extensions/core.extensions.module';
|
||||
import { AppInfoDrawerModule } from './components/info-drawer/info.drawer.module';
|
||||
import { DirectivesModule } from './directives/directives.module';
|
||||
import { ContextMenuModule } from './components/context-menu/context-menu.module';
|
||||
import { ExtensionsModule } from '@alfresco/adf-extensions';
|
||||
import { AppToolbarModule } from './components/toolbar/toolbar.module';
|
||||
import { AppCreateMenuModule } from './components/create-menu/create-menu.module';
|
||||
import { AppSidenavModule } from './components/sidenav/sidenav.module';
|
||||
import { AppCommonModule } from './components/common/common.module';
|
||||
import { AppLayoutModule } from './components/layout/layout.module';
|
||||
import { AppSearchInputModule } from './components/search/search-input.module';
|
||||
import { DocumentListCustomComponentsModule } from './components/dl-custom-components/document-list-custom-components.module';
|
||||
import { AppSearchResultsModule } from './components/search/search-results.module';
|
||||
import { AppLoginModule } from './components/login/login.module';
|
||||
import { AppHeaderModule } from './components/header/header.module';
|
||||
import { AppNodeVersionModule } from './components/node-version/node-version.module';
|
||||
import { FavoritesComponent } from './components/favorites/favorites.component';
|
||||
import { RecentFilesComponent } from './components/recent-files/recent-files.component';
|
||||
import { SharedFilesComponent } from './components/shared-files/shared-files.component';
|
||||
import { CreateFromTemplateDialogComponent } from './dialogs/node-template/create-from-template.dialog';
|
||||
import { environment } from '../environments/environment';
|
||||
import { DetailsComponent } from './components/details/details.component';
|
||||
import { ContentUrlService } from './services/content-url.service';
|
||||
import { HomeComponent } from './components/home/home.component';
|
||||
|
||||
import { registerLocaleData } from '@angular/common';
|
||||
import localeFr from '@angular/common/locales/fr';
|
||||
@ -85,6 +50,18 @@ import localePl from '@angular/common/locales/pl';
|
||||
import localeFi from '@angular/common/locales/fi';
|
||||
import localeDa from '@angular/common/locales/da';
|
||||
import localeSv from '@angular/common/locales/sv';
|
||||
import { AppShellModule, SHELL_APP_SERVICE } from './app-shell';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { AppComponent } from './app.components';
|
||||
import { SHELL_AUTH_TOKEN } from './app-shell/app-shell.routes';
|
||||
import { CONTENT_LAYOUT_ROUTES } from './content-plugin/content.routes';
|
||||
import { ContentServiceExtensionModule } from './content-plugin/content-services-extension.module';
|
||||
import { CoreExtensionsModule } from './extensions/core.extensions.module';
|
||||
import { INITIAL_APP_STATE } from './content-plugin/store/initial-state';
|
||||
import { ContentVersionService } from '@alfresco/adf-content-services';
|
||||
import { ContentUrlService } from './content-plugin/services/content-url.service';
|
||||
import { STORE_INITIAL_APP_DATA } from '@alfresco/aca-shared/store';
|
||||
|
||||
registerLocaleData(localeFr);
|
||||
registerLocaleData(localeDe);
|
||||
@ -106,54 +83,38 @@ registerLocaleData(localeSv);
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
TranslateModule.forRoot(),
|
||||
CoreModule.forRoot(),
|
||||
SharedModule.forRoot(),
|
||||
CoreExtensionsModule.forRoot(),
|
||||
environment.e2e ? NoopAnimationsModule : BrowserAnimationsModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
RouterModule.forRoot(APP_ROUTES, {
|
||||
RouterModule.forRoot([], {
|
||||
useHash: true,
|
||||
enableTracing: false, // enable for debug only
|
||||
relativeLinkResolution: 'legacy'
|
||||
}),
|
||||
MaterialModule,
|
||||
CoreModule.forRoot(),
|
||||
ContentModule.forRoot(),
|
||||
SharedModule.forRoot(),
|
||||
AppStoreModule,
|
||||
CoreExtensionsModule.forRoot(),
|
||||
ExtensionsModule.forRoot(),
|
||||
AppExtensionsModule,
|
||||
AppLoginModule,
|
||||
AppCommonModule,
|
||||
AppLayoutModule,
|
||||
DirectivesModule,
|
||||
ContextMenuModule,
|
||||
AppInfoDrawerModule,
|
||||
AppToolbarModule,
|
||||
AppSidenavModule,
|
||||
AppCreateMenuModule,
|
||||
DocumentListCustomComponentsModule,
|
||||
AppSearchInputModule,
|
||||
AppSearchResultsModule,
|
||||
AppHeaderModule,
|
||||
AppNodeVersionModule,
|
||||
HammerModule,
|
||||
ViewProfileModule
|
||||
],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
FilesComponent,
|
||||
DetailsComponent,
|
||||
LibrariesComponent,
|
||||
FavoriteLibrariesComponent,
|
||||
FavoritesComponent,
|
||||
RecentFilesComponent,
|
||||
SharedFilesComponent,
|
||||
CreateFromTemplateDialogComponent,
|
||||
HomeComponent
|
||||
AppShellModule.withRoutes({
|
||||
shellChildren: [CONTENT_LAYOUT_ROUTES]
|
||||
}),
|
||||
ContentServiceExtensionModule
|
||||
],
|
||||
providers: [
|
||||
{ provide: AppService, useClass: AppService },
|
||||
{ provide: AppConfigService, useClass: DebugAppConfigService },
|
||||
{ provide: ContentVersionService, useClass: ContentUrlService },
|
||||
{
|
||||
provide: SHELL_APP_SERVICE,
|
||||
useClass: AppService
|
||||
},
|
||||
{
|
||||
provide: SHELL_AUTH_TOKEN,
|
||||
useClass: AuthGuard
|
||||
},
|
||||
{
|
||||
provide: STORE_INITIAL_APP_DATA,
|
||||
useValue: INITIAL_APP_STATE
|
||||
},
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
@ -163,6 +124,7 @@ registerLocaleData(localeSv);
|
||||
}
|
||||
}
|
||||
],
|
||||
declarations: [AppComponent],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule {}
|
||||
|
@ -1,575 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2020 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Routes } from '@angular/router';
|
||||
import { AppLayoutComponent } from './components/layout/app-layout/app-layout.component';
|
||||
import { FilesComponent } from './components/files/files.component';
|
||||
import { LibrariesComponent } from './components/libraries/libraries.component';
|
||||
import { FavoriteLibrariesComponent } from './components/favorite-libraries/favorite-libraries.component';
|
||||
import { SearchResultsComponent } from './components/search/search-results/search-results.component';
|
||||
import { SearchLibrariesResultsComponent } from './components/search/search-libraries-results/search-libraries-results.component';
|
||||
import { LoginComponent } from './components/login/login.component';
|
||||
import { AppSharedRuleGuard, GenericErrorComponent, ExtensionsDataLoaderGuard } from '@alfresco/aca-shared';
|
||||
import { AuthGuard, BlankPageComponent } from '@alfresco/adf-core';
|
||||
import { FavoritesComponent } from './components/favorites/favorites.component';
|
||||
import { RecentFilesComponent } from './components/recent-files/recent-files.component';
|
||||
import { SharedFilesComponent } from './components/shared-files/shared-files.component';
|
||||
import { DetailsComponent } from './components/details/details.component';
|
||||
import { HomeComponent } from './components/home/home.component';
|
||||
import { ViewProfileComponent } from './components/view-profile/view-profile.component';
|
||||
import { ViewProfileRuleGuard } from './components/view-profile/view-profile.guard';
|
||||
|
||||
export const APP_ROUTES: Routes = [
|
||||
{
|
||||
path: 'blank',
|
||||
component: BlankPageComponent
|
||||
},
|
||||
{
|
||||
path: 'login',
|
||||
component: LoginComponent,
|
||||
data: {
|
||||
title: 'APP.SIGN_IN'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'preview/s/:id',
|
||||
loadChildren: () => import('./components/shared-link-view/shared-link-view.module').then((m) => m.AppSharedLinkViewModule)
|
||||
},
|
||||
{
|
||||
path: 'view',
|
||||
component: AppLayoutComponent,
|
||||
children: [
|
||||
{
|
||||
path: ':nodeId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: AppLayoutComponent,
|
||||
canActivate: [AuthGuard, ExtensionsDataLoaderGuard],
|
||||
children: [
|
||||
{
|
||||
path: 'profile',
|
||||
canActivate: [ViewProfileRuleGuard],
|
||||
component: ViewProfileComponent
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: HomeComponent
|
||||
},
|
||||
{
|
||||
path: 'personal-files',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: FilesComponent,
|
||||
data: {
|
||||
sortingPreferenceKey: 'personal-files',
|
||||
title: 'APP.BROWSE.PERSONAL.TITLE',
|
||||
defaultNodeId: '-my-'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'details/:nodeId',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: DetailsComponent,
|
||||
data: {
|
||||
navigateSource: 'personal-files'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: ':activeTab',
|
||||
component: DetailsComponent,
|
||||
data: {
|
||||
title: 'APP.BROWSE.PERSONAL.PERMISSIONS.TITLE',
|
||||
navigateSource: 'personal-files'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
// deprecated, backwards compatibility with ACA 1.8
|
||||
{
|
||||
path: 'preview/:nodeId',
|
||||
loadChildren: () => import('./components/preview/preview.module').then((m) => m.PreviewModule),
|
||||
data: {
|
||||
navigateSource: 'personal-files'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'personal-files'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId/:versionId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'personal-files'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'personal-files/:folderId',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: FilesComponent,
|
||||
data: {
|
||||
title: 'APP.BROWSE.PERSONAL.TITLE',
|
||||
sortingPreferenceKey: 'personal-files'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId/:versionId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'personal-files'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
},
|
||||
// deprecated, backwards compatibility with ACA 1.8
|
||||
{
|
||||
path: 'preview/:nodeId',
|
||||
loadChildren: () => import('./components/preview/preview.module').then((m) => m.PreviewModule),
|
||||
data: {
|
||||
navigateSource: 'personal-files'
|
||||
}
|
||||
},
|
||||
// deprecated, backwards compatibility with ACA 1.8
|
||||
{
|
||||
path: ':folderId/preview/:nodeId',
|
||||
loadChildren: () => import('./components/preview/preview.module').then((m) => m.PreviewModule),
|
||||
data: {
|
||||
navigateSource: 'personal-files'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'personal-files'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'libraries',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: LibrariesComponent,
|
||||
data: {
|
||||
title: 'APP.BROWSE.LIBRARIES.MENU.MY_LIBRARIES.TITLE',
|
||||
sortingPreferenceKey: 'libraries'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'libraries/:folderId',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: FilesComponent,
|
||||
data: {
|
||||
title: 'APP.BROWSE.LIBRARIES.MENU.MY_LIBRARIES.TITLE',
|
||||
sortingPreferenceKey: 'libraries-files'
|
||||
}
|
||||
},
|
||||
// deprecated, backwards compatibility with ACA 1.8
|
||||
{
|
||||
path: 'preview/:nodeId',
|
||||
loadChildren: () => import('./components/preview/preview.module').then((m) => m.PreviewModule),
|
||||
data: {
|
||||
navigateSource: 'libraries'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'libraries'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId/:versionId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'libraries'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'favorite',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
pathMatch: 'full',
|
||||
redirectTo: 'libraries'
|
||||
},
|
||||
{
|
||||
path: 'libraries',
|
||||
component: FavoriteLibrariesComponent,
|
||||
data: {
|
||||
title: 'APP.BROWSE.LIBRARIES.MENU.FAVORITE_LIBRARIES.TITLE',
|
||||
sortingPreferenceKey: 'favorite-libraries'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'favorite/libraries/:folderId',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: FilesComponent,
|
||||
data: {
|
||||
title: 'APP.BROWSE.LIBRARIES.MENU.FAVORITE_LIBRARIES.TITLE',
|
||||
sortingPreferenceKey: 'libraries-files'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'libraries'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId/:versionId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'libraries'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'favorites',
|
||||
data: {
|
||||
sortingPreferenceKey: 'favorites'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: FavoritesComponent,
|
||||
data: {
|
||||
title: 'APP.BROWSE.FAVORITES.TITLE',
|
||||
sortingPreferenceKey: 'favorites'
|
||||
}
|
||||
// loadChildren:
|
||||
// './components/favorites/favorites.module#AppFavoritesModule'
|
||||
},
|
||||
// deprecated, backwards compatibility with ACA 1.8
|
||||
{
|
||||
path: 'preview/:nodeId',
|
||||
loadChildren: () => import('./components/preview/preview.module').then((m) => m.PreviewModule),
|
||||
data: {
|
||||
navigateSource: 'favorites'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'favorites'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId/:versionId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'favorites'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'recent-files',
|
||||
data: {
|
||||
sortingPreferenceKey: 'recent-files'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: RecentFilesComponent,
|
||||
data: {
|
||||
title: 'APP.BROWSE.RECENT.TITLE'
|
||||
}
|
||||
// loadChildren:
|
||||
// './components/recent-files/recent-files.module#AppRecentFilesModule'
|
||||
},
|
||||
// deprecated, backwards compatibility with ACA 1.8
|
||||
{
|
||||
path: 'preview/:nodeId',
|
||||
loadChildren: () => import('./components/preview/preview.module').then((m) => m.PreviewModule),
|
||||
data: {
|
||||
navigateSource: 'recent-files'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'recent-files'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId/:versionId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'recent-files'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'shared',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
title: 'APP.BROWSE.SHARED.TITLE',
|
||||
sortingPreferenceKey: 'shared-files'
|
||||
},
|
||||
component: SharedFilesComponent
|
||||
// loadChildren:
|
||||
// './components/shared-files/shared-files.module#AppSharedFilesModule'
|
||||
},
|
||||
// deprecated, backwards compatibility with ACA 1.8
|
||||
{
|
||||
path: 'preview/:nodeId',
|
||||
loadChildren: () => import('./components/preview/preview.module').then((m) => m.PreviewModule),
|
||||
data: {
|
||||
navigateSource: 'shared'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'shared'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId/:versionId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'shared'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
canActivateChild: [AppSharedRuleGuard],
|
||||
canActivate: [AppSharedRuleGuard]
|
||||
},
|
||||
{
|
||||
path: 'trashcan',
|
||||
loadChildren: () => import('./components/trashcan/trashcan.module').then((m) => m.AppTrashcanModule)
|
||||
},
|
||||
{
|
||||
path: 'search',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: SearchResultsComponent,
|
||||
data: {
|
||||
title: 'APP.BROWSE.SEARCH.TITLE'
|
||||
}
|
||||
},
|
||||
// deprecated, backwards compatibility with ACA 1.8
|
||||
{
|
||||
path: 'preview/:nodeId',
|
||||
loadChildren: () => import('./components/preview/preview.module').then((m) => m.PreviewModule),
|
||||
data: {
|
||||
navigateSource: 'search'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'search'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId/:versionId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'search'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'search-libraries',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: SearchLibrariesResultsComponent,
|
||||
data: {
|
||||
title: 'APP.BROWSE.SEARCH.TITLE'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'view/:nodeId',
|
||||
outlet: 'viewer',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
data: {
|
||||
navigateSource: 'search'
|
||||
},
|
||||
loadChildren: () => import('./components/viewer/viewer.module').then((m) => m.AppViewerModule)
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'nodes/:nodeId',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
loadChildren: () => import('@alfresco/aca-folder-rules').then((m) => m.AcaFolderRulesModule)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
component: GenericErrorComponent
|
||||
}
|
||||
],
|
||||
canActivateChild: [AuthGuard]
|
||||
}
|
||||
];
|
@ -30,7 +30,7 @@ import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { CoreExtensionsModule } from '../../extensions/core.extensions.module';
|
||||
import { CoreExtensionsModule } from '../../../extensions/core.extensions.module';
|
||||
import { AppCommonModule } from '../common/common.module';
|
||||
import { ContextMenuItemComponent } from './context-menu-item.component';
|
||||
import { OutsideEventDirective } from './context-menu-outside-event.directive';
|
@ -26,8 +26,8 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { AppTestingModule } from '../../testing/app-testing.module';
|
||||
import { DetailsComponent } from './details.component';
|
||||
import { MetadataTabComponent } from './../info-drawer/metadata-tab/metadata-tab.component';
|
||||
import { CommentsTabComponent } from './../info-drawer/comments-tab/comments-tab.component';
|
||||
import { MetadataTabComponent } from '../info-drawer/metadata-tab/metadata-tab.component';
|
||||
import { CommentsTabComponent } from '../info-drawer/comments-tab/comments-tab.component';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { of, Subject } from 'rxjs';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
@ -28,7 +28,7 @@ import { NgModule } from '@angular/core';
|
||||
import { CustomNameColumnComponent } from './name-column/name-column.component';
|
||||
import { LockedByModule } from '@alfresco/aca-shared';
|
||||
import { ContentModule } from '@alfresco/adf-content-services';
|
||||
import { MaterialModule } from '../../material.module';
|
||||
import { MaterialModule } from '../../../material.module';
|
||||
import { CoreModule } from '@alfresco/adf-core';
|
||||
import { ThumbnailColumnComponent } from './thumbnail-column/thumbnail-column.component';
|
||||
|
@ -4,8 +4,8 @@
|
||||
[tooltip]="appName$ | async"
|
||||
[color]="headerColor$ | async"
|
||||
[title]="appName$ | async"
|
||||
(clicked)="toggleClicked.emit($event)"
|
||||
[expandedSidenav]="expandedSidenav"
|
||||
(clicked)="onToggleSidenav($event)"
|
||||
[expandedSidenav]="isSidenavExpanded"
|
||||
>
|
||||
<div class="adf-toolbar--spacer adf-toolbar-divider"></div>
|
||||
|
@ -30,7 +30,7 @@ import { ContentActionRef } from '@alfresco/adf-extensions';
|
||||
import { AppStore, getHeaderColor, getAppName, getLogoPath, getHeaderImagePath, getHeaderTextColor } from '@alfresco/aca-shared/store';
|
||||
import { AppExtensionService } from '@alfresco/aca-shared';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { AppConfigService } from '@alfresco/adf-core';
|
||||
import { AppConfigService, SidenavLayoutComponent } from '@alfresco/adf-core';
|
||||
import { isContentServiceEnabled } from '@alfresco/aca-shared/rules';
|
||||
|
||||
@Component({
|
||||
@ -42,11 +42,18 @@ import { isContentServiceEnabled } from '@alfresco/aca-shared/rules';
|
||||
})
|
||||
export class AppHeaderComponent implements OnInit, OnDestroy {
|
||||
private onDestroy$: Subject<boolean> = new Subject<boolean>();
|
||||
|
||||
@Output()
|
||||
toggleClicked = new EventEmitter();
|
||||
|
||||
@Input() expandedSidenav = true;
|
||||
|
||||
@Input() data: { layout?: SidenavLayoutComponent; isMenuMinimized?: boolean } = {};
|
||||
|
||||
get isSidenavExpanded(): boolean {
|
||||
return !this.data.isMenuMinimized ?? this.expandedSidenav;
|
||||
}
|
||||
|
||||
appName$: Observable<string>;
|
||||
headerColor$: Observable<any>;
|
||||
headerTextColor$: Observable<string>;
|
||||
@ -55,7 +62,7 @@ export class AppHeaderComponent implements OnInit, OnDestroy {
|
||||
|
||||
actions: Array<ContentActionRef> = [];
|
||||
|
||||
constructor(store: Store<AppStore>, private appExtensions: AppExtensionService, private appConfigService: AppConfigService) {
|
||||
constructor(public store: Store<AppStore>, private appExtensions: AppExtensionService, private appConfigService: AppConfigService) {
|
||||
this.headerColor$ = store.select(getHeaderColor);
|
||||
this.headerTextColor$ = store.select(getHeaderTextColor);
|
||||
this.appName$ = store.select(getAppName);
|
||||
@ -80,6 +87,10 @@ export class AppHeaderComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
onToggleSidenav(_event: boolean): void {
|
||||
this.data.layout.toggleMenu();
|
||||
}
|
||||
|
||||
isContentServiceEnabled(): boolean {
|
||||
return isContentServiceEnabled();
|
||||
}
|
@ -29,7 +29,7 @@ import { ExtensionsModule } from '@alfresco/adf-extensions';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { DirectivesModule } from '../../directives/directives.module';
|
||||
import { MaterialModule } from '../../material.module';
|
||||
import { MaterialModule } from '../../../material.module';
|
||||
import { CommentsTabComponent } from './comments-tab/comments-tab.component';
|
||||
import { MetadataTabComponent } from './metadata-tab/metadata-tab.component';
|
||||
import { LibraryMetadataTabComponent } from './library-metadata-tab/library-metadata-tab.component';
|
@ -27,9 +27,11 @@ import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CoreModule } from '@alfresco/adf-core';
|
||||
import { LoginComponent } from './login.component';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, CoreModule.forChild()],
|
||||
imports: [CommonModule, CoreModule.forChild(), TranslateModule.forChild()],
|
||||
exports: [LoginComponent],
|
||||
declarations: [LoginComponent]
|
||||
})
|
||||
export class AppLoginModule {}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user