mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
progress vertical menu
This commit is contained in:
@@ -130,6 +130,7 @@
|
||||
"devDependencies": {
|
||||
"@angular/compiler": "^6.1.4",
|
||||
"@angular/compiler-cli": "^6.1.4",
|
||||
"@fortawesome/fontawesome-free": "^5.5.0",
|
||||
"@ngrx/entity": "^6.1.0",
|
||||
"@ngrx/schematics": "^6.1.0",
|
||||
"@ngrx/store-devtools": "^6.1.0",
|
||||
|
61
src/app/+admin/admin-sidebar/admin-sidebar.actions.ts
Normal file
61
src/app/+admin/admin-sidebar/admin-sidebar.actions.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
import { type } from '../../shared/ngrx/type';
|
||||
|
||||
/**
|
||||
* For each action type in an action group, make a simple
|
||||
* enum object for all of this group's action types.
|
||||
*
|
||||
* The 'type' utility function coerces strings into string
|
||||
* literal types and runs a simple check to guarantee all
|
||||
* action types in the application are unique.
|
||||
*/
|
||||
export const AdminSidebarSectionActionTypes = {
|
||||
COLLAPSE: type('dspace/admin-sidebar-section/COLLAPSE'),
|
||||
EXPAND: type('dspace/admin-sidebar-sectio/EXPAND'),
|
||||
TOGGLE: type('dspace/admin-sidebar-sectio/TOGGLE'),
|
||||
};
|
||||
|
||||
export class AdminSidebarSectionAction implements Action {
|
||||
/**
|
||||
* Name of the section the action is performed on, used to identify the section
|
||||
*/
|
||||
sectionName: string;
|
||||
|
||||
/**
|
||||
* Type of action that will be performed
|
||||
*/
|
||||
type;
|
||||
|
||||
/**
|
||||
* Initialize with the section's name
|
||||
* @param {string} name of the section
|
||||
*/
|
||||
constructor(name: string) {
|
||||
this.sectionName = name;
|
||||
}
|
||||
}
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
/**
|
||||
* Used to collapse a section
|
||||
*/
|
||||
export class AdminSidebarSectionCollapseAction extends AdminSidebarSectionAction {
|
||||
type = AdminSidebarSectionActionTypes.COLLAPSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to expand a section
|
||||
*/
|
||||
export class AdminSidebarSectionExpandAction extends AdminSidebarSectionAction {
|
||||
type = AdminSidebarSectionActionTypes.EXPAND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to collapse a section when it's expanded and expand it when it's collapsed
|
||||
*/
|
||||
export class AdminSidebarSectionToggleAction extends AdminSidebarSectionAction {
|
||||
type = AdminSidebarSectionActionTypes.TOGGLE;
|
||||
}
|
||||
|
||||
/* tslint:enable:max-classes-per-file */
|
@@ -1,112 +1,135 @@
|
||||
<nav class="navbar navbar-dark bg-dark">
|
||||
<ul class="navbar-nav sidebar-top-level-items">
|
||||
<li class="admin-menu-header">
|
||||
<a class="shortcuts-tree" href="#">
|
||||
<div class="nav-icon-container"><img class="admin-logo" src="assets/images/dspace-logo-mini.svg"></div>
|
||||
<h4 class="nav-item-name">Admin</h4>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fa fa-plus-circle fa-fw"></i>
|
||||
New
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items">
|
||||
<li><a class="nav-item nav-link" href="#">Community</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Collection</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Item</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Item Version</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fa fa-pencil fa-fw"></i>
|
||||
Edit
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items">
|
||||
<li><a class="nav-item nav-link" href="#">Community</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Collection</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Item</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fa fa-arrow-circle-up fa-fw"></i>
|
||||
Import
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items">
|
||||
<li><a class="nav-item nav-link" href="#">Metadata</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Batch Import (ZIP)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fa fa-arrow-circle-down fa-fw"></i>
|
||||
Export
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items">
|
||||
<li><a class="nav-item nav-link" href="#">Community</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Collection</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Item</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Metadata</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fa fa-key fa-fw"></i>
|
||||
Access Control
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items">
|
||||
<li><a class="nav-item nav-link" href="#">People</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Groups</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Authorizations</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fa fa-search fa-fw"></i>
|
||||
Find
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items">
|
||||
<li><a class="nav-item nav-link" href="#">Items</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Withdrawn Items</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Private Items</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fa fa-list fa-fw"></i>
|
||||
Registries
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items">
|
||||
<li><a class="nav-item nav-link" href="#">Metadata</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Format</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fa fa-filter fa-fw"></i>
|
||||
Curation Tasks
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fa fa-bar-chart fa-fw"></i>
|
||||
Statistics
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fa fa-cogs fa-fw"></i>
|
||||
Control Panel
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<nav class="navbar navbar-dark bg-dark p-0">
|
||||
<div class="sidebar-top-level-items">
|
||||
<ul class="navbar-nav">
|
||||
<li class="admin-menu-header">
|
||||
<a class="shortcuts-tree navbar-brand" href="#">
|
||||
<img class="admin-logo mr-2" src="assets/images/dspace-logo-mini.svg">
|
||||
<h4 class="nav-item-name">Admin</h4>
|
||||
</a>
|
||||
</li>
|
||||
<li [ngClass]="{'active': (active('new') | async)}">
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#"
|
||||
(click)="toggle($event, 'new')">
|
||||
<i class="fas fa-plus-circle fa-fw"></i>
|
||||
New
|
||||
<i class="fas fa-chevron-right fa-pull-right fa-xxs"
|
||||
[ngClass]="{'fa-rotate-90': (active('new') | async)}"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items" [ngbCollapse]="!(active('new') | async)">
|
||||
<li><a class="nav-item nav-link" href="#">Community</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Collection</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Item</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Item Version</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li [ngClass]="{'active': (active('edit') | async)}">
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#"
|
||||
(click)="toggle($event, 'edit')">
|
||||
<i class="fas fa-pencil-alt fa-fw"></i>
|
||||
Edit
|
||||
<i class="fas fa-chevron-right fa-pull-right fa-xxs"
|
||||
[ngClass]="{'fa-rotate-90': (active('edit') | async)}"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items" [ngbCollapse]="!(active('edit') | async)">
|
||||
<li><a class="nav-item nav-link" href="#">Community</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Collection</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Item</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li [ngClass]="{'active': (active('import') | async)}">
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#"
|
||||
(click)="toggle($event, 'import')">
|
||||
<i class="fas fa-arrow-circle-up fa-fw"></i>
|
||||
Import
|
||||
<i class="fas fa-chevron-right fa-pull-right fa-xxs"
|
||||
[ngClass]="{'fa-rotate-90': (active('import') | async)}"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items" [ngbCollapse]="!(active('import') | async)">
|
||||
<li><a class="nav-item nav-link" href="#">Metadata</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Batch Import (ZIP)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li [ngClass]="{'active': (active('export') | async)}">
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#"
|
||||
(click)="toggle($event, 'export')">
|
||||
<i class="fas fa-arrow-circle-down fa-fw"></i>
|
||||
Export
|
||||
<i class="fas fa-chevron-right fa-pull-right fa-xxs"
|
||||
[ngClass]="{'fa-rotate-90': (active('export') | async)}"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items" [ngbCollapse]="!(active('export') | async)">
|
||||
<li><a class="nav-item nav-link" href="#">Community</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Collection</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Item</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Metadata</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li [ngClass]="{'active': (active('access_control') | async)}">
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#"
|
||||
(click)="toggle($event, 'access_control')">
|
||||
<i class="fas fa-key fa-fw"></i>
|
||||
Access Control
|
||||
<i class="fas fa-chevron-right fa-pull-right fa-xxs"
|
||||
[ngClass]="{'fa-rotate-90': (active('access_control') | async)}"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items"
|
||||
[ngbCollapse]="!(active('access_control') | async)">
|
||||
<li><a class="nav-item nav-link" href="#">People</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Groups</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Authorizations</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li [ngClass]="{'active': (active('find') | async)}">
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#"
|
||||
(click)="toggle($event, 'find')">
|
||||
<i class="fas fa-search fa-fw"></i>
|
||||
Find
|
||||
<i class="fas fa-chevron-right fa-pull-right fa-xxs"
|
||||
[ngClass]="{'fa-rotate-90': (active('find') | async)}"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items" [ngbCollapse]="!(active('find') | async)">
|
||||
<li><a class="nav-item nav-link" href="#">Items</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Withdrawn Items</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Private Items</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li [ngClass]="{'active': (active('registries') | async)}">
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#"
|
||||
(click)="toggle($event, 'registries')">
|
||||
<i class="fas fa-list fa-fw"></i>
|
||||
Registries
|
||||
<i class="fas fa-chevron-right fa-pull-right fa-xxs"
|
||||
[ngClass]="{'fa-rotate-90': (active('registries') | async)}"></i>
|
||||
</a>
|
||||
<ul class="sidebar-sub-level-items" [ngbCollapse]="!(active('registries') | async)">
|
||||
<li><a class="nav-item nav-link" href="#">Metadata</a></li>
|
||||
<li><a class="nav-item nav-link" href="#">Format</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fas fa-filter fa-fw"></i>
|
||||
Curation Tasks
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fas fa-chart-bar fa-fw"></i>
|
||||
Statistics
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fas fa-cogs fa-fw"></i>
|
||||
Control Panel
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="navbar-nav">
|
||||
<a class="nav-item nav-link shortcuts-tree" href="#">
|
||||
<i class="fas fa-fw fa-angle-double-right"></i>
|
||||
Collapse
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
@@ -1,8 +1,41 @@
|
||||
@import '../../../styles/variables.scss';
|
||||
|
||||
:host {
|
||||
position: absolute;
|
||||
.sidebar-sub-level-items {
|
||||
list-style: disc;
|
||||
color: $navbar-dark-color;
|
||||
position: fixed;
|
||||
nav {
|
||||
height: 100vh;
|
||||
flex-direction: column;
|
||||
>div.sidebar-top-level-items {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
.navbar-nav {
|
||||
min-width: $admin-sidebar-width;
|
||||
> * {
|
||||
padding: $spacer/2 $spacer;
|
||||
&.active {
|
||||
background-color: $admin-sidebar-dark;
|
||||
}
|
||||
}
|
||||
.sidebar-sub-level-items {
|
||||
list-style: disc;
|
||||
color: $navbar-dark-color;
|
||||
}
|
||||
.fa-xxs {
|
||||
font-size: 0.5rem;
|
||||
line-height: 3;
|
||||
}
|
||||
.admin-menu-header {
|
||||
background-color: $admin-sidebar-dark;
|
||||
img {
|
||||
|
||||
height: 1em;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
h4 {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,10 +1,45 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store';
|
||||
import { AdminSidebarSectionsState, AdminSidebarSectionState } from './admin-sidebar.reducer';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { AdminSidebarSectionToggleAction } from './admin-sidebar.actions';
|
||||
|
||||
const sidebarSectionStateSelector = (state: AdminSidebarSectionsState) => state.adminSidebarSection;
|
||||
|
||||
const sectionByNameSelector = (name: string): MemoizedSelector<AdminSidebarSectionsState, AdminSidebarSectionState> => {
|
||||
return keySelector<AdminSidebarSectionState>(name);
|
||||
};
|
||||
|
||||
export function keySelector<T>(key: string): MemoizedSelector<AdminSidebarSectionsState, T> {
|
||||
return createSelector(sidebarSectionStateSelector, (state: AdminSidebarSectionState) => {
|
||||
if (hasValue(state)) {
|
||||
return state[key];
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
@Component({
|
||||
selector: 'ds-admin-sidebar',
|
||||
templateUrl: './admin-sidebar.component.html',
|
||||
styleUrls: ['./admin-sidebar.component.scss'],
|
||||
})
|
||||
export class AdminSidebarComponent {
|
||||
constructor(private store: Store<AdminSidebarSectionsState>) {
|
||||
|
||||
}
|
||||
|
||||
public active(name: string): Observable<boolean> {
|
||||
return this.store.pipe(
|
||||
select(sectionByNameSelector(name)),
|
||||
map((state: AdminSidebarSectionState) => hasValue(state) ? !state.sectionCollapsed : false)
|
||||
);
|
||||
}
|
||||
|
||||
toggle(event: Event, name: string) {
|
||||
event.preventDefault();
|
||||
this.store.dispatch(new AdminSidebarSectionToggleAction(name));
|
||||
}
|
||||
}
|
60
src/app/+admin/admin-sidebar/admin-sidebar.reducer.ts
Normal file
60
src/app/+admin/admin-sidebar/admin-sidebar.reducer.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { AdminSidebarSectionAction, AdminSidebarSectionActionTypes } from './admin-sidebar.actions';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
|
||||
/**
|
||||
* Interface that represents the state for a single section
|
||||
*/
|
||||
export interface AdminSidebarSectionState {
|
||||
sectionCollapsed: boolean,
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface that represents the state for all available sections
|
||||
*/
|
||||
export interface AdminSidebarSectionsState {
|
||||
[name: string]: AdminSidebarSectionState
|
||||
}
|
||||
|
||||
const initialState: AdminSidebarSectionsState = Object.create(null);
|
||||
const initiallyCollapsed = true;
|
||||
/**
|
||||
* Performs a search section action on the current state
|
||||
* @param {AdminSidebarSectionsState} state The state before the action is performed
|
||||
* @param {AdminSidebarSectionAction} action The action that should be performed
|
||||
* @returns {AdminSidebarSectionsState} The state after the action is performed
|
||||
*/
|
||||
export function sidebarSectionReducer(state = initialState, action: AdminSidebarSectionAction): AdminSidebarSectionsState {
|
||||
|
||||
switch (action.type) {
|
||||
case AdminSidebarSectionActionTypes.COLLAPSE: {
|
||||
return Object.assign({}, state, {
|
||||
[action.sectionName]: {
|
||||
sectionCollapsed: true,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
case AdminSidebarSectionActionTypes.EXPAND: {
|
||||
return Object.assign({}, state, {
|
||||
[action.sectionName]: {
|
||||
sectionCollapsed: false,
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
case AdminSidebarSectionActionTypes.TOGGLE: {
|
||||
const currentState = state[action.sectionName];
|
||||
const collapsed = hasValue(currentState) ? currentState.sectionCollapsed : initiallyCollapsed;
|
||||
return Object.assign({}, state, {
|
||||
[action.sectionName]: {
|
||||
sectionCollapsed: !collapsed,
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
@@ -5,7 +5,7 @@ import { AdminRoutingModule } from './admin-routing.module';
|
||||
@NgModule({
|
||||
imports: [
|
||||
AdminRegistriesModule,
|
||||
AdminRoutingModule
|
||||
AdminRoutingModule,
|
||||
]
|
||||
})
|
||||
export class AdminModule {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<div (click)="toggle()" class="filter-name"><h5 class="d-inline-block mb-0">{{'search.filters.filter.' + filter.name + '.head'| translate}}</h5> <span class="filter-toggle fa float-right"
|
||||
<div (click)="toggle()" class="filter-name"><h5 class="d-inline-block mb-0">{{'search.filters.filter.' + filter.name + '.head'| translate}}</h5> <span class="filter-toggle fas float-right"
|
||||
[ngClass]="(isCollapsed() | async) ? 'fa-plus' : 'fa-minus'"></span></div>
|
||||
<div [@slide]="(isCollapsed() | async) ? 'collapsed' : 'expanded'" (@slide.start)="startSlide($event)" (@slide.done)="finishSlide($event)" class="search-filter-wrapper" [ngClass]="{'closed' : collapsed}">
|
||||
<ds-search-facet-filter-wrapper [filterConfig]="filter"></ds-search-facet-filter-wrapper>
|
||||
|
@@ -26,7 +26,7 @@
|
||||
<ds-view-mode-switch></ds-view-mode-switch>
|
||||
<button (click)="openSidebar()" aria-controls="#search-body"
|
||||
class="btn btn-outline-primary float-right open-sidebar"><i
|
||||
class="fa fa-sliders"></i> {{"search.sidebar.open"
|
||||
class="fas fa-sliders"></i> {{"search.sidebar.open"
|
||||
| translate}}
|
||||
</button>
|
||||
</div>
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<button (click)="toggleSidebar.emit()"
|
||||
aria-controls="#search-body"
|
||||
class="btn btn-outline-primary float-right close-sidebar"><i
|
||||
class="fa fa-arrow-right"></i> {{"search.sidebar.close" | translate}}
|
||||
class="fas fa-arrow-right"></i> {{"search.sidebar.close" | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<div id="search-sidebar-content">
|
||||
|
@@ -1,7 +1,7 @@
|
||||
@import '../styles/variables.scss';
|
||||
@import '../styles/font-awesome-imports.scss';
|
||||
@import '../../node_modules/bootstrap/scss/bootstrap.scss';
|
||||
@import '../../node_modules/nouislider/distribute/nouislider.min.css';
|
||||
@import "../../node_modules/font-awesome/scss/font-awesome.scss";
|
||||
|
||||
html {
|
||||
position: relative;
|
||||
|
@@ -16,6 +16,10 @@ import {
|
||||
} from './shared/notifications/notifications.reducers';
|
||||
import { truncatableReducer, TruncatablesState } from './shared/truncatable/truncatable.reducer';
|
||||
import { navbarReducer, NavbarState } from './navbar/navbar.reducer';
|
||||
import {
|
||||
AdminSidebarSectionsState,
|
||||
sidebarSectionReducer
|
||||
} from './+admin/admin-sidebar/admin-sidebar.reducer';
|
||||
|
||||
export interface AppState {
|
||||
router: fromRouter.RouterReducerState;
|
||||
@@ -26,6 +30,7 @@ export interface AppState {
|
||||
searchSidebar: SearchSidebarState;
|
||||
searchFilter: SearchFiltersState;
|
||||
truncatable: TruncatablesState;
|
||||
adminSidebarSection: AdminSidebarSectionsState;
|
||||
}
|
||||
|
||||
export const appReducers: ActionReducerMap<AppState> = {
|
||||
@@ -36,7 +41,8 @@ export const appReducers: ActionReducerMap<AppState> = {
|
||||
notifications: notificationsReducer,
|
||||
searchSidebar: sidebarReducer,
|
||||
searchFilter: filterReducer,
|
||||
truncatable: truncatableReducer
|
||||
truncatable: truncatableReducer,
|
||||
adminSidebarSection: sidebarSectionReducer
|
||||
};
|
||||
|
||||
export const routerStateSelector = (state: AppState) => state.router;
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import { Component, HostBinding, OnDestroy, OnInit } from '@angular/core';
|
||||
import { createSelector, Store } from '@ngrx/store';
|
||||
import { createSelector, select, Store } from '@ngrx/store';
|
||||
import { AppState } from '../app.reducer';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { NavbarState } from '../navbar/navbar.reducer';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { hasValue } from '../shared/empty.util';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { Subscription } from 'rxjs/internal/Subscription';
|
||||
|
||||
const navbarStateSelector = (state: AppState) => state.navbar;
|
||||
const navCollapsedSelector = createSelector(navbarStateSelector, (navbar: NavbarState) => navbar.navCollapsed);
|
||||
@@ -24,7 +24,7 @@ export class HeaderNavbarWrapperComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.isNavBarCollapsed = this.store.select(navCollapsedSelector);
|
||||
this.isNavBarCollapsed = this.store.pipe(select(navCollapsedSelector));
|
||||
this.sub = this.isNavBarCollapsed.subscribe((isCollapsed) => this.isOpen = !isCollapsed)
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
<button class="navbar-toggler" type="button" (click)="toggle()"
|
||||
aria-controls="collapsingNav"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon fa fa-bars fa-fw" aria-hidden="true"></span>
|
||||
<span class="navbar-toggler-icon fas fa-bars fa-fw" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { NavbarToggleAction } from '../navbar/navbar.actions';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '../app.reducer';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-header',
|
||||
|
@@ -49,7 +49,7 @@ describe('NavbarComponent', () => {
|
||||
|
||||
comp = fixture.componentInstance;
|
||||
|
||||
store = fixture.debugElement.injector.get(Store) as Store<HeaderState>;
|
||||
store = fixture.debugElement.injector.get(Store) as Store<NavbarState>;
|
||||
spyOn(store, 'dispatch');
|
||||
});
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { AppState } from '../app.reducer';
|
||||
import { slideMobileNav } from '../shared/animations/slide';
|
||||
import { HostWindowService } from '../shared/host-window.service';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-navbar',
|
||||
|
@@ -1,25 +1,25 @@
|
||||
<ul class="navbar-nav" [ngClass]="{'mr-auto': (isXsOrSm$ | async)}">
|
||||
<li *ngIf="!(isAuthenticated | async) && !(isXsOrSm$ | async) && (showAuth | async)" class="nav-item" (click)="$event.stopPropagation();">
|
||||
<div ngbDropdown placement="bottom-right" class="d-inline-block" @fadeInOut>
|
||||
<a href="#" id="dropdownLogin" class="nav-link" (click)="$event.preventDefault()" ngbDropdownToggle><i class="fa fa-sign-in fa-fw" aria-hidden="true"></i> {{ 'nav.login' | translate }}<span class="caret"></span></a>
|
||||
<a href="#" id="dropdownLogin" class="nav-link" (click)="$event.preventDefault()" ngbDropdownToggle><i class="fas fa-sign-in-alt fa-fw" aria-hidden="true"></i> {{ 'nav.login' | translate }}<span class="caret"></span></a>
|
||||
<div id="loginDropdownMenu" [ngClass]="{'pl-3 pr-3': (loading | async)}" ngbDropdownMenu aria-labelledby="dropdownLogin">
|
||||
<ds-log-in></ds-log-in>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li *ngIf="!(isAuthenticated | async) && (isXsOrSm$ | async)" class="nav-item">
|
||||
<a id="loginLink" class="nav-link" routerLink="/login" routerLinkActive="active"><i class="fa fa-sign-in fa-fw" aria-hidden="true"></i> {{ 'nav.login' | translate }}<span class="sr-only">(current)</span></a>
|
||||
<a id="loginLink" class="nav-link" routerLink="/login" routerLinkActive="active"><i class="fas fa-sign-in-alt fa-fw" aria-hidden="true"></i> {{ 'nav.login' | translate }}<span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li *ngIf="(isAuthenticated | async) && !(isXsOrSm$ | async) && (showAuth | async)" class="nav-item">
|
||||
<div ngbDropdown placement="bottom-right" class="d-inline-block" @fadeInOut>
|
||||
<a href="#" id="dropdownUser" class="nav-link" (click)="$event.preventDefault()" ngbDropdownToggle><i class="fa fa-user fa-fw" aria-hidden="true"></i>Hello {{(user | async).name}}<span class="caret"></span></a>
|
||||
<a href="#" id="dropdownUser" class="nav-link" (click)="$event.preventDefault()" ngbDropdownToggle><i class="fas fa-user fa-fw" aria-hidden="true"></i>Hello {{(user | async).name}}<span class="caret"></span></a>
|
||||
<div id="logoutDropdownMenu" ngbDropdownMenu aria-labelledby="dropdownUser">
|
||||
<ds-log-out></ds-log-out>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li *ngIf="(isAuthenticated | async) && (isXsOrSm$ | async)" class="nav-item">
|
||||
<a id="logoutLink" class="nav-link" routerLink="/logout" routerLinkActive="active"><i class="fa fa-sign-out fa-fw" aria-hidden="true"></i> {{ 'nav.logout' | translate }}<span class="sr-only">(current)</span></a>
|
||||
<a id="logoutLink" class="nav-link" routerLink="/logout" routerLinkActive="active"><i class="fas fa-sign-out-alt fa-fw" aria-hidden="true"></i> {{ 'nav.logout' | translate }}<span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
[ngbTooltip]="tipContent"
|
||||
triggers="manual"
|
||||
#t="ngbTooltip"
|
||||
class="fa {{icon.style}}"
|
||||
class="fas {{icon.style}}"
|
||||
[class.mr-1]="!l"
|
||||
[class.mr-2]="l"
|
||||
aria-hidden="true"
|
||||
@@ -23,7 +23,7 @@
|
||||
(mouseover)="showTooltip(t, i, icon.metadata)"
|
||||
(mouseout)="t.close()"></i>
|
||||
</ng-container>
|
||||
<p class="chip-label text-truncate d-table-cell">{{c.display}}</p><i class="fa fa-times ml-2" (click)="removeChips($event, i)"></i>
|
||||
<p class="chip-label text-truncate d-table-cell">{{c.display}}</p><i class="fas fa-times ml-2" (click)="removeChips($event, i)"></i>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
@@ -34,14 +34,14 @@ describe('ChipsItem model test suite', () => {
|
||||
});
|
||||
|
||||
it('should update icons', () => {
|
||||
const icons: ChipsItemIcon[] = [{metadata: 'test', hasAuthority: false, style: 'fa fa-plus'}];
|
||||
const icons: ChipsItemIcon[] = [{metadata: 'test', hasAuthority: false, style: 'fas fa-plus'}];
|
||||
item.updateIcons(icons);
|
||||
|
||||
expect(item.icons).toEqual(icons);
|
||||
});
|
||||
|
||||
it('should return true if has icons', () => {
|
||||
const icons: ChipsItemIcon[] = [{metadata: 'test', hasAuthority: false, style: 'fa fa-plus'}];
|
||||
const icons: ChipsItemIcon[] = [{metadata: 'test', hasAuthority: false, style: 'fas fa-plus'}];
|
||||
item.updateIcons(icons);
|
||||
const hasIcons = item.hasIcons();
|
||||
|
||||
|
@@ -27,7 +27,7 @@ export const DATE_TEST_MODEL_CONFIG = {
|
||||
placeholder: 'Date',
|
||||
readOnly: false,
|
||||
required: true,
|
||||
toggleIcon: 'fa fa-calendar'
|
||||
toggleIcon: 'fas fa-calendar'
|
||||
};
|
||||
|
||||
describe('DsDatePickerComponent test suite', () => {
|
||||
|
@@ -2,7 +2,7 @@
|
||||
class="close position-relative"
|
||||
ngbTooltip="{{'form.group-collapse-help' | translate}}"
|
||||
placement="left">
|
||||
<span class="fa fa-angle-up fa-fw fa-2x"
|
||||
<span class="fas fa-angle-up fa-fw fa-2x"
|
||||
aria-hidden="true"
|
||||
(click)="collapseForm()"></span>
|
||||
</a>
|
||||
@@ -10,7 +10,7 @@
|
||||
class="close position-relative"
|
||||
ngbTooltip="{{'form.group-expand-help' | translate}}"
|
||||
placement="left">
|
||||
<span class="fa fa-angle-down fa-fw fa-2x"
|
||||
<span class="fas fa-angle-down fa-fw fa-2x"
|
||||
aria-hidden="true"
|
||||
(click)="expandForm()"></span>
|
||||
</a>
|
||||
@@ -33,21 +33,21 @@
|
||||
class="btn btn-link"
|
||||
[disabled]="isMandatoryFieldEmpty()"
|
||||
(click)="save()">
|
||||
<i class="fa fa-save text-primary fa-2x"
|
||||
<i class="fas fa-save text-primary fa-2x"
|
||||
aria-hidden="true"></i>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn btn-link"
|
||||
[disabled]="!editMode"
|
||||
(click)="delete()">
|
||||
<i class="fa fa-trash text-danger fa-2x"
|
||||
<i class="fas fa-trash text-danger fa-2x"
|
||||
aria-hidden="true"></i>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn btn-link"
|
||||
[disabled]="isMandatoryFieldEmpty()"
|
||||
(click)="clear()">
|
||||
<i class="fa fa-undo fa-2x"
|
||||
<i class="fas fa-undo fa-2x"
|
||||
aria-hidden="true"></i>
|
||||
</button>
|
||||
|
||||
|
@@ -41,6 +41,6 @@
|
||||
(keypress)="preventEventsPropagation($event)"
|
||||
(keydown)="preventEventsPropagation($event)"
|
||||
(keyup)="onKeyUp($event)"/>
|
||||
<i *ngIf="searching" class="fa fa-circle-o-notch fa-spin fa-2x fa-fw text-primary position-absolute mt-1 p-0" aria-hidden="true"></i>
|
||||
<i *ngIf="searching" class="fas fa-circle-o-notch fa-spin fa-2x fa-fw text-primary position-absolute mt-1 p-0" aria-hidden="true"></i>
|
||||
</ds-chips>
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
{{ r.display}}
|
||||
</ng-template>
|
||||
<div class="position-relative right-addon">
|
||||
<i *ngIf="searching" class="fa fa-circle-o-notch fa-spin fa-2x fa-fw text-primary position-absolute mt-1 p-0" aria-hidden="true"></i>
|
||||
<i *ngIf="searching" class="fas fa-circle-o-notch fa-spin fa-2x fa-fw text-primary position-absolute mt-1 p-0" aria-hidden="true"></i>
|
||||
<input class="form-control"
|
||||
[attr.autoComplete]="model.autoComplete"
|
||||
[class.is-invalid]="showErrorMessages"
|
||||
|
@@ -11,7 +11,7 @@ export class DateFieldParser extends FieldParser {
|
||||
let malformedDate = false;
|
||||
const inputDateModelConfig: DynamicDatePickerModelConfig = this.initModel(null, label);
|
||||
|
||||
inputDateModelConfig.toggleIcon = 'fa fa-calendar';
|
||||
inputDateModelConfig.toggleIcon = 'fas fa-calendar';
|
||||
this.setValues(inputDateModelConfig as any, fieldValue);
|
||||
// Init Data and validity check
|
||||
if (isNotEmpty(inputDateModelConfig.value)) {
|
||||
|
@@ -20,12 +20,12 @@
|
||||
<button type="button" class="btn btn-secondary"
|
||||
[disabled]="isItemReadOnly(context, index)"
|
||||
(click)="insertItem($event, group.context, group.index + 1)">
|
||||
<i class="fa fa-plus" aria-hidden="true"></i>
|
||||
<i class="fas fa-plus" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary"
|
||||
(click)="removeItem($event, context, index)"
|
||||
[disabled]="group.context.groups.length === 1 || isItemReadOnly(context, index)">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -37,7 +37,7 @@
|
||||
<button type="button" class="btn btn-secondary"
|
||||
(click)="removeItem($event, context, index)"
|
||||
[disabled]="group.context.groups.length === 1 || isItemReadOnly(context, index)">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
<div class="d-flex flex-row">
|
||||
<div class="d-flex flex-column justify-content-center align-items-center">
|
||||
<div class="notification-icon d-flex justify-content-center"><i
|
||||
[ngClass]="{'fa fa-2x': true,
|
||||
[ngClass]="{'fas fa-2x': true,
|
||||
'fa-check': notification.type == 'alert-success',
|
||||
'fa-times-circle': notification.type == 'alert-danger',
|
||||
'fa-exclamation-triangle': notification.type == 'alert-warning',
|
||||
|
@@ -7,12 +7,12 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<div *ngIf="!hideGear" ngbDropdown #paginationControls="ngbDropdown" placement="bottom-right" class="d-inline-block float-right">
|
||||
<button class="btn btn-outline-primary" id="paginationControls" ngbDropdownToggle><i class="fa fa-cog" aria-hidden="true"></i></button>
|
||||
<button class="btn btn-outline-primary" id="paginationControls" ngbDropdownToggle><i class="fas fa-cog" aria-hidden="true"></i></button>
|
||||
<div id="paginationControlsDropdownMenu" aria-labelledby="paginationControls" ngbDropdownMenu>
|
||||
<h6 class="dropdown-header">{{ 'pagination.results-per-page' | translate}}</h6>
|
||||
<button class="dropdown-item" *ngFor="let item of pageSizeOptions" (click)="doPageSizeChange(item)"><i [ngClass]="{'invisible': item != pageSize}" class="fa fa-check" aria-hidden="true"></i> {{item}} </button>
|
||||
<button class="dropdown-item" *ngFor="let item of pageSizeOptions" (click)="doPageSizeChange(item)"><i [ngClass]="{'invisible': item != pageSize}" class="fas fa-check" aria-hidden="true"></i> {{item}} </button>
|
||||
<h6 class="dropdown-header">{{ 'pagination.sort-direction' | translate}}</h6>
|
||||
<button class="dropdown-item" *ngFor="let direction of (sortDirections | dsKeys)" (click)="doSortDirectionChange(direction.value)"><i [ngClass]="{'invisible': direction.value !== sortDirection}" class="fa fa-check" aria-hidden="true"></i> {{'sorting.' + direction.key | translate}} </button>
|
||||
<button class="dropdown-item" *ngFor="let direction of (sortDirections | dsKeys)" (click)="doSortDirectionChange(direction.value)"><i [ngClass]="{'invisible': direction.value !== sortDirection}" class="fas fa-check" aria-hidden="true"></i> {{'sorting.' + direction.key | translate}} </button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -76,7 +76,6 @@ import { NumberPickerComponent } from './number-picker/number-picker.component';
|
||||
import { DsDatePickerComponent } from './form/builder/ds-dynamic-form-ui/models/date-picker/date-picker.component';
|
||||
import { DsDynamicLookupComponent } from './form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component';
|
||||
import { MockAdminGuard } from './mocks/mock-admin-guard.service';
|
||||
import { BrowseByModule } from '../+browse-by/browse-by.module';
|
||||
import { BrowseByComponent } from './browse-by/browse-by.component';
|
||||
import { BrowseEntryListElementComponent } from './object-list/browse-entry-list-element/browse-entry-list-element.component';
|
||||
import { DebounceDirective } from './utils/debounce.directive';
|
||||
|
@@ -19,7 +19,7 @@
|
||||
(fileOver)="fileOverBase($event)"
|
||||
class="well ds-base-drop-zone mt-1 mb-3 text-muted">
|
||||
<p class="text-center m-0 pt-2" [hidden]="uploader?.queue?.length !== 0">
|
||||
<span><i class="fa fa-cloud-upload" aria-hidden="true"></i> {{dropMsg | translate}} {{'uploader.or' | translate}}
|
||||
<span><i class="fas fa-cloud-upload" aria-hidden="true"></i> {{dropMsg | translate}} {{'uploader.or' | translate}}
|
||||
<label class="btn btn-link m-0 p-0">
|
||||
<input class="d-none" type="file" ng2FileSelect [uploader]="uploader" multiple />
|
||||
{{'uploader.browse' | translate}}
|
||||
@@ -32,7 +32,7 @@
|
||||
<span class="filename">{{'uploader.queue-lenght' | translate}}: {{ uploader?.queue?.length }} | {{ uploader?.queue[0]?.file.name }}</span>
|
||||
<div class="btn-group btn-group-sm float-right" role="group">
|
||||
<button type="button" class="btn btn-danger" (click)="uploader.clearQueue()" [disabled]="!uploader.queue.length">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
<span *ngIf="uploader.progress < 100" class="float-right mr-3">{{ uploader.progress }}%</span>
|
||||
|
@@ -6,7 +6,7 @@
|
||||
routerLinkActive="active"
|
||||
[class.active]="currentMode === viewModeEnum.List"
|
||||
class="btn btn-secondary">
|
||||
<i class="fa fa-list" title="{{'search.view-switch.show-list' | translate}}"></i>
|
||||
<i class="fas fa-list" title="{{'search.view-switch.show-list' | translate}}"></i>
|
||||
</a>
|
||||
<a routerLink="."
|
||||
[queryParams]="{view: 'grid'}"
|
||||
@@ -15,6 +15,6 @@
|
||||
routerLinkActive="active"
|
||||
[class.active]="currentMode !== viewModeEnum.List"
|
||||
class="btn btn-secondary">
|
||||
<i class="fa fa-th-large" title="{{'search.view-switch.show-grid' | translate}}"></i>
|
||||
<i class="fas fa-th-large" title="{{'search.view-switch.show-grid' | translate}}"></i>
|
||||
</a>
|
||||
</div>
|
@@ -14,3 +14,6 @@ $nav-z-index: 10;
|
||||
$sidebar-z-index: 20;
|
||||
|
||||
$header-logo-height: 80px;
|
||||
|
||||
$admin-sidebar-dark: #0a1118;
|
||||
$admin-sidebar-width: 250px;
|
||||
|
5
src/styles/_font-awesome-imports.scss
Normal file
5
src/styles/_font-awesome-imports.scss
Normal file
@@ -0,0 +1,5 @@
|
||||
@import "../../node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss";
|
||||
@import "../../node_modules/@fortawesome/fontawesome-free/scss/solid.scss";
|
||||
@import "../../node_modules/@fortawesome/fontawesome-free/scss/brands.scss";
|
||||
@import "../../node_modules/@fortawesome/fontawesome-free/scss/regular.scss";
|
||||
|
@@ -1,5 +1,4 @@
|
||||
@import 'bootstrap_variables.scss';
|
||||
@import '../../node_modules/font-awesome/scss/variables.scss';
|
||||
@import '../../node_modules/bootstrap/scss/functions.scss';
|
||||
@import '../../node_modules/bootstrap/scss/variables.scss';
|
||||
@import '_functions.scss';
|
||||
|
@@ -90,7 +90,7 @@ module.exports = {
|
||||
},
|
||||
plugins: [
|
||||
new CopyWebpackPlugin([{
|
||||
from: join(__dirname, '..', 'node_modules', 'font-awesome', 'fonts'),
|
||||
from: join(__dirname, '..', 'node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'),
|
||||
to: join('assets', 'fonts')
|
||||
}, {
|
||||
from: join(__dirname, '..', 'resources', 'images'),
|
||||
|
Reference in New Issue
Block a user