mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-15 14:03:06 +00:00
46063: saved currect state
This commit is contained in:
@@ -105,8 +105,6 @@
|
||||
"pem": "1.12.3",
|
||||
"reflect-metadata": "0.1.10",
|
||||
"rxjs": "5.4.3",
|
||||
"shave": "^2.1.3",
|
||||
"text-overflow-clamp": "^1.0.0",
|
||||
"ts-md5": "1.2.2",
|
||||
"webfontloader": "1.6.28",
|
||||
"zone.js": "0.8.18"
|
||||
|
@@ -1,5 +1,4 @@
|
||||
@import '../styles/variables.scss';
|
||||
@import '../styles/mixins.scss';
|
||||
@import '../../node_modules/bootstrap/scss/bootstrap.scss';
|
||||
@import "../../node_modules/font-awesome/scss/font-awesome.scss";
|
||||
|
||||
@@ -32,7 +31,3 @@ body {
|
||||
margin-top: $content-spacing;
|
||||
margin-bottom: $content-spacing;
|
||||
}
|
||||
|
||||
.clamp-3 {
|
||||
@include clamp(3);
|
||||
}
|
@@ -11,6 +11,7 @@ import {
|
||||
filterReducer,
|
||||
SearchFiltersState
|
||||
} from './+search-page/search-filters/search-filter/search-filter.reducer';
|
||||
import { truncatableReducer, TruncatablesState } from './shared/truncatable/truncatable.reducer';
|
||||
|
||||
export interface AppState {
|
||||
router: fromRouter.RouterReducerState;
|
||||
@@ -18,6 +19,7 @@ export interface AppState {
|
||||
header: HeaderState;
|
||||
searchSidebar: SearchSidebarState;
|
||||
searchFilter: SearchFiltersState;
|
||||
truncatable: TruncatablesState;
|
||||
}
|
||||
|
||||
export const appReducers: ActionReducerMap<AppState> = {
|
||||
@@ -25,5 +27,6 @@ export const appReducers: ActionReducerMap<AppState> = {
|
||||
hostWindow: hostWindowReducer,
|
||||
header: headerReducer,
|
||||
searchSidebar: sidebarReducer,
|
||||
searchFilter: filterReducer
|
||||
searchFilter: filterReducer,
|
||||
truncatable: truncatableReducer
|
||||
};
|
||||
|
2
src/app/core/cache/response-cache.service.ts
vendored
2
src/app/core/cache/response-cache.service.ts
vendored
@@ -4,7 +4,7 @@ import { MemoizedSelector, Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { ResponseCacheEntry } from './response-cache.reducer';
|
||||
import { hasNoValue, hasValue } from '../../shared/empty.util';
|
||||
import { hasNoValue } from '../../shared/empty.util';
|
||||
import { ResponseCacheRemoveAction, ResponseCacheAddAction } from './response-cache.actions';
|
||||
import { RestResponse } from './response-cache.models';
|
||||
import { CoreState } from '../core.reducers';
|
||||
|
@@ -9,6 +9,6 @@
|
||||
(<span *ngIf="dso.findMetadata('dc.publisher')" class="item-list-publisher" [innerHTML]="getFirstValue('dc.publisher')">, </span><span *ngIf="dso.findMetadata('dc.date.issued')" class="item-list-date" [innerHTML]="getFirstValue('dc.date.issued')"></span>)
|
||||
</span>
|
||||
<div *ngIf="dso.findMetadata('dc.description.abstract')" class="item-list-abstract">
|
||||
<div class="clamp-3" [innerHTML]="getFirstValue('dc.description.abstract')"></div>
|
||||
<ds-truncatable [id]="dso.id" [minLines]="3" [maxLines]="15" [content]="getFirstValue('dc.description.abstract')"></ds-truncatable>
|
||||
</div>
|
||||
</div>
|
@@ -12,7 +12,6 @@ import { NgxPaginationModule } from 'ngx-pagination';
|
||||
import { EnumKeysPipe } from './utils/enum-keys-pipe';
|
||||
import { FileSizePipe } from './utils/file-size-pipe';
|
||||
import { SafeUrlPipe } from './utils/safe-url-pipe';
|
||||
import { TruncatePipe } from './utils/truncate.pipe';
|
||||
|
||||
import { CollectionListElementComponent } from '../object-list/collection-list-element/collection-list-element.component';
|
||||
import { ComcolPageContentComponent } from './comcol-page-content/comcol-page-content.component';
|
||||
@@ -31,8 +30,9 @@ import { SearchFormComponent } from './search-form/search-form.component';
|
||||
import { WrapperListElementComponent } from '../object-list/wrapper-list-element/wrapper-list-element.component';
|
||||
import { ViewModeSwitchComponent } from './view-mode-switch/view-mode-switch.component';
|
||||
import { VarDirective } from './utils/var.directive';
|
||||
import { ShaveDirective } from './utils/shave.directive';
|
||||
|
||||
import { TruncatePipe } from './utils/truncate.pipe';
|
||||
import { TruncatableComponent } from './truncatable/truncatable.component';
|
||||
import { TruncatableService } from './truncatable/truncatable.service';
|
||||
|
||||
const MODULES = [
|
||||
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
|
||||
@@ -67,6 +67,7 @@ const COMPONENTS = [
|
||||
ThumbnailComponent,
|
||||
WrapperListElementComponent,
|
||||
ViewModeSwitchComponent,
|
||||
TruncatableComponent
|
||||
];
|
||||
|
||||
const ENTRY_COMPONENTS = [
|
||||
@@ -77,9 +78,12 @@ const ENTRY_COMPONENTS = [
|
||||
SearchResultListElementComponent
|
||||
];
|
||||
|
||||
const PROVIDERS = [
|
||||
TruncatableService
|
||||
];
|
||||
|
||||
const DIRECTIVES = [
|
||||
VarDirective,
|
||||
ShaveDirective
|
||||
VarDirective
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
@@ -93,6 +97,9 @@ const DIRECTIVES = [
|
||||
...ENTRY_COMPONENTS,
|
||||
...DIRECTIVES
|
||||
],
|
||||
providers: [
|
||||
...PROVIDERS
|
||||
],
|
||||
exports: [
|
||||
...MODULES,
|
||||
...PIPES,
|
||||
|
29
src/app/shared/truncatable/truncatable.actions.ts
Normal file
29
src/app/shared/truncatable/truncatable.actions.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
import { type } from '../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 TruncatableActionTypes = {
|
||||
TOGGLE: type('dspace/truncatable/TOGGLE'),
|
||||
};
|
||||
|
||||
export class TruncatableAction implements Action {
|
||||
id: string;
|
||||
type;
|
||||
constructor(name: string) {
|
||||
this.id = name;
|
||||
}
|
||||
}
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
export class TruncatableToggleAction extends TruncatableAction {
|
||||
type = TruncatableActionTypes.TOGGLE;
|
||||
}
|
||||
|
||||
/* tslint:enable:max-classes-per-file */
|
1
src/app/shared/truncatable/truncatable.component.html
Normal file
1
src/app/shared/truncatable/truncatable.component.html
Normal file
@@ -0,0 +1 @@
|
||||
<div class="clamp-{{lines}}" [innerHTML]="content" (click)="toggleCollapse()"></div>
|
41
src/app/shared/truncatable/truncatable.component.scss
Normal file
41
src/app/shared/truncatable/truncatable.component.scss
Normal file
@@ -0,0 +1,41 @@
|
||||
@import '../../../styles/_variables.scss';
|
||||
@import '../../../styles/_mixins.scss';
|
||||
|
||||
@mixin clamp($lines) {
|
||||
max-height: $lines * $line-height-base * $font-size-base;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
line-height: $line-height-base;
|
||||
overflow-wrap: break-word;
|
||||
|
||||
&:after {
|
||||
content: "...";
|
||||
color: $link-color;
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
padding-right: 15px;
|
||||
top: ($lines - 1) * $line-height-base * $font-size-base;
|
||||
right: 0;
|
||||
width: 30%;
|
||||
min-width: 75px;
|
||||
max-width: 150px;
|
||||
height: $line-height-base * $font-size-base;
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0), $body-bg 50%);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
.clamp-1 {
|
||||
@include clamp(1);
|
||||
}
|
||||
.clamp-2 {
|
||||
@include clamp(2);
|
||||
}
|
||||
.clamp-3 {
|
||||
@include clamp(3);
|
||||
}
|
||||
.clamp-15 {
|
||||
@include clamp(15);
|
||||
}
|
||||
|
||||
|
42
src/app/shared/truncatable/truncatable.component.ts
Normal file
42
src/app/shared/truncatable/truncatable.component.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import {
|
||||
Component, Input
|
||||
} from '@angular/core';
|
||||
import { TruncatableService } from './truncatable.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-truncatable',
|
||||
templateUrl: './truncatable.component.html',
|
||||
styleUrls: ['./truncatable.component.scss']
|
||||
})
|
||||
export class TruncatableComponent {
|
||||
@Input() minLines: number;
|
||||
@Input() maxLines: number;
|
||||
@Input() initialExpand = false;
|
||||
@Input() id: string;
|
||||
@Input() content;
|
||||
private lines: number;
|
||||
|
||||
public constructor(private service: TruncatableService) {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.initialExpand) {
|
||||
this.service.toggle(this.id);
|
||||
}
|
||||
this.setLines();
|
||||
}
|
||||
|
||||
public toggleCollapse() {
|
||||
this.service.toggle(this.id);
|
||||
this.setLines();
|
||||
}
|
||||
|
||||
private setLines() {
|
||||
if (this.service.isCollapsed(this.id)) {
|
||||
this.lines = this.minLines;
|
||||
} else {
|
||||
this.lines = this.maxLines;
|
||||
}
|
||||
}
|
||||
}
|
31
src/app/shared/truncatable/truncatable.reducer.ts
Normal file
31
src/app/shared/truncatable/truncatable.reducer.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { TruncatableAction, TruncatableActionTypes } from './truncatable.actions';
|
||||
|
||||
export interface TruncatableState {
|
||||
collapsed: boolean;
|
||||
}
|
||||
|
||||
export interface TruncatablesState {
|
||||
[id: string]: TruncatableState
|
||||
}
|
||||
|
||||
const initialState: TruncatablesState = Object.create(null);
|
||||
|
||||
export function truncatableReducer(state = initialState, action: TruncatableAction): TruncatablesState {
|
||||
|
||||
switch (action.type) {
|
||||
|
||||
case TruncatableActionTypes.TOGGLE: {
|
||||
if (!state[action.id]) {
|
||||
state[action.id] = {collapsed: false};
|
||||
}
|
||||
return Object.assign({}, state, {
|
||||
[action.id]: {
|
||||
collapsed: !state[action.id].collapsed,
|
||||
}
|
||||
});
|
||||
}
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
47
src/app/shared/truncatable/truncatable.service.ts
Normal file
47
src/app/shared/truncatable/truncatable.service.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { createSelector, MemoizedSelector, Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { TruncatablesState, TruncatableState } from './truncatable.reducer';
|
||||
import { TruncatableToggleAction } from './truncatable.actions';
|
||||
import { hasValue } from '../empty.util';
|
||||
|
||||
const truncatableStateSelector = (state: TruncatablesState) => state.truncatable;
|
||||
|
||||
@Injectable()
|
||||
export class TruncatableService {
|
||||
|
||||
constructor(private store: Store<TruncatablesState>) {
|
||||
}
|
||||
|
||||
isCollapsed(id: string): Observable<boolean> {
|
||||
return this.store.select(truncatableByIdSelector(id))
|
||||
.map((object: TruncatableState) => {
|
||||
console.log(object);
|
||||
if (object) {
|
||||
return object.collapsed;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public toggle(id: string): void {
|
||||
this.store.dispatch(new TruncatableToggleAction(id));
|
||||
}
|
||||
}
|
||||
|
||||
function truncatableByIdSelector(id: string): MemoizedSelector<TruncatablesState, TruncatableState> {
|
||||
return keySelector<TruncatableState>(id);
|
||||
}
|
||||
|
||||
export function keySelector<T>(key: string): MemoizedSelector<TruncatablesState, T> {
|
||||
return createSelector(truncatableStateSelector, (state: TruncatableState) => {
|
||||
console.log(state, 'test');
|
||||
|
||||
if (hasValue(state)) {
|
||||
return state[key];
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
import {
|
||||
Directive, ElementRef, Inject, Input, OnChanges, OnDestroy,
|
||||
OnInit
|
||||
} from '@angular/core';
|
||||
import { default as shave } from 'shave';
|
||||
import { NativeWindowRef, NativeWindowService } from '../window.service';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
@Directive({
|
||||
selector: '[dsShave]'
|
||||
})
|
||||
export class ShaveDirective implements OnDestroy, OnChanges {
|
||||
|
||||
@Input() shave: IShaveOptions = {};
|
||||
|
||||
@Input()
|
||||
set shaveHeight(value) {
|
||||
if (value > 0) {
|
||||
console.log(value);
|
||||
this._shaveHeight = value;
|
||||
}
|
||||
};
|
||||
|
||||
get shaveHeight() {
|
||||
return this._shaveHeight;
|
||||
}
|
||||
|
||||
private _shaveHeight = 72;
|
||||
private sub;
|
||||
|
||||
constructor(private ele: ElementRef, @Inject(NativeWindowService) private _window: NativeWindowRef) {
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
if (this.shaveHeight > 0) {
|
||||
this.runShave();
|
||||
}
|
||||
this.subscribeForResizeEvent();
|
||||
}
|
||||
|
||||
subscribeForResizeEvent() {
|
||||
const obs = Observable.fromEvent(this._window.nativeWindow, 'resize');
|
||||
this.sub = obs.subscribe((e) => this.runShave());
|
||||
}
|
||||
|
||||
private runShave() {
|
||||
shave(this.ele.nativeElement, this.shaveHeight, this.shave);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.sub) {
|
||||
this.sub.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,26 +1,3 @@
|
||||
@import '../../node_modules/bootstrap/scss/functions.scss';
|
||||
@import '../../node_modules/bootstrap/scss/mixins.scss';
|
||||
@import '../../node_modules/bootstrap/scss/variables.scss';
|
||||
|
||||
@mixin clamp($lines) {
|
||||
max-height: $lines * $line-height-base * $font-size-base;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
line-height: $line-height-base;
|
||||
overflow-wrap: break-word;
|
||||
|
||||
&:after {
|
||||
content: "...";
|
||||
color: $link-color;
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
padding-right: 15px;
|
||||
top: ($lines - 1) * $line-height-base * $font-size-base;
|
||||
right: 0;
|
||||
width: 30%;
|
||||
min-width: 75px;
|
||||
max-width: 150px;
|
||||
height: $line-height-base * $font-size-base;
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0), $body-bg 50%);
|
||||
}
|
||||
}
|
31
yarn.lock
31
yarn.lock
@@ -1942,10 +1942,6 @@ dom-serializer@0:
|
||||
domelementtype "~1.1.1"
|
||||
entities "~1.1.1"
|
||||
|
||||
dom-walk@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
|
||||
|
||||
domain-browser@^1.1.1:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
|
||||
@@ -2795,13 +2791,6 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, gl
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
global@^4.3.1:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
|
||||
dependencies:
|
||||
min-document "^2.19.0"
|
||||
process "~0.5.1"
|
||||
|
||||
globals@^9.18.0:
|
||||
version "9.18.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
|
||||
@@ -4443,12 +4432,6 @@ mimic-fn@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
|
||||
|
||||
min-document@^2.19.0:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
|
||||
dependencies:
|
||||
dom-walk "^0.1.0"
|
||||
|
||||
minimalistic-assert@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3"
|
||||
@@ -5798,10 +5781,6 @@ process@^0.11.0:
|
||||
version "0.11.10"
|
||||
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
||||
|
||||
process@~0.5.1:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
|
||||
|
||||
progress@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
|
||||
@@ -6668,10 +6647,6 @@ shallow-clone@^0.1.2:
|
||||
lazy-cache "^0.2.3"
|
||||
mixin-object "^2.0.1"
|
||||
|
||||
shave@^2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/shave/-/shave-2.1.3.tgz#89c7df997d35a95bc31703c9150161bc98d3fa3b"
|
||||
|
||||
shebang-command@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||
@@ -7165,12 +7140,6 @@ term-size@^1.2.0:
|
||||
dependencies:
|
||||
execa "^0.7.0"
|
||||
|
||||
text-overflow-clamp@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/text-overflow-clamp/-/text-overflow-clamp-1.0.0.tgz#9327faec1b85bf0b293d8c8df32243cbee5c050e"
|
||||
dependencies:
|
||||
global "^4.3.1"
|
||||
|
||||
throttleit@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c"
|
||||
|
Reference in New Issue
Block a user