mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2026-09-09 18:02:54 +00:00
[ACA-1830] create menu enhancements (#670)
* nested menus for create button * evaluate sub-menu permissions * demo plugin * "create library" action * unit tests and proper effect name
This commit is contained in:
+1
-2
@@ -49,8 +49,7 @@
|
|||||||
"cardview",
|
"cardview",
|
||||||
"webm",
|
"webm",
|
||||||
"keycodes",
|
"keycodes",
|
||||||
"denysvuika",
|
"denysvuika"
|
||||||
"fdescribe"
|
|
||||||
],
|
],
|
||||||
"dictionaries": ["html", "en-gb", "en_US"]
|
"dictionaries": ["html", "en-gb", "en_US"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -612,6 +612,7 @@ Below is the list of public actions types you can use in the plugin definitions
|
|||||||
| NAVIGATE_ROUTE | any[] | Navigate to a particular Route (supports parameters) |
|
| NAVIGATE_ROUTE | any[] | Navigate to a particular Route (supports parameters) |
|
||||||
| NAVIGATE_FOLDER | MinimalNodeEntity | Navigate to a folder based on the Node properties. |
|
| NAVIGATE_FOLDER | MinimalNodeEntity | Navigate to a folder based on the Node properties. |
|
||||||
| NAVIGATE_PARENT_FOLDER | MinimalNodeEntity | Navigate to a containing folder based on the Node properties. |
|
| NAVIGATE_PARENT_FOLDER | MinimalNodeEntity | Navigate to a containing folder based on the Node properties. |
|
||||||
|
| NAVIGATE_LIBRARY | string | Navigate to library |
|
||||||
| SEARCH_BY_TERM | string | Perform a simple search by the term and navigate to Search results. |
|
| SEARCH_BY_TERM | string | Perform a simple search by the term and navigate to Search results. |
|
||||||
| SNACKBAR_INFO | string | Show information snackbar with the message provided. |
|
| SNACKBAR_INFO | string | Show information snackbar with the message provided. |
|
||||||
| SNACKBAR_WARNING | string | Show warning snackbar with the message provided. |
|
| SNACKBAR_WARNING | string | Show warning snackbar with the message provided. |
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export class Sidenav extends Component {
|
|||||||
link: '.sidenav-menu__item',
|
link: '.sidenav-menu__item',
|
||||||
label: '.menu__item--label',
|
label: '.menu__item--label',
|
||||||
activeLink: '.menu__item--active',
|
activeLink: '.menu__item--active',
|
||||||
newButton: '.adf-sidebar-action-menu-button'
|
newButton: '[data-automation-id="create-button"]'
|
||||||
};
|
};
|
||||||
|
|
||||||
links: ElementArrayFinder = this.component.all(by.css(Sidenav.selectors.link));
|
links: ElementArrayFinder = this.component.all(by.css(Sidenav.selectors.link));
|
||||||
|
|||||||
@@ -1,14 +1,26 @@
|
|||||||
<adf-sidebar-action-menu
|
<ng-container *ngIf="expanded">
|
||||||
[expanded]="showLabel"
|
<button
|
||||||
[attr.title]="'APP.NEW_MENU.TOOLTIP' | translate"
|
data-automation-id="create-button"
|
||||||
[title]="'APP.NEW_MENU.LABEL' | translate">
|
mat-raised-button
|
||||||
<mat-icon sidebar-menu-title-icon>arrow_drop_down</mat-icon>
|
[matMenuTriggerFor]="rootMenu"
|
||||||
<div sidebar-menu-expand-icon>
|
title="{{ 'APP.NEW_MENU.TOOLTIP' | translate }}">
|
||||||
<mat-icon [title]="'APP.NEW_MENU.TOOLTIP' | translate">queue</mat-icon>
|
<span class="app-create-menu__text">{{ 'APP.NEW_MENU.LABEL' | translate }}</span>
|
||||||
</div>
|
<mat-icon title="{{ 'APP.NEW_MENU.TOOLTIP' | translate }}">arrow_drop_down</mat-icon>
|
||||||
<div sidebar-menu-options>
|
</button>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="!expanded">
|
||||||
|
<button
|
||||||
|
class="app-create-menu--collapsed"
|
||||||
|
data-automation-id="create-button"
|
||||||
|
[matMenuTriggerFor]="rootMenu"
|
||||||
|
title="{{ 'APP.NEW_MENU.TOOLTIP' | translate }}">
|
||||||
|
<mat-icon title="{{ 'APP.NEW_MENU.TOOLTIP' | translate }}">queue</mat-icon>
|
||||||
|
</button>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<mat-menu #rootMenu="matMenu" class="app-create-menu__root-menu app-create-menu__sub-menu" [overlapTrigger]="false" yPosition="below">
|
||||||
<ng-container *ngFor="let action of createActions; trackBy: trackById">
|
<ng-container *ngFor="let action of createActions; trackBy: trackById">
|
||||||
<app-toolbar-menu-item [actionRef]="action"></app-toolbar-menu-item>
|
<app-toolbar-menu-item [actionRef]="action"></app-toolbar-menu-item>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</mat-menu>
|
||||||
</adf-sidebar-action-menu>
|
|
||||||
|
|||||||
@@ -1,3 +1,87 @@
|
|||||||
|
@mixin app-create-menu-theme($theme) {
|
||||||
|
$foreground: map-get($theme, foreground);
|
||||||
|
$accent: map-get($theme, accent);
|
||||||
|
$primary: map-get($theme, primary);
|
||||||
|
|
||||||
.app-create-menu {
|
.app-create-menu {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
.mat-raised-button {
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
box-shadow: none !important;
|
||||||
|
height: 37.5px;
|
||||||
|
background-color: mat-color($accent);
|
||||||
|
color: mat-color($primary, default-contrast) !important;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12.7px;
|
||||||
|
font-weight: normal;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
.mat-icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 25px;
|
||||||
|
color: mat-color($primary, default-contrast) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
width: 100%;
|
||||||
|
height: 20px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__root-menu {
|
||||||
|
max-width: 290px !important;
|
||||||
|
width: 290px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
& > .mat-menu-content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--collapsed {
|
||||||
|
color: mat-color($foreground, text, 0.54);
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
color: mat-color($primary);
|
||||||
|
}
|
||||||
|
margin: 0;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__sub-menu {
|
||||||
|
.mat-menu-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
color: mat-color($foreground, text, 0.54);
|
||||||
|
line-height: 48px;
|
||||||
|
box-shadow: none;
|
||||||
|
transform: none;
|
||||||
|
transition: unset;
|
||||||
|
font-weight: normal;
|
||||||
|
text-transform: capitalize;
|
||||||
|
color: mat-color($primary);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: mat-color($accent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-menu-item[disabled],
|
||||||
|
.mat-menu-item[disabled]:hover {
|
||||||
|
color: mat-color($foreground, text, 0.38);
|
||||||
|
|
||||||
|
.mat-icon {
|
||||||
|
color: mat-color($foreground, text, 0.38);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ export class CreateMenuComponent implements OnInit, OnDestroy {
|
|||||||
@Input()
|
@Input()
|
||||||
showLabel: boolean;
|
showLabel: boolean;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
expanded: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private store: Store<AppStore>,
|
private store: Store<AppStore>,
|
||||||
private extensions: AppExtensionService
|
private extensions: AppExtensionService
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ import { LibrariesComponent } from './libraries.component';
|
|||||||
import { AppTestingModule } from '../../testing/app-testing.module';
|
import { AppTestingModule } from '../../testing/app-testing.module';
|
||||||
import { ContentApiService } from '../../services/content-api.service';
|
import { ContentApiService } from '../../services/content-api.service';
|
||||||
import { ExperimentalDirective } from '../../directives/experimental.directive';
|
import { ExperimentalDirective } from '../../directives/experimental.directive';
|
||||||
|
import { EffectsModule } from '@ngrx/effects';
|
||||||
|
import { LibraryEffects } from 'src/app/store/effects';
|
||||||
|
|
||||||
describe('LibrariesComponent', () => {
|
describe('LibrariesComponent', () => {
|
||||||
let fixture: ComponentFixture<LibrariesComponent>;
|
let fixture: ComponentFixture<LibrariesComponent>;
|
||||||
@@ -69,7 +71,7 @@ describe('LibrariesComponent', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [AppTestingModule],
|
imports: [AppTestingModule, EffectsModule.forRoot([LibraryEffects])],
|
||||||
declarations: [
|
declarations: [
|
||||||
DataTableComponent,
|
DataTableComponent,
|
||||||
TimeAgoPipe,
|
TimeAgoPipe,
|
||||||
@@ -153,13 +155,8 @@ describe('LibrariesComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('Node navigation', () => {
|
describe('Node navigation', () => {
|
||||||
let routerSpy;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
routerSpy = spyOn(router, 'navigate');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not navigate when id is not passed', () => {
|
it('does not navigate when id is not passed', () => {
|
||||||
|
spyOn(router, 'navigate').and.stub();
|
||||||
component.navigate(null);
|
component.navigate(null);
|
||||||
|
|
||||||
expect(router.navigate).not.toHaveBeenCalled();
|
expect(router.navigate).not.toHaveBeenCalled();
|
||||||
@@ -167,11 +164,12 @@ describe('LibrariesComponent', () => {
|
|||||||
|
|
||||||
it('navigates to node id', () => {
|
it('navigates to node id', () => {
|
||||||
const document = { id: 'documentId' };
|
const document = { id: 'documentId' };
|
||||||
|
spyOn(router, 'navigate').and.stub();
|
||||||
spyOn(contentApi, 'getNode').and.returnValue(of({ entry: document }));
|
spyOn(contentApi, 'getNode').and.returnValue(of({ entry: document }));
|
||||||
|
|
||||||
component.navigate(node.id);
|
component.navigate(node.id);
|
||||||
|
|
||||||
expect(routerSpy.calls.argsFor(0)[0]).toEqual(['./', document.id]);
|
expect(router.navigate).toHaveBeenCalledWith(['libraries', 'documentId']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -24,18 +24,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
|
||||||
import { ShareDataRow } from '@alfresco/adf-content-services';
|
import { ShareDataRow } from '@alfresco/adf-content-services';
|
||||||
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
||||||
|
|
||||||
import { PageComponent } from '../page.component';
|
import { PageComponent } from '../page.component';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { AppStore } from '../../store/states/app.state';
|
import { AppStore } from '../../store/states/app.state';
|
||||||
import { SiteEntry } from 'alfresco-js-api';
|
import { SiteEntry } from 'alfresco-js-api';
|
||||||
import { ContentManagementService } from '../../services/content-management.service';
|
import { ContentManagementService } from '../../services/content-management.service';
|
||||||
import { ContentApiService } from '../../services/content-api.service';
|
|
||||||
import { AppExtensionService } from '../../extensions/extension.service';
|
import { AppExtensionService } from '../../extensions/extension.service';
|
||||||
import { map } from 'rxjs/operators';
|
import { NavigateLibraryAction } from 'src/app/store/actions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './libraries.component.html'
|
templateUrl: './libraries.component.html'
|
||||||
@@ -44,12 +41,9 @@ export class LibrariesComponent extends PageComponent implements OnInit {
|
|||||||
isSmallScreen = false;
|
isSmallScreen = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
|
||||||
content: ContentManagementService,
|
content: ContentManagementService,
|
||||||
private contentApi: ContentApiService,
|
|
||||||
store: Store<AppStore>,
|
store: Store<AppStore>,
|
||||||
extensions: AppExtensionService,
|
extensions: AppExtensionService,
|
||||||
private router: Router,
|
|
||||||
private breakpointObserver: BreakpointObserver
|
private breakpointObserver: BreakpointObserver
|
||||||
) {
|
) {
|
||||||
super(store, extensions, content);
|
super(store, extensions, content);
|
||||||
@@ -60,9 +54,6 @@ export class LibrariesComponent extends PageComponent implements OnInit {
|
|||||||
|
|
||||||
this.subscriptions.push(
|
this.subscriptions.push(
|
||||||
this.content.libraryDeleted.subscribe(() => this.reload()),
|
this.content.libraryDeleted.subscribe(() => this.reload()),
|
||||||
this.content.libraryCreated.subscribe((node: SiteEntry) => {
|
|
||||||
this.navigate(node.entry.guid);
|
|
||||||
}),
|
|
||||||
|
|
||||||
this.breakpointObserver
|
this.breakpointObserver
|
||||||
.observe([Breakpoints.HandsetPortrait, Breakpoints.HandsetLandscape])
|
.observe([Breakpoints.HandsetPortrait, Breakpoints.HandsetLandscape])
|
||||||
@@ -101,15 +92,6 @@ export class LibrariesComponent extends PageComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
navigate(libraryId: string) {
|
navigate(libraryId: string) {
|
||||||
if (libraryId) {
|
this.store.dispatch(new NavigateLibraryAction(libraryId));
|
||||||
this.contentApi
|
|
||||||
.getNode(libraryId, { relativePath: '/documentLibrary' })
|
|
||||||
.pipe(map(node => node.entry))
|
|
||||||
.subscribe(documentLibrary => {
|
|
||||||
this.router.navigate(['./', documentLibrary.id], {
|
|
||||||
relativeTo: this.route
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<div class="sidenav">
|
<div class="sidenav">
|
||||||
<div class="sidenav__section sidenav__section sidenav_action-menu">
|
<div class="sidenav__section sidenav__section sidenav_action-menu">
|
||||||
<app-create-menu [showLabel]="showLabel"></app-create-menu>
|
<app-create-menu [expanded]="showLabel"></app-create-menu>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngFor="let group of groups; trackBy: trackById"
|
<div *ngFor="let group of groups; trackBy: trackById"
|
||||||
|
|||||||
@@ -1,3 +1,30 @@
|
|||||||
|
<ng-container [ngSwitch]="actionRef.type">
|
||||||
|
|
||||||
|
<ng-container *ngSwitchCase="'menu'">
|
||||||
|
<button
|
||||||
|
mat-menu-item
|
||||||
|
[disabled]="actionRef.disabled"
|
||||||
|
[matMenuTriggerFor]="childMenu">
|
||||||
|
<mat-icon>{{ actionRef.icon }}</mat-icon>
|
||||||
|
<span>{{ actionRef.title | translate }}</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<mat-menu #childMenu="matMenu" class="app-create-menu__sub-menu">
|
||||||
|
<ng-container *ngFor="let child of actionRef.children; trackBy: trackById">
|
||||||
|
<app-toolbar-menu-item [actionRef]="child"></app-toolbar-menu-item>
|
||||||
|
</ng-container>
|
||||||
|
</mat-menu>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngSwitchCase="'separator'">
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngSwitchCase="'custom'">
|
||||||
|
<adf-dynamic-component [id]="actionRef.component"></adf-dynamic-component>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngSwitchDefault>
|
||||||
<button
|
<button
|
||||||
[id]="actionRef.id"
|
[id]="actionRef.id"
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
@@ -12,3 +39,8 @@
|
|||||||
<mat-icon>{{ actionRef.icon }}</mat-icon>
|
<mat-icon>{{ actionRef.icon }}</mat-icon>
|
||||||
<span>{{ actionRef.title | translate }}</span>
|
<span>{{ actionRef.title | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -51,4 +51,8 @@ export class ToolbarMenuItemComponent {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trackById(index: number, obj: { id: string }) {
|
||||||
|
return obj.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,7 +196,8 @@ export class AppExtensionService implements RuleContext {
|
|||||||
|
|
||||||
getCreateActions(): Array<ContentActionRef> {
|
getCreateActions(): Array<ContentActionRef> {
|
||||||
return this.createActions
|
return this.createActions
|
||||||
.filter(action => this.filterByRules(action))
|
.map(action => this.copyAction(action))
|
||||||
|
.map(action => this.buildMenu(action))
|
||||||
.map(action => {
|
.map(action => {
|
||||||
let disabled = false;
|
let disabled = false;
|
||||||
|
|
||||||
@@ -211,6 +212,39 @@ export class AppExtensionService implements RuleContext {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private buildMenu(actionRef: ContentActionRef): ContentActionRef {
|
||||||
|
if (
|
||||||
|
actionRef.type === ContentActionType.menu &&
|
||||||
|
actionRef.children &&
|
||||||
|
actionRef.children.length > 0
|
||||||
|
) {
|
||||||
|
const children = actionRef.children
|
||||||
|
.filter(action => this.filterByRules(action))
|
||||||
|
.map(action => this.buildMenu(action));
|
||||||
|
|
||||||
|
actionRef.children = children
|
||||||
|
.map(action => {
|
||||||
|
let disabled = false;
|
||||||
|
|
||||||
|
if (action.rules && action.rules.enabled) {
|
||||||
|
disabled = !this.extensions.evaluateRule(
|
||||||
|
action.rules.enabled,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...action,
|
||||||
|
disabled
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.reduce(reduceEmptyMenus, [])
|
||||||
|
.reduce(reduceSeparators, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
return actionRef;
|
||||||
|
}
|
||||||
|
|
||||||
// evaluates content actions for the selection and parent folder node
|
// evaluates content actions for the selection and parent folder node
|
||||||
getAllowedToolbarActions(): Array<ContentActionRef> {
|
getAllowedToolbarActions(): Array<ContentActionRef> {
|
||||||
return this.toolbarActions
|
return this.toolbarActions
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ export class ContentManagementService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
createLibrary() {
|
createLibrary(): Observable<SiteEntry> {
|
||||||
const dialogInstance = this.dialogRef.open(LibraryDialogComponent, {
|
const dialogInstance = this.dialogRef.open(LibraryDialogComponent, {
|
||||||
width: '400px'
|
width: '400px'
|
||||||
});
|
});
|
||||||
@@ -243,11 +243,9 @@ export class ContentManagementService {
|
|||||||
this.store.dispatch(new SnackbarErrorAction(message));
|
this.store.dispatch(new SnackbarErrorAction(message));
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogInstance.afterClosed().subscribe((node: SiteEntry) => {
|
return dialogInstance
|
||||||
if (node) {
|
.afterClosed()
|
||||||
this.libraryCreated.next(node);
|
.pipe(tap(node => this.libraryCreated.next(node)));
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteLibrary(id: string): void {
|
deleteLibrary(id: string): void {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import { Action } from '@ngrx/store';
|
|||||||
|
|
||||||
export const DELETE_LIBRARY = 'DELETE_LIBRARY';
|
export const DELETE_LIBRARY = 'DELETE_LIBRARY';
|
||||||
export const CREATE_LIBRARY = 'CREATE_LIBRARY';
|
export const CREATE_LIBRARY = 'CREATE_LIBRARY';
|
||||||
|
export const NAVIGATE_LIBRARY = 'NAVIGATE_LIBRARY';
|
||||||
|
|
||||||
export class DeleteLibraryAction implements Action {
|
export class DeleteLibraryAction implements Action {
|
||||||
readonly type = DELETE_LIBRARY;
|
readonly type = DELETE_LIBRARY;
|
||||||
@@ -37,3 +38,8 @@ export class CreateLibraryAction implements Action {
|
|||||||
readonly type = CREATE_LIBRARY;
|
readonly type = CREATE_LIBRARY;
|
||||||
constructor() {}
|
constructor() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class NavigateLibraryAction implements Action {
|
||||||
|
readonly type = NAVIGATE_LIBRARY;
|
||||||
|
constructor(public payload?: string) {}
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import {
|
|||||||
DownloadEffects,
|
DownloadEffects,
|
||||||
ViewerEffects,
|
ViewerEffects,
|
||||||
SearchEffects,
|
SearchEffects,
|
||||||
SiteEffects,
|
LibraryEffects,
|
||||||
UploadEffects,
|
UploadEffects,
|
||||||
FavoriteEffects,
|
FavoriteEffects,
|
||||||
ModalsEffects
|
ModalsEffects
|
||||||
@@ -57,7 +57,7 @@ import {
|
|||||||
DownloadEffects,
|
DownloadEffects,
|
||||||
ViewerEffects,
|
ViewerEffects,
|
||||||
SearchEffects,
|
SearchEffects,
|
||||||
SiteEffects,
|
LibraryEffects,
|
||||||
UploadEffects,
|
UploadEffects,
|
||||||
FavoriteEffects,
|
FavoriteEffects,
|
||||||
ModalsEffects
|
ModalsEffects
|
||||||
|
|||||||
@@ -25,24 +25,30 @@
|
|||||||
|
|
||||||
import { Effect, Actions, ofType } from '@ngrx/effects';
|
import { Effect, Actions, ofType } from '@ngrx/effects';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { map, take } from 'rxjs/operators';
|
import { map, take, switchMap } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
DeleteLibraryAction,
|
DeleteLibraryAction,
|
||||||
DELETE_LIBRARY,
|
DELETE_LIBRARY,
|
||||||
CreateLibraryAction,
|
CreateLibraryAction,
|
||||||
CREATE_LIBRARY
|
CREATE_LIBRARY,
|
||||||
|
NavigateLibraryAction,
|
||||||
|
NAVIGATE_LIBRARY
|
||||||
} from '../actions';
|
} from '../actions';
|
||||||
import { ContentManagementService } from '../../services/content-management.service';
|
import { ContentManagementService } from '../../services/content-management.service';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { AppStore } from '../states';
|
import { AppStore } from '../states';
|
||||||
import { appSelection } from '../selectors/app.selectors';
|
import { appSelection } from '../selectors/app.selectors';
|
||||||
|
import { ContentApiService } from '../../services/content-api.service';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SiteEffects {
|
export class LibraryEffects {
|
||||||
constructor(
|
constructor(
|
||||||
private store: Store<AppStore>,
|
private store: Store<AppStore>,
|
||||||
private actions$: Actions,
|
private actions$: Actions,
|
||||||
private content: ContentManagementService
|
private content: ContentManagementService,
|
||||||
|
private contentApi: ContentApiService,
|
||||||
|
private router: Router
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Effect({ dispatch: false })
|
@Effect({ dispatch: false })
|
||||||
@@ -64,11 +70,26 @@ export class SiteEffects {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@Effect({ dispatch: false })
|
@Effect()
|
||||||
createLibrary$ = this.actions$.pipe(
|
createLibrary$ = this.actions$.pipe(
|
||||||
ofType<CreateLibraryAction>(CREATE_LIBRARY),
|
ofType<CreateLibraryAction>(CREATE_LIBRARY),
|
||||||
|
switchMap(() => this.content.createLibrary()),
|
||||||
|
map(node => new NavigateLibraryAction(node.entry.guid))
|
||||||
|
);
|
||||||
|
|
||||||
|
@Effect({ dispatch: false })
|
||||||
|
navigateLibrary$ = this.actions$.pipe(
|
||||||
|
ofType<NavigateLibraryAction>(NAVIGATE_LIBRARY),
|
||||||
map(action => {
|
map(action => {
|
||||||
this.content.createLibrary();
|
const libraryId = action.payload;
|
||||||
|
if (libraryId) {
|
||||||
|
this.contentApi
|
||||||
|
.getNode(libraryId, { relativePath: '/documentLibrary' })
|
||||||
|
.pipe(map(node => node.entry))
|
||||||
|
.subscribe(documentLibrary => {
|
||||||
|
this.router.navigate(['libraries', documentLibrary.id]);
|
||||||
|
});
|
||||||
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,12 @@
|
|||||||
@import '../components/permissions/permission-manager/permission-manager.component.theme';
|
@import '../components/permissions/permission-manager/permission-manager.component.theme';
|
||||||
@import '../components/context-menu/context-menu.component.theme';
|
@import '../components/context-menu/context-menu.component.theme';
|
||||||
@import '../dialogs/node-versions/node-versions.dialog.theme';
|
@import '../dialogs/node-versions/node-versions.dialog.theme';
|
||||||
|
@import '../components/create-menu/create-menu.component.scss';
|
||||||
|
|
||||||
@import './overrides/adf-toolbar.theme';
|
@import './overrides/adf-toolbar.theme';
|
||||||
@import './overrides/adf-search-filter.theme';
|
@import './overrides/adf-search-filter.theme';
|
||||||
@import './overrides/adf-info-drawer.theme';
|
@import './overrides/adf-info-drawer.theme';
|
||||||
@import './overrides/adf-upload-button.theme';
|
@import './overrides/adf-upload-button.theme';
|
||||||
@import './overrides/adf-sidebar-action-menu.theme';
|
|
||||||
@import './overrides/adf-upload-dialog.theme';
|
@import './overrides/adf-upload-dialog.theme';
|
||||||
@import './overrides/adf-pagination.theme';
|
@import './overrides/adf-pagination.theme';
|
||||||
@import './overrides/adf-sidenav-layout.theme';
|
@import './overrides/adf-sidenav-layout.theme';
|
||||||
@@ -74,7 +74,6 @@ $custom-theme: mat-light-theme($custom-theme-primary, $custom-theme-accent);
|
|||||||
@include adf-search-filter-theme($theme);
|
@include adf-search-filter-theme($theme);
|
||||||
@include adf-info-drawer-theme($theme);
|
@include adf-info-drawer-theme($theme);
|
||||||
@include adf-upload-button-theme($theme);
|
@include adf-upload-button-theme($theme);
|
||||||
@include adf-sidebar-action-menu-theme($theme);
|
|
||||||
@include adf-pagination-theme($theme);
|
@include adf-pagination-theme($theme);
|
||||||
@include adf-sidenav-layout-theme($theme);
|
@include adf-sidenav-layout-theme($theme);
|
||||||
@include adf-document-list-theme($theme);
|
@include adf-document-list-theme($theme);
|
||||||
@@ -95,4 +94,5 @@ $custom-theme: mat-light-theme($custom-theme-primary, $custom-theme-accent);
|
|||||||
@include aca-about-component-theme($theme);
|
@include aca-about-component-theme($theme);
|
||||||
@include aca-current-user-theme($theme);
|
@include aca-current-user-theme($theme);
|
||||||
@include aca-context-menu-theme($theme);
|
@include aca-context-menu-theme($theme);
|
||||||
|
@include app-create-menu-theme($theme);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
@mixin adf-sidebar-action-menu-theme($theme) {
|
|
||||||
$foreground: map-get($theme, foreground);
|
|
||||||
$accent: map-get($theme, accent);
|
|
||||||
$primary: map-get($theme, primary);
|
|
||||||
|
|
||||||
.adf-sidebar-action-menu {
|
|
||||||
.adf-sidebar-action-menu-button {
|
|
||||||
font-size: 12.7px;
|
|
||||||
font-weight: normal;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mat-menu-panel.adf-sidebar-action-menu-panel {
|
|
||||||
max-width: 290px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.adf-sidebar-action-menu-panel {
|
|
||||||
width: 290px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.adf-sidebar-action-menu-panel .mat-menu-content {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.adf-sidebar-action-menu-icon {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.adf-sidebar-action-menu-icon div[sidebar-menu-expand-icon] {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.adf-sidebar-action-menu {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.adf-sidebar-action-menu-options {
|
|
||||||
width: 100% !important;
|
|
||||||
|
|
||||||
.mat-menu-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 14px;
|
|
||||||
color: mat-color($foreground, text, 0.54);
|
|
||||||
line-height: 48px;
|
|
||||||
box-shadow: none;
|
|
||||||
transform: none;
|
|
||||||
transition: unset;
|
|
||||||
font-weight: normal;
|
|
||||||
text-transform: capitalize;
|
|
||||||
color: mat-color($primary);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: mat-color($accent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mat-menu-item[disabled],
|
|
||||||
.mat-menu-item[disabled]:hover {
|
|
||||||
color: mat-color($foreground, text, 0.38);
|
|
||||||
|
|
||||||
.mat-icon {
|
|
||||||
color: mat-color($foreground, text, 0.38);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,12 @@
|
|||||||
"$schema": "../../extension.schema.json",
|
"$schema": "../../extension.schema.json",
|
||||||
"$name": "app",
|
"$name": "app",
|
||||||
"$version": "1.0.0",
|
"$version": "1.0.0",
|
||||||
"$references": ["plugin1.json", "dev.tools.json", "app.header.json"],
|
"$references": [
|
||||||
|
"plugin1.json",
|
||||||
|
"dev.tools.json",
|
||||||
|
"app.header.json",
|
||||||
|
"app.create.json"
|
||||||
|
],
|
||||||
|
|
||||||
"rules": [
|
"rules": [
|
||||||
{
|
{
|
||||||
@@ -132,23 +137,9 @@
|
|||||||
|
|
||||||
"features": {
|
"features": {
|
||||||
"create": [
|
"create": [
|
||||||
{
|
|
||||||
"id": "app.create.folder",
|
|
||||||
"order": 100,
|
|
||||||
"icon": "create_new_folder",
|
|
||||||
"title": "APP.NEW_MENU.MENU_ITEMS.CREATE_FOLDER",
|
|
||||||
"description": "APP.NEW_MENU.TOOLTIPS.CREATE_FOLDER",
|
|
||||||
"description-disabled": "APP.NEW_MENU.TOOLTIPS.CREATE_FOLDER_NOT_ALLOWED",
|
|
||||||
"actions": {
|
|
||||||
"click": "CREATE_FOLDER"
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"enabled": "app.navigation.folder.canCreate"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "app.create.uploadFile",
|
"id": "app.create.uploadFile",
|
||||||
"order": 200,
|
"order": 100,
|
||||||
"icon": "file_upload",
|
"icon": "file_upload",
|
||||||
"title": "APP.NEW_MENU.MENU_ITEMS.UPLOAD_FILE",
|
"title": "APP.NEW_MENU.MENU_ITEMS.UPLOAD_FILE",
|
||||||
"description": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FILES",
|
"description": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FILES",
|
||||||
@@ -162,7 +153,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "app.create.uploadFolder",
|
"id": "app.create.uploadFolder",
|
||||||
"order": 300,
|
"order": 200,
|
||||||
"icon": "file_upload",
|
"icon": "file_upload",
|
||||||
"title": "APP.NEW_MENU.MENU_ITEMS.UPLOAD_FOLDER",
|
"title": "APP.NEW_MENU.MENU_ITEMS.UPLOAD_FOLDER",
|
||||||
"description": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FOLDERS",
|
"description": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FOLDERS",
|
||||||
@@ -173,6 +164,35 @@
|
|||||||
"rules": {
|
"rules": {
|
||||||
"enabled": "app.navigation.folder.canUpload"
|
"enabled": "app.navigation.folder.canUpload"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.create.separator.1",
|
||||||
|
"type": "separator",
|
||||||
|
"order": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.create.folder",
|
||||||
|
"order": 400,
|
||||||
|
"icon": "create_new_folder",
|
||||||
|
"title": "APP.NEW_MENU.MENU_ITEMS.CREATE_FOLDER",
|
||||||
|
"description": "APP.NEW_MENU.TOOLTIPS.CREATE_FOLDER",
|
||||||
|
"description-disabled": "APP.NEW_MENU.TOOLTIPS.CREATE_FOLDER_NOT_ALLOWED",
|
||||||
|
"actions": {
|
||||||
|
"click": "CREATE_FOLDER"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"enabled": "app.navigation.folder.canCreate"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.create.library",
|
||||||
|
"order": 600,
|
||||||
|
"title": "APP.NEW_MENU.MENU_ITEMS.CREATE_LIBRARY",
|
||||||
|
"description": "APP.NEW_MENU.TOOLTIPS.CREATE_LIBRARY",
|
||||||
|
"icon": "create_new_folder",
|
||||||
|
"actions": {
|
||||||
|
"click": "CREATE_LIBRARY"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"navbar": [
|
"navbar": [
|
||||||
@@ -296,18 +316,6 @@
|
|||||||
"visible": "app.trashcan.hasSelection"
|
"visible": "app.trashcan.hasSelection"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "app.toolbar.createLibrary",
|
|
||||||
"order": 600,
|
|
||||||
"title": "Create Library",
|
|
||||||
"icon": "create_new_folder",
|
|
||||||
"actions": {
|
|
||||||
"click": "CREATE_LIBRARY"
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"visible": "app.navigation.isLibraries"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "app.toolbar.info",
|
"id": "app.toolbar.info",
|
||||||
"type": "custom",
|
"type": "custom",
|
||||||
|
|||||||
@@ -22,7 +22,8 @@
|
|||||||
"MENU_ITEMS": {
|
"MENU_ITEMS": {
|
||||||
"CREATE_FOLDER": "Create folder",
|
"CREATE_FOLDER": "Create folder",
|
||||||
"UPLOAD_FILE": "Upload file",
|
"UPLOAD_FILE": "Upload file",
|
||||||
"UPLOAD_FOLDER": "Upload folder"
|
"UPLOAD_FOLDER": "Upload folder",
|
||||||
|
"CREATE_LIBRARY": "Create Library"
|
||||||
},
|
},
|
||||||
"TOOLTIPS": {
|
"TOOLTIPS": {
|
||||||
"CREATE_FOLDER": "Create new folder",
|
"CREATE_FOLDER": "Create new folder",
|
||||||
@@ -30,7 +31,8 @@
|
|||||||
"UPLOAD_FILES": "Select files to upload",
|
"UPLOAD_FILES": "Select files to upload",
|
||||||
"UPLOAD_FILES_NOT_ALLOWED": "Files cannot be uploaded whilst viewing the current items",
|
"UPLOAD_FILES_NOT_ALLOWED": "Files cannot be uploaded whilst viewing the current items",
|
||||||
"UPLOAD_FOLDERS": "Select folders to upload",
|
"UPLOAD_FOLDERS": "Select folders to upload",
|
||||||
"UPLOAD_FOLDERS_NOT_ALLOWED": "Folders cannot be uploaded whilst viewing the current items"
|
"UPLOAD_FOLDERS_NOT_ALLOWED": "Folders cannot be uploaded whilst viewing the current items",
|
||||||
|
"CREATE_LIBRARY": "Create a new File Library"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"BROWSE": {
|
"BROWSE": {
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../../../extension.schema.json",
|
||||||
|
"$name": "app.create",
|
||||||
|
"$version": "1.0.0",
|
||||||
|
|
||||||
|
|
||||||
|
"features": {
|
||||||
|
"create": [
|
||||||
|
{
|
||||||
|
"id": "app.test.create1",
|
||||||
|
"order": 10,
|
||||||
|
"icon": "extension",
|
||||||
|
"title": "Custom Create",
|
||||||
|
"type": "menu",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"id": "level1.1",
|
||||||
|
"icon": "extension",
|
||||||
|
"title": "Level 1.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "level1.separator",
|
||||||
|
"type": "separator"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "level1.2",
|
||||||
|
"icon": "extension",
|
||||||
|
"title": "Level 1.2",
|
||||||
|
"type": "menu",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"id": "level2.1",
|
||||||
|
"icon": "extension",
|
||||||
|
"title": "Level 2.1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"enabled": "app.navigation.folder.canCreate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.create.separator",
|
||||||
|
"order": 20,
|
||||||
|
"type": "separator"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-2
@@ -3,9 +3,10 @@
|
|||||||
@import '~@alfresco/adf-core/prebuilt-themes/adf-blue-orange.css';
|
@import '~@alfresco/adf-core/prebuilt-themes/adf-blue-orange.css';
|
||||||
@import 'app/ui/application';
|
@import 'app/ui/application';
|
||||||
|
|
||||||
body, html {
|
body,
|
||||||
|
html {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-family: 'Muli', "Helvetica", "Arial", sans-serif !important;
|
font-family: 'Muli', 'Helvetica', 'Arial', sans-serif !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|||||||
Reference in New Issue
Block a user