mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
57053: added menu preview
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<li class="sidebar-section">
|
<li class="sidebar-section">
|
||||||
<a class="nav-item nav-link shortcut-icon">
|
<a class="nav-item nav-link shortcut-icon" [routerLink]="section.model.link">
|
||||||
<i class="fas fa-{{section.icon}} fa-fw"></i>
|
<i class="fas fa-{{section.icon}} fa-fw"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="sidebar-collapsible">
|
<div class="sidebar-collapsible">
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
<nav @slideHorizontal class="navbar navbar-dark bg-dark p-0"
|
<nav @slideHorizontal class="navbar navbar-dark bg-dark p-0"
|
||||||
[ngClass]="{'active': sidebarOpen, 'inactive': sidebarClosed}"
|
[ngClass]="{'active': sidebarOpen, 'inactive': sidebarClosed}"
|
||||||
[@slideSidebar]="{
|
[@slideSidebar]="{
|
||||||
value: ((menuCollapsed | async) ? 'collapsed' : 'expanded'),
|
value: (!(sidebarExpanded | async) ? 'collapsed' : 'expanded'),
|
||||||
params: {sidebarWidth: (sidebarWidth | async)}
|
params: {sidebarWidth: (sidebarWidth | async)}
|
||||||
}" (@slideSidebar.done)="finishSlide($event)" (@slideSidebar.start)="startSlide($event)" *ngIf="menuVisible | async">
|
}" (@slideSidebar.done)="finishSlide($event)" (@slideSidebar.start)="startSlide($event)" *ngIf="menuVisible | async" (mouseenter)="expandPreview($event)" (mouseleave)="collapsePreview($event)">
|
||||||
<div class="sidebar-top-level-items">
|
<div class="sidebar-top-level-items">
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
<li class="admin-menu-header sidebar-section">
|
<li class="admin-menu-header sidebar-section">
|
||||||
@@ -30,8 +30,7 @@
|
|||||||
<a class="nav-item nav-link shortcut-icon"
|
<a class="nav-item nav-link shortcut-icon"
|
||||||
href="#"
|
href="#"
|
||||||
(click)="toggle($event)">
|
(click)="toggle($event)">
|
||||||
<i class="fas fa-fw fa-angle-double-right"
|
<i class="fas fa-fw" [ngClass]="{'fa-angle-double-right': (menuCollapsed | async), 'fa-angle-double-left': !(menuCollapsed | async)}"></i>
|
||||||
[ngClass]="{'fa-angle-double-right': (menuCollapsed | async), 'fa-angle-double-left': !(menuCollapsed | async)}"></i>
|
|
||||||
</a>
|
</a>
|
||||||
<div class="sidebar-collapsible">
|
<div class="sidebar-collapsible">
|
||||||
<a class="nav-item nav-link sidebar-section"
|
<a class="nav-item nav-link sidebar-section"
|
||||||
|
@@ -20,7 +20,7 @@ $icon-z-index: 10;
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.inactive ::ng-deep .sidebar-collapsible {
|
&.inactive ::ng-deep .sidebar-collapsible {
|
||||||
margin-left: -#{$admin-sidebar-width};
|
margin-left: -#{$sidebar-items-width};
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-nav {
|
.navbar-nav {
|
||||||
@@ -58,7 +58,7 @@ $icon-z-index: 10;
|
|||||||
z-index: $icon-z-index;
|
z-index: $icon-z-index;
|
||||||
}
|
}
|
||||||
.sidebar-collapsible {
|
.sidebar-collapsible {
|
||||||
width: $admin-sidebar-width;
|
width: $sidebar-items-width;
|
||||||
position: relative;
|
position: relative;
|
||||||
a {
|
a {
|
||||||
padding-right: $spacer;
|
padding-right: $spacer;
|
||||||
@@ -69,10 +69,6 @@ $icon-z-index: 10;
|
|||||||
color: $navbar-dark-active-color;
|
color: $navbar-dark-active-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar-collapse-toggle {
|
|
||||||
border-top: 2px solid rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,7 +8,8 @@ import { MenuComponent } from '../../shared/menu/menu.component';
|
|||||||
import { TextSectionTypeModel } from '../../shared/menu/models/section-types/text.model';
|
import { TextSectionTypeModel } from '../../shared/menu/models/section-types/text.model';
|
||||||
import { LinkSectionTypeModel } from '../../shared/menu/models/section-types/link.model';
|
import { LinkSectionTypeModel } from '../../shared/menu/models/section-types/link.model';
|
||||||
import { AuthService } from '../../core/auth/auth.service';
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
import { first } from 'rxjs/operators';
|
import { first, map } from 'rxjs/operators';
|
||||||
|
import { combineLatest as combineLatestObservable } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-admin-sidebar',
|
selector: 'ds-admin-sidebar',
|
||||||
@@ -19,8 +20,9 @@ import { first } from 'rxjs/operators';
|
|||||||
export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
||||||
menuID = MenuID.ADMIN;
|
menuID = MenuID.ADMIN;
|
||||||
sidebarWidth: Observable<string>;
|
sidebarWidth: Observable<string>;
|
||||||
sidebarOpen = true;
|
sidebarOpen = true; // Open in UI, animation finished
|
||||||
sidebarClosed = !this.sidebarOpen;
|
sidebarClosed = !this.sidebarOpen; // Closed in UI, animation finished
|
||||||
|
sidebarExpanded: Observable<boolean>;
|
||||||
|
|
||||||
constructor(protected menuService: MenuService,
|
constructor(protected menuService: MenuService,
|
||||||
protected injector: Injector,
|
protected injector: Injector,
|
||||||
@@ -33,7 +35,7 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.createMenu();
|
this.createMenu();
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
this.sidebarWidth = this.variableService.getVariable('adminSidebarWidth');
|
this.sidebarWidth = this.variableService.getVariable('sidebarItemsWidth');
|
||||||
this.authService.isAuthenticated()
|
this.authService.isAuthenticated()
|
||||||
.subscribe((loggedIn: boolean) => {
|
.subscribe((loggedIn: boolean) => {
|
||||||
if (loggedIn) {
|
if (loggedIn) {
|
||||||
@@ -44,7 +46,11 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
|||||||
.subscribe((collapsed: boolean) => {
|
.subscribe((collapsed: boolean) => {
|
||||||
this.sidebarOpen = !collapsed;
|
this.sidebarOpen = !collapsed;
|
||||||
this.sidebarClosed = collapsed;
|
this.sidebarClosed = collapsed;
|
||||||
})
|
});
|
||||||
|
this.sidebarExpanded = combineLatestObservable(this.menuCollapsed, this.menuPreviewCollapsed)
|
||||||
|
.pipe(
|
||||||
|
map(([collapsed, previewCollapsed]) => (!collapsed || !previewCollapsed))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
createMenu() {
|
createMenu() {
|
||||||
@@ -431,5 +437,4 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
|||||||
this.sidebarOpen = true;
|
this.sidebarOpen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<li class="sidebar-section" [ngClass]="{'active': (active | async)}"
|
<li class="sidebar-section" [ngClass]="{'expanded': (expanded | async)}"
|
||||||
[@bgColor]="{
|
[@bgColor]="{
|
||||||
value: ((active | async) ? 'endBackground' : 'startBackground'),
|
value: ((expanded | async) ? 'endBackground' : 'startBackground'),
|
||||||
params: {endColor: (sidebarActiveBg | async)}}">
|
params: {endColor: (sidebarActiveBg | async)}}">
|
||||||
<div class="icon-wrapper">
|
<div class="icon-wrapper">
|
||||||
<a class="nav-item nav-link shortcut-icon" (click)="toggleSection($event)" href="#">
|
<a class="nav-item nav-link shortcut-icon" (click)="toggleSection($event)" href="#">
|
||||||
@@ -15,9 +15,9 @@
|
|||||||
*ngComponentOutlet="itemComponents.get(section.id); injector: itemInjectors.get(section.id);"></ng-container>
|
*ngComponentOutlet="itemComponents.get(section.id); injector: itemInjectors.get(section.id);"></ng-container>
|
||||||
</span>
|
</span>
|
||||||
<i class="fas fa-chevron-right fa-pull-right"
|
<i class="fas fa-chevron-right fa-pull-right"
|
||||||
[@rotate]="(active | async) ? 'expanded' : 'collapsed'"></i>
|
[@rotate]="(expanded | async) ? 'expanded' : 'collapsed'"></i>
|
||||||
</a>
|
</a>
|
||||||
<ul class="sidebar-sub-level-items list-unstyled" @slide *ngIf="(active | async)">
|
<ul class="sidebar-sub-level-items list-unstyled" @slide *ngIf="(expanded | async)">
|
||||||
<li *ngFor="let subSection of (subSections | async)">
|
<li *ngFor="let subSection of (subSections | async)">
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngComponentOutlet="itemComponents.get(subSection.id); injector: itemInjectors.get(subSection.id);"></ng-container>
|
*ngComponentOutlet="itemComponents.get(subSection.id); injector: itemInjectors.get(subSection.id);"></ng-container>
|
||||||
|
@@ -9,6 +9,8 @@ import { rendersSectionForMenu } from '../../../shared/menu/menu.decorator';
|
|||||||
import { MenuService } from '../../../shared/menu/menu.service';
|
import { MenuService } from '../../../shared/menu/menu.service';
|
||||||
import { MenuSection } from '../../../shared/menu/menu.reducer';
|
import { MenuSection } from '../../../shared/menu/menu.reducer';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { combineLatest as combineLatestObservable } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-expandable-admin-sidebar-section',
|
selector: 'ds-expandable-admin-sidebar-section',
|
||||||
@@ -23,6 +25,8 @@ export class ExpandableAdminSidebarSectionComponent extends AdminSidebarSectionC
|
|||||||
menuID = MenuID.ADMIN;
|
menuID = MenuID.ADMIN;
|
||||||
sidebarActiveBg;
|
sidebarActiveBg;
|
||||||
sidebarCollapsed: Observable<boolean>;
|
sidebarCollapsed: Observable<boolean>;
|
||||||
|
sidebarPreviewCollapsed: Observable<boolean>;
|
||||||
|
expanded: Observable<boolean>;
|
||||||
|
|
||||||
constructor(@Inject('sectionDataProvider') menuSection, protected menuService: MenuService,
|
constructor(@Inject('sectionDataProvider') menuSection, protected menuService: MenuService,
|
||||||
private variableService: CSSVariableService, protected injector: Injector) {
|
private variableService: CSSVariableService, protected injector: Injector) {
|
||||||
@@ -35,5 +39,10 @@ export class ExpandableAdminSidebarSectionComponent extends AdminSidebarSectionC
|
|||||||
this.subSections = this.menuService.getSubSectionsByParentID(this.menuID, this.section.id);
|
this.subSections = this.menuService.getSubSectionsByParentID(this.menuID, this.section.id);
|
||||||
this.sidebarActiveBg = this.variableService.getVariable('adminSidebarActiveBg');
|
this.sidebarActiveBg = this.variableService.getVariable('adminSidebarActiveBg');
|
||||||
this.sidebarCollapsed = this.menuService.isMenuCollapsed(this.menuID);
|
this.sidebarCollapsed = this.menuService.isMenuCollapsed(this.menuID);
|
||||||
|
this.sidebarPreviewCollapsed = this.menuService.isMenuPreviewCollapsed(this.menuID);
|
||||||
|
this.expanded = combineLatestObservable(this.active, this.sidebarCollapsed, this.sidebarPreviewCollapsed)
|
||||||
|
.pipe(
|
||||||
|
map(([active, sidebarCollapsed, sidebarPreviewCollapsed]) => (active && (!sidebarCollapsed || !sidebarPreviewCollapsed)))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<div class="outer-wrapper">
|
<div class="outer-wrapper">
|
||||||
<ds-admin-sidebar></ds-admin-sidebar>
|
<ds-admin-sidebar></ds-admin-sidebar>
|
||||||
<div class="inner-wrapper" [@slideSidebarMargin]="{
|
<div class="inner-wrapper" [@slideSidebarPadding]="{
|
||||||
value: ((hasAdminSidebar | async) ? 'expanded' : 'collapsed'),
|
value: (!(sidebarVisible | async) ? 'hidden' : (sidebarCollapsed | async) ? 'shown' : 'expanded'),
|
||||||
params: {collapsedSidebarWidth: (collapsedSidebarWidth | async)}
|
params: {collapsedSidebarWidth: (collapsedSidebarWidth | async), totalSidebarWidth: (totalSidebarWidth | async)}
|
||||||
}">
|
}">
|
||||||
<ds-header-navbar-wrapper></ds-header-navbar-wrapper>
|
<ds-header-navbar-wrapper></ds-header-navbar-wrapper>
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@ body {
|
|||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-content {
|
.main-content {
|
||||||
@@ -39,7 +40,7 @@ ds-header-navbar-wrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ds-admin-sidebar {
|
ds-admin-sidebar {
|
||||||
position: absolute;
|
position: fixed;
|
||||||
z-index: $sidebar-z-index;
|
z-index: $sidebar-z-index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@ import { CSSVariableService } from './shared/sass-helper/sass-helper.service';
|
|||||||
import { MenuService } from './shared/menu/menu.service';
|
import { MenuService } from './shared/menu/menu.service';
|
||||||
import { MenuID } from './shared/menu/initial-menus-state';
|
import { MenuID } from './shared/menu/initial-menus-state';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { slideSidebarMargin } from './shared/animations/slide';
|
import { slideSidebarPadding } from './shared/animations/slide';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-app',
|
selector: 'ds-app',
|
||||||
@@ -36,12 +36,14 @@ import { slideSidebarMargin } from './shared/animations/slide';
|
|||||||
styleUrls: ['./app.component.scss'],
|
styleUrls: ['./app.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
encapsulation: ViewEncapsulation.None,
|
encapsulation: ViewEncapsulation.None,
|
||||||
animations: [slideSidebarMargin]
|
animations: [slideSidebarPadding]
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit, AfterViewInit {
|
export class AppComponent implements OnInit, AfterViewInit {
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
hasAdminSidebar: Observable<boolean>;
|
sidebarVisible: Observable<boolean>;
|
||||||
|
sidebarCollapsed: Observable<boolean>;
|
||||||
collapsedSidebarWidth: Observable<string>;
|
collapsedSidebarWidth: Observable<string>;
|
||||||
|
totalSidebarWidth: Observable<string>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(GLOBAL_CONFIG) public config: GlobalConfig,
|
@Inject(GLOBAL_CONFIG) public config: GlobalConfig,
|
||||||
@@ -80,9 +82,11 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||||||
first(),
|
first(),
|
||||||
filter((authenticated) => !authenticated)
|
filter((authenticated) => !authenticated)
|
||||||
).subscribe((authenticated) => this.authService.checkAuthenticationToken());
|
).subscribe((authenticated) => this.authService.checkAuthenticationToken());
|
||||||
this.hasAdminSidebar = this.menuService.isMenuVisible(MenuID.ADMIN);
|
this.sidebarVisible = this.menuService.isMenuVisible(MenuID.ADMIN);
|
||||||
|
this.sidebarCollapsed = this.menuService.isMenuCollapsed(MenuID.ADMIN);
|
||||||
|
|
||||||
this.collapsedSidebarWidth = this.cssService.getVariable('collapsedSidebarWidth');
|
this.collapsedSidebarWidth = this.cssService.getVariable('collapsedSidebarWidth');
|
||||||
|
this.totalSidebarWidth = this.cssService.getVariable('totalSidebarWidth');
|
||||||
}
|
}
|
||||||
|
|
||||||
private storeCSSVariables() {
|
private storeCSSVariables() {
|
||||||
|
@@ -9,7 +9,6 @@ nav.navbar {
|
|||||||
@media screen and (max-width: map-get($grid-breakpoints, md)) {
|
@media screen and (max-width: map-get($grid-breakpoints, md)) {
|
||||||
.navbar {
|
.navbar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
left: 0;
|
|
||||||
background-color: $white;
|
background-color: $white;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -37,7 +36,6 @@ nav.navbar {
|
|||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<div class="page-not-found">
|
<div class="page-not-found container">
|
||||||
<h1>404</h1>
|
<h1>404</h1>
|
||||||
<h2><small>{{"404.page-not-found" | translate}}</small></h2>
|
<h2><small>{{"404.page-not-found" | translate}}</small></h2>
|
||||||
<br/>
|
<br/>
|
||||||
|
@@ -59,8 +59,11 @@ export const slideSidebar = trigger('slideSidebar', [
|
|||||||
))
|
))
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const slideSidebarMargin = trigger('slideSidebarMargin', [
|
export const slideSidebarPadding = trigger('slideSidebarPadding', [
|
||||||
state('collapsed', style({ marginLeft: 0 })),
|
state('hidden', style({ paddingLeft: 0 })),
|
||||||
state('expanded', style({ marginLeft: '{{ collapsedSidebarWidth }}' }), { params: { collapsedSidebarWidth: '*' } }),
|
state('shown', style({ paddingLeft: '{{ collapsedSidebarWidth }}' }), { params: { collapsedSidebarWidth: '*' } }),
|
||||||
transition('collapsed <=> expanded', [animate('200ms')]),
|
state('expanded', style({ paddingLeft: '{{ totalSidebarWidth }}' }), { params: { totalSidebarWidth: '*' } }),
|
||||||
|
transition('hidden <=> shown', [animate('200ms')]),
|
||||||
|
transition('hidden <=> expanded', [animate('200ms')]),
|
||||||
|
transition('shown <=> expanded', [animate('200ms')]),
|
||||||
]);
|
]);
|
@@ -14,6 +14,7 @@ export const initialMenusState: MenusState = {
|
|||||||
{
|
{
|
||||||
id: MenuID.ADMIN,
|
id: MenuID.ADMIN,
|
||||||
collapsed: true,
|
collapsed: true,
|
||||||
|
previewCollapsed: true,
|
||||||
visible: false,
|
visible: false,
|
||||||
sections: {},
|
sections: {},
|
||||||
sectionToSubsectionIndex: {}
|
sectionToSubsectionIndex: {}
|
||||||
@@ -22,6 +23,7 @@ export const initialMenusState: MenusState = {
|
|||||||
{
|
{
|
||||||
id: MenuID.PUBLIC,
|
id: MenuID.PUBLIC,
|
||||||
collapsed: true,
|
collapsed: true,
|
||||||
|
previewCollapsed: true,
|
||||||
visible: true,
|
visible: true,
|
||||||
sections: {},
|
sections: {},
|
||||||
sectionToSubsectionIndex: {}
|
sectionToSubsectionIndex: {}
|
||||||
|
@@ -9,6 +9,8 @@ export const MenuActionTypes = {
|
|||||||
EXPAND_MENU: type('dspace/menu/EXPAND_MENU'),
|
EXPAND_MENU: type('dspace/menu/EXPAND_MENU'),
|
||||||
SHOW_MENU: type('dspace/menu/SHOW_MENU'),
|
SHOW_MENU: type('dspace/menu/SHOW_MENU'),
|
||||||
HIDE_MENU: type('dspace/menu/HIDE_MENU'),
|
HIDE_MENU: type('dspace/menu/HIDE_MENU'),
|
||||||
|
COLLAPSE_MENU_PREVIEW: type('dspace/menu/COLLAPSE_MENU_PREVIEW'),
|
||||||
|
EXPAND_MENU_PREVIEW: type('dspace/menu/EXPAND_MENU_PREVIEW'),
|
||||||
ADD_SECTION: type('dspace/menu-section/ADD_SECTION'),
|
ADD_SECTION: type('dspace/menu-section/ADD_SECTION'),
|
||||||
REMOVE_SECTION: type('dspace/menu-section/REMOVE_SECTION'),
|
REMOVE_SECTION: type('dspace/menu-section/REMOVE_SECTION'),
|
||||||
SHOW_SECTION: type('dspace/menu-section/SHOW_SECTION'),
|
SHOW_SECTION: type('dspace/menu-section/SHOW_SECTION'),
|
||||||
@@ -66,6 +68,25 @@ export class HideMenuAction implements Action {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class CollapseMenuPreviewAction implements Action {
|
||||||
|
type = MenuActionTypes.COLLAPSE_MENU_PREVIEW;
|
||||||
|
menuID: MenuID;
|
||||||
|
|
||||||
|
constructor(menuID: MenuID) {
|
||||||
|
this.menuID = menuID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ExpandMenuPreviewAction implements Action {
|
||||||
|
type = MenuActionTypes.EXPAND_MENU_PREVIEW;
|
||||||
|
menuID: MenuID;
|
||||||
|
|
||||||
|
constructor(menuID: MenuID) {
|
||||||
|
this.menuID = menuID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// MENU STRUCTURING ACTIONS
|
// MENU STRUCTURING ACTIONS
|
||||||
export abstract class MenuSectionAction implements Action {
|
export abstract class MenuSectionAction implements Action {
|
||||||
type;
|
type;
|
||||||
|
@@ -15,6 +15,7 @@ import { MenuSectionComponent } from './menu-section/menu-section.component';
|
|||||||
export class MenuComponent implements OnInit {
|
export class MenuComponent implements OnInit {
|
||||||
menuID: MenuID;
|
menuID: MenuID;
|
||||||
menuCollapsed: Observable<boolean>;
|
menuCollapsed: Observable<boolean>;
|
||||||
|
menuPreviewCollapsed: Observable<boolean>;
|
||||||
menuVisible: Observable<boolean>;
|
menuVisible: Observable<boolean>;
|
||||||
sections: Observable<MenuSection[]>;
|
sections: Observable<MenuSection[]>;
|
||||||
sectionInjectors: Map<string, Injector> = new Map<string, Injector>();
|
sectionInjectors: Map<string, Injector> = new Map<string, Injector>();
|
||||||
@@ -26,6 +27,7 @@ export class MenuComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.menuCollapsed = this.menuService.isMenuCollapsed(this.menuID);
|
this.menuCollapsed = this.menuService.isMenuCollapsed(this.menuID);
|
||||||
|
this.menuPreviewCollapsed = this.menuService.isMenuPreviewCollapsed(this.menuID);
|
||||||
this.menuVisible = this.menuService.isMenuVisible(this.menuID);
|
this.menuVisible = this.menuService.isMenuVisible(this.menuID);
|
||||||
this.sections = this.menuService.getMenuTopSections(this.menuID).pipe(first());
|
this.sections = this.menuService.getMenuTopSections(this.menuID).pipe(first());
|
||||||
this.sections.subscribe((sections: MenuSection[]) => {
|
this.sections.subscribe((sections: MenuSection[]) => {
|
||||||
@@ -41,6 +43,27 @@ export class MenuComponent implements OnInit {
|
|||||||
this.menuService.toggleMenu(this.menuID);
|
this.menuService.toggleMenu(this.menuID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expand(event: Event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.menuService.expandMenu(this.menuID);
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse(event: Event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.menuService.collapseMenu(this.menuID);
|
||||||
|
}
|
||||||
|
|
||||||
|
expandPreview(event: Event) {
|
||||||
|
console.log("HOI IK HOVER");
|
||||||
|
event.preventDefault();
|
||||||
|
this.menuService.expandMenuPreview(this.menuID);
|
||||||
|
}
|
||||||
|
|
||||||
|
collapsePreview(event: Event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.menuService.collapseMenuPreview(this.menuID);
|
||||||
|
}
|
||||||
|
|
||||||
getSectionComponent(section: MenuSection): Observable<GenericConstructor<MenuSectionComponent>> {
|
getSectionComponent(section: MenuSection): Observable<GenericConstructor<MenuSectionComponent>> {
|
||||||
return this.menuService.hasSubSections(this.menuID, section.id).pipe(
|
return this.menuService.hasSubSections(this.menuID, section.id).pipe(
|
||||||
map((expandable: boolean) => {
|
map((expandable: boolean) => {
|
||||||
|
@@ -17,45 +17,45 @@ import { MenuService } from './menu.service';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MenuEffects {
|
export class MenuEffects {
|
||||||
|
//
|
||||||
|
// @Effect()
|
||||||
|
// public collapseSectionsOnCollapseMenu$: Observable<Action> = this.actions$.pipe(
|
||||||
|
// ofType(MenuActionTypes.COLLAPSE_MENU, MenuActionTypes.TOGGLE_MENU),
|
||||||
|
// switchMap((action: CollapseMenuAction | ToggleMenuAction) => {
|
||||||
|
// return this.menuService.getMenu(action.menuID).pipe(
|
||||||
|
// first(),
|
||||||
|
// switchMap((menu: MenuState) => {
|
||||||
|
// if (menu.collapsed) {
|
||||||
|
// const sections = menu.sections;
|
||||||
|
// return Object.keys(sections)
|
||||||
|
// .map((id) => {
|
||||||
|
// return new DeactivateMenuSectionAction(action.menuID, id);
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// } else {
|
||||||
|
// return [{ type: 'NO_ACTION' }];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
// })
|
||||||
|
// );
|
||||||
|
|
||||||
@Effect()
|
// @Effect()
|
||||||
public collapseSectionsOnCollapseMenu$: Observable<Action> = this.actions$.pipe(
|
// public onExpandSectionMenuExpandMenu: Observable<Action> = this.actions$.pipe(
|
||||||
ofType(MenuActionTypes.COLLAPSE_MENU, MenuActionTypes.TOGGLE_MENU),
|
// ofType(MenuActionTypes.ACTIVATE_SECTION, MenuActionTypes.TOGGLE_ACTIVE_SECTION),
|
||||||
switchMap((action: CollapseMenuAction | ToggleMenuAction) => {
|
// switchMap((action: ActivateMenuSectionAction | ToggleActiveMenuSectionAction) => {
|
||||||
return this.menuService.getMenu(action.menuID).pipe(
|
// return this.menuService.getMenu(action.menuID).pipe(
|
||||||
first(),
|
// first(),
|
||||||
switchMap((menu: MenuState) => {
|
// map((menu: MenuState) => {
|
||||||
if (menu.collapsed) {
|
// if (menu.collapsed) {
|
||||||
const sections = menu.sections;
|
// return new ExpandMenuAction(menu.id)
|
||||||
return Object.keys(sections)
|
// } else {
|
||||||
.map((id) => {
|
// return { type: 'NO_ACTION' };
|
||||||
return new DeactivateMenuSectionAction(action.menuID, id);
|
// }
|
||||||
}
|
// }));
|
||||||
)
|
// })
|
||||||
} else {
|
// );
|
||||||
return [{ type: 'NO_ACTION' }];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
@Effect()
|
|
||||||
public onExpandSectionMenuExpandMenu: Observable<Action> = this.actions$.pipe(
|
|
||||||
ofType(MenuActionTypes.ACTIVATE_SECTION, MenuActionTypes.TOGGLE_ACTIVE_SECTION),
|
|
||||||
switchMap((action: ActivateMenuSectionAction | ToggleActiveMenuSectionAction) => {
|
|
||||||
return this.menuService.getMenu(action.menuID).pipe(
|
|
||||||
first(),
|
|
||||||
map((menu: MenuState) => {
|
|
||||||
if (menu.collapsed) {
|
|
||||||
return new ExpandMenuAction(menu.id)
|
|
||||||
} else {
|
|
||||||
return { type: 'NO_ACTION' };
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
constructor(private actions$: Actions,
|
constructor(private actions$: Actions,
|
||||||
private menuService: MenuService) {
|
private menuService: MenuService) {
|
||||||
|
@@ -18,7 +18,8 @@ export type MenusState = {
|
|||||||
|
|
||||||
export interface MenuState {
|
export interface MenuState {
|
||||||
id: MenuID;
|
id: MenuID;
|
||||||
collapsed: boolean;
|
collapsed: boolean
|
||||||
|
previewCollapsed: boolean;
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
sections: MenuSections
|
sections: MenuSections
|
||||||
sectionToSubsectionIndex: MenuSectionIndex;
|
sectionToSubsectionIndex: MenuSectionIndex;
|
||||||
@@ -53,6 +54,14 @@ export function menusReducer(state: MenusState = initialMenusState, action: Menu
|
|||||||
const newMenuState = Object.assign({}, menuState, { collapsed: false });
|
const newMenuState = Object.assign({}, menuState, { collapsed: false });
|
||||||
return Object.assign({}, state, { [action.menuID]: newMenuState });
|
return Object.assign({}, state, { [action.menuID]: newMenuState });
|
||||||
}
|
}
|
||||||
|
case MenuActionTypes.COLLAPSE_MENU_PREVIEW: {
|
||||||
|
const newMenuState = Object.assign({}, menuState, { previewCollapsed: true });
|
||||||
|
return Object.assign({}, state, { [action.menuID]: newMenuState });
|
||||||
|
}
|
||||||
|
case MenuActionTypes.EXPAND_MENU_PREVIEW: {
|
||||||
|
const newMenuState = Object.assign({}, menuState, { previewCollapsed: false });
|
||||||
|
return Object.assign({}, state, { [action.menuID]: newMenuState });
|
||||||
|
}
|
||||||
case MenuActionTypes.TOGGLE_MENU: {
|
case MenuActionTypes.TOGGLE_MENU: {
|
||||||
const newMenuState = Object.assign({}, menuState, { collapsed: !menuState.collapsed });
|
const newMenuState = Object.assign({}, menuState, { collapsed: !menuState.collapsed });
|
||||||
return Object.assign({}, state, { [action.menuID]: newMenuState });
|
return Object.assign({}, state, { [action.menuID]: newMenuState });
|
||||||
|
@@ -7,8 +7,13 @@ import { Observable } from 'rxjs/internal/Observable';
|
|||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
ActivateMenuSectionAction,
|
ActivateMenuSectionAction,
|
||||||
AddMenuSectionAction, DeactivateMenuSectionAction, HideMenuAction,
|
AddMenuSectionAction,
|
||||||
RemoveMenuSectionAction, ShowMenuAction,
|
CollapseMenuAction, CollapseMenuPreviewAction,
|
||||||
|
DeactivateMenuSectionAction,
|
||||||
|
ExpandMenuAction, ExpandMenuPreviewAction,
|
||||||
|
HideMenuAction,
|
||||||
|
RemoveMenuSectionAction,
|
||||||
|
ShowMenuAction,
|
||||||
ToggleActiveMenuSectionAction,
|
ToggleActiveMenuSectionAction,
|
||||||
ToggleMenuAction,
|
ToggleMenuAction,
|
||||||
} from './menu.actions';
|
} from './menu.actions';
|
||||||
@@ -97,12 +102,34 @@ export class MenuService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isMenuPreviewCollapsed(menuID: MenuID): Observable<boolean> {
|
||||||
|
return this.getMenu(menuID).pipe(
|
||||||
|
map((state: MenuState) => state.previewCollapsed)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
isMenuVisible(menuID: MenuID): Observable<boolean> {
|
isMenuVisible(menuID: MenuID): Observable<boolean> {
|
||||||
return this.getMenu(menuID).pipe(
|
return this.getMenu(menuID).pipe(
|
||||||
map((state: MenuState) => state.visible)
|
map((state: MenuState) => state.visible)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expandMenu(menuID: MenuID): void {
|
||||||
|
this.store.dispatch(new ExpandMenuAction(menuID));
|
||||||
|
}
|
||||||
|
|
||||||
|
collapseMenu(menuID: MenuID): void {
|
||||||
|
this.store.dispatch(new CollapseMenuAction(menuID));
|
||||||
|
}
|
||||||
|
|
||||||
|
expandMenuPreview(menuID: MenuID): void {
|
||||||
|
this.store.dispatch(new ExpandMenuPreviewAction(menuID));
|
||||||
|
}
|
||||||
|
|
||||||
|
collapseMenuPreview(menuID: MenuID): void {
|
||||||
|
this.store.dispatch(new CollapseMenuPreviewAction(menuID));
|
||||||
|
}
|
||||||
|
|
||||||
toggleMenu(menuID: MenuID): void {
|
toggleMenu(menuID: MenuID): void {
|
||||||
this.store.dispatch(new ToggleMenuAction(menuID));
|
this.store.dispatch(new ToggleMenuAction(menuID));
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,9 @@
|
|||||||
$fa-fixed-width: 1.25rem;
|
$fa-fixed-width: 1.25rem;
|
||||||
$icon-padding: 1rem;
|
$icon-padding: 1rem;
|
||||||
$collapsed-sidebar-width: calculatePx($fa-fixed-width + (2 * $icon-padding));
|
$collapsed-sidebar-width: calculatePx($fa-fixed-width + (2 * $icon-padding));
|
||||||
|
$sidebar-items-width: 250px;
|
||||||
|
$total-sidebar-width: $collapsed-sidebar-width + $sidebar-items-width;
|
||||||
|
|
||||||
/* Fonts */
|
/* Fonts */
|
||||||
$fa-font-path: "../assets/fonts";
|
$fa-font-path: "../assets/fonts";
|
||||||
/* Images */
|
/* Images */
|
||||||
|
@@ -18,7 +18,6 @@ $header-logo-height: 80px;
|
|||||||
$admin-sidebar-bg: $dark;
|
$admin-sidebar-bg: $dark;
|
||||||
$admin-sidebar-active-bg: darken($dark, 3%);
|
$admin-sidebar-active-bg: darken($dark, 3%);
|
||||||
$admin-sidebar-header-bg: darken($dark, 7%);
|
$admin-sidebar-header-bg: darken($dark, 7%);
|
||||||
$admin-sidebar-width: 250px;
|
|
||||||
|
|
||||||
$dark-scrollbar-background: $admin-sidebar-active-bg;
|
$dark-scrollbar-background: $admin-sidebar-active-bg;
|
||||||
$dark-scrollbar-foreground: #47495d;
|
$dark-scrollbar-foreground: #47495d;
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
@import '_variables.scss';
|
@import '_variables.scss';
|
||||||
|
|
||||||
:export {
|
:export {
|
||||||
adminSidebarWidth: $admin-sidebar-width;
|
|
||||||
xlMin: map-get($grid-breakpoints, xl);
|
xlMin: map-get($grid-breakpoints, xl);
|
||||||
mdMin: map-get($grid-breakpoints, md);
|
mdMin: map-get($grid-breakpoints, md);
|
||||||
lgMin: map-get($grid-breakpoints, lg);
|
lgMin: map-get($grid-breakpoints, lg);
|
||||||
smMin: map-get($grid-breakpoints, sm);
|
smMin: map-get($grid-breakpoints, sm);
|
||||||
adminSidebarActiveBg: $admin-sidebar-active-bg;
|
adminSidebarActiveBg: $admin-sidebar-active-bg;
|
||||||
|
sidebarItemsWidth: $sidebar-items-width;
|
||||||
collapsedSidebarWidth: $collapsed-sidebar-width;
|
collapsedSidebarWidth: $collapsed-sidebar-width;
|
||||||
|
totalSidebarWidth: $total-sidebar-width;
|
||||||
}
|
}
|
Reference in New Issue
Block a user