diff --git a/src/app/+collection-page/edit-collection-page/edit-collection-page.component.ts b/src/app/+collection-page/edit-collection-page/edit-collection-page.component.ts index a3978a5e43ef49f41bd9ef7881277bf41f4b0c6b..ba70bd26c6ba5566dafa5114805d0dc7c8752c50 100644 --- a/src/app/+collection-page/edit-collection-page/edit-collection-page.component.ts +++ b/src/app/+collection-page/edit-collection-page/edit-collection-page.component.ts @@ -1,7 +1,6 @@ import { Component } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { EditComColPageComponent } from '../../shared/comcol-forms/edit-comcol-page/edit-comcol-page.component'; -import { NormalizedCollection } from '../../core/cache/models/normalized-collection.model'; import { Collection } from '../../core/shared/collection.model'; import { CollectionDataService } from '../../core/data/collection-data.service'; diff --git a/src/app/+item-page/edit-item-page/edit-item-page.component.ts b/src/app/+item-page/edit-item-page/edit-item-page.component.ts index 4ea47f08e73a48a1b05e1ab03f577374e754936f..eafc04ae0b491da4dbc070461974dfb2f80e63c7 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.component.ts +++ b/src/app/+item-page/edit-item-page/edit-item-page.component.ts @@ -1,6 +1,6 @@ import { fadeIn, fadeInOut } from '../../shared/animations/fade'; import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; -import { ActivatedRoute, Params, Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { RemoteData } from '../../core/data/remote-data'; import { Item } from '../../core/shared/item.model'; import { Observable } from 'rxjs'; diff --git a/src/app/+my-dspace-page/my-dspace-configuration.service.ts b/src/app/+my-dspace-page/my-dspace-configuration.service.ts index 4a065824258c893d8a10428cfb3cf55e3ff5faee..a580ba992019bbfeeff17790170a798053dd3efc 100644 --- a/src/app/+my-dspace-page/my-dspace-configuration.service.ts +++ b/src/app/+my-dspace-page/my-dspace-configuration.service.ts @@ -97,4 +97,8 @@ export class MyDSpaceConfigurationService extends SearchConfigurationService { ) } + public getCurrentView(): Observable<string> { + return this.routeService.getQueryParameterValue('view'); + } + } diff --git a/src/app/+my-dspace-page/my-dspace-page.component.html b/src/app/+my-dspace-page/my-dspace-page.component.html index 6f15070303eaa3e1d711e93e4c03e2f225a7b5d1..b38edebd97fb3196bfa28e70bcd8550a7acd375b 100644 --- a/src/app/+my-dspace-page/my-dspace-page.component.html +++ b/src/app/+my-dspace-page/my-dspace-page.component.html @@ -5,7 +5,8 @@ <ds-search-sidebar *ngIf="!(isXsOrSm$ | async)" class="col-3 sidebar-md-sticky" id="search-sidebar" [configurationList]="(configurationList$ | async)" - [resultCount]="(resultsRD$ | async)?.payload.totalElements"></ds-search-sidebar> + [resultCount]="(resultsRD$ | async)?.payload.totalElements" + [viewModeList]="viewModeList"></ds-search-sidebar> <div class="col-12 col-md-9"> <ds-search-form id="mydspace-form" [query]="(searchOptions$ | async)?.query" @@ -27,7 +28,7 @@ </ds-search-sidebar> <div id="mydspace-content" class="col-12"> <div class="d-block d-md-none search-controls clearfix"> - <ds-view-mode-switch></ds-view-mode-switch> + <ds-view-mode-switch [viewModeList]="viewModeList"></ds-view-mode-switch> <button (click)="openSidebar()" aria-controls="#mydspace-body" class="btn btn-outline-primary float-right open-sidebar"><i class="fas fa-sliders"></i> {{"search.sidebar.open" diff --git a/src/app/+my-dspace-page/my-dspace-page.component.ts b/src/app/+my-dspace-page/my-dspace-page.component.ts index 7afb8e2586fdfe75898a3a220c7616d39bc2d6b9..a173a39d99ba6831f26cd029f9d7eb6d9dc824ba 100644 --- a/src/app/+my-dspace-page/my-dspace-page.component.ts +++ b/src/app/+my-dspace-page/my-dspace-page.component.ts @@ -1,13 +1,14 @@ import { ChangeDetectionStrategy, Component, Inject, InjectionToken, OnInit } from '@angular/core'; + import { BehaviorSubject, Observable, Subscription } from 'rxjs'; -import { switchMap, } from 'rxjs/operators'; +import { switchMap, tap, } from 'rxjs/operators'; + import { PaginatedList } from '../core/data/paginated-list'; import { RemoteData } from '../core/data/remote-data'; import { DSpaceObject } from '../core/shared/dspace-object.model'; import { pushInOut } from '../shared/animations/push'; import { HostWindowService } from '../shared/host-window.service'; import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model'; -import { SearchFilterService } from '../+search-page/search-filters/search-filter/search-filter.service'; import { SearchService } from '../+search-page/search-service/search.service'; import { SearchSidebarService } from '../+search-page/search-sidebar/search-sidebar.service'; import { hasValue } from '../shared/empty.util'; @@ -18,6 +19,7 @@ import { SearchConfigurationOption } from '../+search-page/search-switch-configu import { RoleType } from '../core/roles/role-types'; import { SearchConfigurationService } from '../+search-page/search-service/search-configuration.service'; import { MyDSpaceConfigurationService } from './my-dspace-configuration.service'; +import { ViewMode } from '../core/shared/view-mode.model'; export const MYDSPACE_ROUTE = '/mydspace'; export const SEARCH_CONFIG_SERVICE: InjectionToken<SearchConfigurationService> = new InjectionToken<SearchConfigurationService>('searchConfigurationService'); @@ -79,10 +81,11 @@ export class MyDSpacePageComponent implements OnInit { roleTypeEnum = RoleType; + viewModeList = [ViewMode.List, ViewMode.Detail]; + constructor(private service: SearchService, private sidebarService: SearchSidebarService, private windowService: HostWindowService, - private filterService: SearchFilterService, @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: MyDSpaceConfigurationService) { this.isXsOrSm$ = this.windowService.isXsOrSm(); this.service.setServiceOptions(MyDSpaceResponseParsingService, true); @@ -97,10 +100,11 @@ export class MyDSpacePageComponent implements OnInit { */ ngOnInit(): void { this.configurationList$ = this.searchConfigService.getAvailableConfigurationOptions(); - this.searchOptions$ = this.searchConfigService.paginatedSearchOptions; + this.sub = this.searchOptions$.pipe( - switchMap((options) => this.service.search(options).pipe(getSucceededRemoteData()))) + tap(() => this.resultsRD$.next(null)), + switchMap((options: PaginatedSearchOptions) => this.service.search(options).pipe(getSucceededRemoteData()))) .subscribe((results) => { this.resultsRD$.next(results); }); diff --git a/src/app/+my-dspace-page/my-dspace-result.model.ts b/src/app/+my-dspace-page/my-dspace-result.model.ts index f8902f310ba849680c17625d07e67c1c7ba7fab1..5605c746e8603b70627d26ea6169dcfe470832af 100644 --- a/src/app/+my-dspace-page/my-dspace-result.model.ts +++ b/src/app/+my-dspace-page/my-dspace-result.model.ts @@ -1,5 +1,5 @@ import { DSpaceObject } from '../core/shared/dspace-object.model'; -import { MetadataMap } from '../core/shared/metadata.interfaces'; +import { MetadataMap } from '../core/shared/metadata.models'; import { ListableObject } from '../shared/object-collection/shared/listable-object.model'; /** diff --git a/src/app/+my-dspace-page/my-dspace-results/my-dspace-results.component.html b/src/app/+my-dspace-page/my-dspace-results/my-dspace-results.component.html index 29a5ab41cda17a0399d0eda6cdc1b36991874b16..132a0d22040141c37952b2c8ad9937ff6977691c 100644 --- a/src/app/+my-dspace-page/my-dspace-results/my-dspace-results.component.html +++ b/src/app/+my-dspace-page/my-dspace-results/my-dspace-results.component.html @@ -7,6 +7,6 @@ [hideGear]="true"> </ds-viewable-collection> </div> -<ds-loading *ngIf="!searchResults || searchResults?.isLoading" message="{{'loading.mydspace-results' | translate}}"></ds-loading> +<ds-loading *ngIf="isLoading()" message="{{'loading.mydspace-results' | translate}}"></ds-loading> <ds-error *ngIf="searchResults?.hasFailed && (!searchResults?.error || searchResults?.error?.statusCode != 400)" message="{{'error.search-results' | translate}}"></ds-error> <h3 *ngIf="searchResults?.payload?.page.length == 0" class="text-center text-muted" ><span>{{'mydspace.results.no-results' | translate}}</span></h3> diff --git a/src/app/+my-dspace-page/my-dspace-results/my-dspace-results.component.ts b/src/app/+my-dspace-page/my-dspace-results/my-dspace-results.component.ts index 1058a3eefd1167596fb4ffecca981af7343b3a26..e6a086fd46cf663677571dd1c825444caa8ca322 100644 --- a/src/app/+my-dspace-page/my-dspace-results/my-dspace-results.component.ts +++ b/src/app/+my-dspace-page/my-dspace-results/my-dspace-results.component.ts @@ -8,6 +8,7 @@ import { MyDSpaceResult } from '../my-dspace-result.model'; import { SearchOptions } from '../../+search-page/search-options.model'; import { PaginatedList } from '../../core/data/paginated-list'; import { ViewMode } from '../../core/shared/view-mode.model'; +import { isEmpty } from '../../shared/empty.util'; /** * This component renders a simple item page. @@ -28,6 +29,9 @@ export class MyDSpaceResultsComponent { @Input() sortConfig: SortOptions; @Input() viewMode: ViewMode; - public hasBorder = true; + hasBorder = true; + isLoading() { + return !this.searchResults || isEmpty(this.searchResults) || this.searchResults.isLoading; + } } diff --git a/src/app/+search-page/search-service/search.service.ts b/src/app/+search-page/search-service/search.service.ts index 1d5ff0619371234fba63d8a111dea773beecd841..e98fecd830146e2e81672cedddfa7128552b7af9 100644 --- a/src/app/+search-page/search-service/search.service.ts +++ b/src/app/+search-page/search-service/search.service.ts @@ -1,13 +1,7 @@ import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; import { Injectable, OnDestroy } from '@angular/core'; -import { - ActivatedRoute, - NavigationExtras, - PRIMARY_OUTLET, - Router, - UrlSegmentGroup -} from '@angular/router'; -import { distinctUntilChanged, filter, first, map, switchMap, take, tap } from 'rxjs/operators'; +import { ActivatedRoute, NavigationExtras, PRIMARY_OUTLET, Router, UrlSegmentGroup } from '@angular/router'; +import { first, map, switchMap } from 'rxjs/operators'; import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service'; import { FacetConfigSuccessResponse, @@ -22,11 +16,7 @@ import { RequestService } from '../../core/data/request.service'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { GenericConstructor } from '../../core/shared/generic-constructor'; import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; -import { - configureRequest, filterSuccessfulResponses, - getResponseFromEntry, - getSucceededRemoteData -} from '../../core/shared/operators'; +import { configureRequest, getResponseFromEntry, getSucceededRemoteData } from '../../core/shared/operators'; import { URLCombiner } from '../../core/url-combiner/url-combiner'; import { hasValue, isEmpty, isNotEmpty, isNotUndefined } from '../../shared/empty.util'; import { NormalizedSearchResult } from '../normalized-search-result.model'; @@ -47,6 +37,7 @@ import { CommunityDataService } from '../../core/data/community-data.service'; import { ViewMode } from '../../core/shared/view-mode.model'; import { ResourceType } from '../../core/shared/resource-type'; import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; +import { RouteService } from '../../shared/services/route.service'; /** * Service that performs all general actions that have to do with the search page @@ -80,6 +71,7 @@ export class SearchService implements OnDestroy { constructor(private router: Router, private route: ActivatedRoute, + private routeService: RouteService, protected requestService: RequestService, private rdb: RemoteDataBuildService, private halService: HALEndpointService, @@ -235,7 +227,6 @@ export class SearchService implements OnDestroy { * @returns {Observable<RemoteData<PaginatedList<FacetValue>>>} Emits the given page of facet values */ getFacetValuesFor(filterConfig: SearchFilterConfig, valuePage: number, searchOptions?: SearchOptions, filterQuery?: string): Observable<RemoteData<PaginatedList<FacetValue>>> { - console.log('getFacetValuesFor'); const requestObs = this.halService.getEndpoint(this.facetLinkPathPrefix + filterConfig.name).pipe( map((url: string) => { const args: string[] = [`page=${valuePage - 1}`, `size=${filterConfig.pageSize}`]; @@ -323,9 +314,9 @@ export class SearchService implements OnDestroy { * @returns {Observable<ViewMode>} The current view mode */ getViewMode(): Observable<ViewMode> { - return this.route.queryParams.pipe(map((params) => { - if (isNotEmpty(params.view) && hasValue(params.view)) { - return params.view; + return this.routeService.getQueryParamMap().pipe(map((params) => { + if (isNotEmpty(params.get('view')) && hasValue(params.get('view'))) { + return params.get('view'); } else { return ViewMode.List; } @@ -337,12 +328,21 @@ export class SearchService implements OnDestroy { * @param {ViewMode} viewMode Mode to switch to */ setViewMode(viewMode: ViewMode) { - const navigationExtras: NavigationExtras = { - queryParams: { view: viewMode }, - queryParamsHandling: 'merge' - }; + this.routeService.getQueryParameterValue('pageSize').pipe(first()) + .subscribe((pageSize) => { + let queryParams = { view: viewMode }; + if (viewMode === ViewMode.Detail) { + queryParams = Object.assign(queryParams, {pageSize: '1'}); + } else if (pageSize === '1') { + queryParams = Object.assign(queryParams, {pageSize: '10'}); + } + const navigationExtras: NavigationExtras = { + queryParams: queryParams, + queryParamsHandling: 'merge' + }; - this.router.navigate([this.getSearchLink()], navigationExtras); + this.router.navigate([this.getSearchLink()], navigationExtras); + }) } /** diff --git a/src/app/+search-page/search-settings/search-settings.component.ts b/src/app/+search-page/search-settings/search-settings.component.ts index 24b2ee4778d1387110bf61378f542c20fc3f9c42..d26545b7f1afbf10b22ff5ffdf98659d74e349a7 100644 --- a/src/app/+search-page/search-settings/search-settings.component.ts +++ b/src/app/+search-page/search-settings/search-settings.component.ts @@ -54,7 +54,7 @@ export class SearchSettingsComponent implements OnInit { }, queryParamsHandling: 'merge' }; - this.router.navigate([ '/search' ], navigationExtras); + this.router.navigate([ this.service.getSearchLink() ], navigationExtras); } /** @@ -71,6 +71,6 @@ export class SearchSettingsComponent implements OnInit { }, queryParamsHandling: 'merge' }; - this.router.navigate([ '/search' ], navigationExtras); + this.router.navigate([ this.service.getSearchLink() ], navigationExtras); } } diff --git a/src/app/+search-page/search-sidebar/search-sidebar.component.html b/src/app/+search-page/search-sidebar/search-sidebar.component.html index ac9c83444343165ca82317a8348b9dd044096c5d..3934f8cdacf5d7b1809a166f0064dd819964b524 100644 --- a/src/app/+search-page/search-sidebar/search-sidebar.component.html +++ b/src/app/+search-page/search-sidebar/search-sidebar.component.html @@ -8,7 +8,7 @@ </button> </div> <div id="search-sidebar-content"> - <ds-view-mode-switch class="d-none d-md-block"></ds-view-mode-switch> + <ds-view-mode-switch [viewModeList]="viewModeList" class="d-none d-md-block"></ds-view-mode-switch> <div class="sidebar-content"> <ds-search-switch-configuration *ngIf="configurationList" [configurationList]="configurationList"></ds-search-switch-configuration> <ds-search-filters></ds-search-filters> diff --git a/src/app/+search-page/search-sidebar/search-sidebar.component.ts b/src/app/+search-page/search-sidebar/search-sidebar.component.ts index bdd90633b0366406d0aed3505c360c7386909780..9abcf71dcb92d74b2a8f91ec961096182ae6357b 100644 --- a/src/app/+search-page/search-sidebar/search-sidebar.component.ts +++ b/src/app/+search-page/search-sidebar/search-sidebar.component.ts @@ -29,6 +29,11 @@ export class SearchSidebarComponent { */ @Input() resultCount; + /** + * The list of available view mode options + */ + @Input() viewModeList; + /** * Emits event when the user clicks a button to open or close the sidebar */ diff --git a/src/app/core/auth/auth.service.ts b/src/app/core/auth/auth.service.ts index fdb372f643ae1b18cdcf7d4f24a2458d77e53253..aac8953098861188ff53ec8200d8c20277459cd9 100644 --- a/src/app/core/auth/auth.service.ts +++ b/src/app/core/auth/auth.service.ts @@ -1,43 +1,27 @@ -import {Observable, of, of as observableOf} from 'rxjs'; -import { - distinctUntilChanged, - filter, - first, - map, - startWith, - switchMap, - take, - withLatestFrom -} from 'rxjs/operators'; import { Inject, Injectable, Optional } from '@angular/core'; import { PRIMARY_OUTLET, Router, UrlSegmentGroup, UrlTree } from '@angular/router'; import { HttpHeaders } from '@angular/common/http'; import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens'; +import { Observable, of as observableOf } from 'rxjs'; +import { distinctUntilChanged, filter, map, startWith, switchMap, take, withLatestFrom } from 'rxjs/operators'; import { RouterReducerState } from '@ngrx/router-store'; import { select, Store } from '@ngrx/store'; import { CookieAttributes } from 'js-cookie'; import { EPerson } from '../eperson/models/eperson.model'; import { AuthRequestService } from './auth-request.service'; - import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service'; import { AuthStatus } from './models/auth-status.model'; import { AuthTokenInfo, TOKENITEM } from './models/auth-token-info.model'; import { isEmpty, isNotEmpty, isNotNull, isNotUndefined } from '../../shared/empty.util'; import { CookieService } from '../../shared/services/cookie.service'; -import { - getAuthenticationToken, - getRedirectUrl, - isAuthenticated, - isTokenRefreshing -} from './selectors'; +import { getAuthenticationToken, getRedirectUrl, isAuthenticated, isTokenRefreshing } from './selectors'; import { AppState, routerStateSelector } from '../../app.reducer'; import { ResetAuthenticationMessagesAction, SetRedirectUrlAction } from './auth.actions'; import { NativeWindowRef, NativeWindowService } from '../../shared/services/window.service'; import { Base64EncodeUrl } from '../../shared/utils/encode-decode.util'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { NormalizedEPerson } from '../eperson/models/normalized-eperson.model'; export const LOGIN_ROUTE = '/login'; export const LOGOUT_ROUTE = '/logout'; diff --git a/src/app/core/data/collection-data.service.ts b/src/app/core/data/collection-data.service.ts index 1e7f9ec074ce3bfcacb949508fd43e92095d64c0..993954a360ae6d4c265722e99229dc518f34b77e 100644 --- a/src/app/core/data/collection-data.service.ts +++ b/src/app/core/data/collection-data.service.ts @@ -4,7 +4,6 @@ import { filter, map, take } from 'rxjs/operators'; import { Store } from '@ngrx/store'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { NormalizedCollection } from '../cache/models/normalized-collection.model'; import { ObjectCacheService } from '../cache/object-cache.service'; import { CoreState } from '../core.reducers'; import { Collection } from '../shared/collection.model'; diff --git a/src/app/core/data/community-data.service.ts b/src/app/core/data/community-data.service.ts index 75ef58b06bb8c7c47a461813dd1cd3b64fbc52e7..8db4d762eb69fa104ff85d3a5e5839893d688aeb 100644 --- a/src/app/core/data/community-data.service.ts +++ b/src/app/core/data/community-data.service.ts @@ -1,9 +1,8 @@ -import { filter, mergeMap, take } from 'rxjs/operators'; +import { filter, take } from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { NormalizedCommunity } from '../cache/models/normalized-community.model'; import { ObjectCacheService } from '../cache/object-cache.service'; import { CoreState } from '../core.reducers'; import { Community } from '../shared/community.model'; @@ -12,7 +11,7 @@ import { RequestService } from './request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { FindAllOptions, FindAllRequest } from './request.models'; import { RemoteData } from './remote-data'; -import { hasValue, isNotEmpty } from '../../shared/empty.util'; +import { hasValue } from '../../shared/empty.util'; import { Observable } from 'rxjs'; import { PaginatedList } from './paginated-list'; import { NotificationsService } from '../../shared/notifications/notifications.service'; diff --git a/src/app/core/data/default-change-analyzer.service.ts b/src/app/core/data/default-change-analyzer.service.ts index 1fd207d2bffa0a16741bb049d8ed0876942eee72..cd30479f6df00ea59e537d967a3259fc638b1f24 100644 --- a/src/app/core/data/default-change-analyzer.service.ts +++ b/src/app/core/data/default-change-analyzer.service.ts @@ -1,9 +1,7 @@ import { Operation } from 'fast-json-patch/lib/core'; import { compare } from 'fast-json-patch'; import { ChangeAnalyzer } from './change-analyzer'; -import { NormalizedDSpaceObject } from '../cache/models/normalized-dspace-object.model'; import { Injectable } from '@angular/core'; -import { DSpaceObject } from '../shared/dspace-object.model'; import { CacheableObject } from '../cache/object-cache.reducer'; import { NormalizedObject } from '../cache/models/normalized-object.model'; diff --git a/src/app/core/data/mydspace-response-parsing.service.ts b/src/app/core/data/mydspace-response-parsing.service.ts index a99661faed44d8eeee8295d1723e3f2f1d567617..9cd2103657ccebbe2784162b88907d442efa7538 100644 --- a/src/app/core/data/mydspace-response-parsing.service.ts +++ b/src/app/core/data/mydspace-response-parsing.service.ts @@ -7,7 +7,7 @@ import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response. import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer'; import { hasValue } from '../../shared/empty.util'; import { SearchQueryResponse } from '../../+search-page/search-service/search-query-response.model'; -import { MetadataMap, MetadataValue } from '../shared/metadata.interfaces'; +import { MetadataMap, MetadataValue } from '../shared/metadata.models'; @Injectable() export class MyDSpaceResponseParsingService implements ResponseParsingService { @@ -17,7 +17,7 @@ export class MyDSpaceResponseParsingService implements ResponseParsingService { parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse { // fallback for unexpected empty response const emptyPayload = { - _embedded : { + _embedded: { objects: [] } }; @@ -28,8 +28,11 @@ export class MyDSpaceResponseParsingService implements ResponseParsingService { const mdMap: MetadataMap = {}; if (hhObject) { for (const key of Object.keys(hhObject)) { - const value: MetadataValue = { value: hhObject[key].join('...'), language: null }; - mdMap[key] = [ value ]; + const value: MetadataValue = Object.assign(new MetadataValue(), { + value: hhObject[key].join('...'), + language: null + }); + mdMap[key] = [value]; } } return mdMap; @@ -50,10 +53,30 @@ export class MyDSpaceResponseParsingService implements ResponseParsingService { .filter((object) => hasValue(object._embedded)) .map((object, index) => Object.assign({}, object, { rObject: dsoSelfLinks[index], - hitHighlights: hitHighlights[index] + hitHighlights: hitHighlights[index], + _embedded: this.filterEmbeddedObjects(object) })); payload.objects = objects; const deserialized = new DSpaceRESTv2Serializer(SearchQueryResponse).deserialize(payload); return new SearchSuccessResponse(deserialized, data.statusCode, data.statusText, this.dsoParser.processPageInfo(payload)); } + + protected filterEmbeddedObjects(object) { + const allowedEmbeddedKeys = ['submitter', 'item', 'workspaceitem', 'workflowitem']; + if (object._embedded.rObject && object._embedded.rObject._embedded) { + return Object.assign({}, object._embedded, { + rObject: Object.assign({}, object._embedded.rObject, { + _embedded: Object.keys(object._embedded.rObject._embedded) + .filter((key) => allowedEmbeddedKeys.includes(key)) + .reduce((obj, key) => { + obj[key] = object._embedded.rObject._embedded[key]; + return obj; + }, {}) + }) + }); + } else { + return object; + } + + } } diff --git a/src/app/core/data/request.service.ts b/src/app/core/data/request.service.ts index cdf7dd6de0e036cee80cdcb4abe36a54121d7537..fa6adfcc3650c48e7afdedb84013154487f7fc4b 100644 --- a/src/app/core/data/request.service.ts +++ b/src/app/core/data/request.service.ts @@ -253,11 +253,10 @@ export class RequestService { } /** - * This method will store the href of every GET request that gets configured in a local variable, and - * remove it as soon as it can be found in the store. + * This method remove requests that are on their way to the store. */ private clearRequestsOnTheirWayToTheStore(request: GetRequest) { - this.store.pipe(select(this.entryFromUUIDSelector(request.uuid)), + this.getByHref(request.href).pipe( find((re: RequestEntry) => hasValue(re))) .subscribe((re: RequestEntry) => { if (!re.responsePending) { @@ -265,6 +264,7 @@ export class RequestService { } }); } + /** * Dispatch commit action to send all changes (for a certain method) to the server (buffer) * @param {RestRequestMethod} method RestRequestMethod for which the changes should be committed diff --git a/src/app/core/eperson/models/normalized-eperson.model.ts b/src/app/core/eperson/models/normalized-eperson.model.ts index 1032c84db1ee7fd70bda31ea3f3d9e233f1aca2d..6bb66e93e6e34a4f9f295d36ea7cc0355c19c158 100644 --- a/src/app/core/eperson/models/normalized-eperson.model.ts +++ b/src/app/core/eperson/models/normalized-eperson.model.ts @@ -14,9 +14,6 @@ export class NormalizedEPerson extends NormalizedDSpaceObject<EPerson> implement @autoserialize public handle: string; - @autoserialize - public name: string; - @autoserializeAs(NormalizedGroup) groups: Group[]; diff --git a/src/app/core/message/message-response-parsing.service.ts b/src/app/core/message/message-response-parsing.service.ts index 1a08ab481d4b18c77883590e82a15cb83c30c0dc..eea3f2659fd7701e9b0e145b9e7616dbc00a7b0b 100644 --- a/src/app/core/message/message-response-parsing.service.ts +++ b/src/app/core/message/message-response-parsing.service.ts @@ -7,13 +7,13 @@ import { BaseResponseParsingService } from '../data/base-response-parsing.servic import { GLOBAL_CONFIG } from '../../../config'; import { GlobalConfig } from '../../../config/global-config.interface'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { NormalizedSubmissionObjectFactory } from '../submission/normalized-submission-object-factory'; import { ErrorResponse, MessageResponse, RestResponse } from '../cache/response.models'; +import { NormalizedObjectFactory } from '../cache/models/normalized-object-factory'; @Injectable() export class MessageResponseParsingService extends BaseResponseParsingService implements ResponseParsingService { - protected objectFactory = NormalizedSubmissionObjectFactory; + protected objectFactory = NormalizedObjectFactory; protected toCache = false; constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig, diff --git a/src/app/core/tasks/claimed-task-data.service.ts b/src/app/core/tasks/claimed-task-data.service.ts index f35c999ac5bc32be3061b1c2dbac4e312ea88569..f1175d1b1cf0fd55046485daeab585cb5bf6b551 100644 --- a/src/app/core/tasks/claimed-task-data.service.ts +++ b/src/app/core/tasks/claimed-task-data.service.ts @@ -7,7 +7,6 @@ import { Observable } from 'rxjs'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { CoreState } from '../core.reducers'; import { RequestService } from '../data/request.service'; -import { NormalizedClaimedTask } from './models/normalized-claimed-task-object.model'; import { ClaimedTask } from './models/claimed-task-object.model'; import { TasksService } from './tasks.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -17,7 +16,7 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; @Injectable() -export class ClaimedTaskDataService extends TasksService<NormalizedClaimedTask, ClaimedTask> { +export class ClaimedTaskDataService extends TasksService<ClaimedTask> { protected linkPath = 'claimedtasks'; protected forceBypassCache = true; @@ -30,7 +29,7 @@ export class ClaimedTaskDataService extends TasksService<NormalizedClaimedTask, protected halService: HALEndpointService, protected notificationsService: NotificationsService, protected http: HttpClient, - protected comparator: DSOChangeAnalyzer) { + protected comparator: DSOChangeAnalyzer<ClaimedTask>) { super(); } diff --git a/src/app/core/tasks/models/normalized-claimed-task-object.model.ts b/src/app/core/tasks/models/normalized-claimed-task-object.model.ts index 5b8604ac42812b05f4fc2657d5f23a5cf67ad129..e6a9096cb4700d11b8f6c767afb6e15bb96b43fe 100644 --- a/src/app/core/tasks/models/normalized-claimed-task-object.model.ts +++ b/src/app/core/tasks/models/normalized-claimed-task-object.model.ts @@ -9,7 +9,7 @@ import { ResourceType } from '../../shared/resource-type'; */ @mapsTo(ClaimedTask) @inheritSerialization(NormalizedTaskObject) -export class NormalizedClaimedTask extends NormalizedTaskObject { +export class NormalizedClaimedTask extends NormalizedTaskObject<ClaimedTask> { /** * The task identifier diff --git a/src/app/core/tasks/models/normalized-pool-task-object.model.ts b/src/app/core/tasks/models/normalized-pool-task-object.model.ts index 15152b4f5a455114a25b9aac92b490ba472d65a5..beb2d15e8c9760a63e39513e427be35207758d60 100644 --- a/src/app/core/tasks/models/normalized-pool-task-object.model.ts +++ b/src/app/core/tasks/models/normalized-pool-task-object.model.ts @@ -9,7 +9,7 @@ import { ResourceType } from '../../shared/resource-type'; */ @mapsTo(PoolTask) @inheritSerialization(NormalizedTaskObject) -export class NormalizedPoolTask extends NormalizedTaskObject { +export class NormalizedPoolTask extends NormalizedTaskObject<PoolTask> { /** * The task identifier diff --git a/src/app/core/tasks/models/normalized-task-object.model.ts b/src/app/core/tasks/models/normalized-task-object.model.ts index 4a41ec983a6830513b2da68f8037e95a20652727..7e0fb3f6bb42ea3edf7f6941cb83aca4037b5c5b 100644 --- a/src/app/core/tasks/models/normalized-task-object.model.ts +++ b/src/app/core/tasks/models/normalized-task-object.model.ts @@ -3,13 +3,14 @@ import { mapsTo, relationship } from '../../cache/builders/build-decorators'; import { ResourceType } from '../../shared/resource-type'; import { NormalizedDSpaceObject } from '../../cache/models/normalized-dspace-object.model'; import { TaskObject } from './task-object.model'; +import { DSpaceObject } from '../../shared/dspace-object.model'; /** * An abstract model class for a DSpaceObject. */ @mapsTo(TaskObject) @inheritSerialization(NormalizedDSpaceObject) -export abstract class NormalizedTaskObject extends NormalizedDSpaceObject { +export abstract class NormalizedTaskObject<T extends DSpaceObject> extends NormalizedDSpaceObject<T> { /** * The task identifier diff --git a/src/app/core/tasks/pool-task-data.service.ts b/src/app/core/tasks/pool-task-data.service.ts index df2c05fe6d2206499d336f82111e9f44d11ab136..fb1d53420b1ae827d1ae77764b1c34ce06b4e841 100644 --- a/src/app/core/tasks/pool-task-data.service.ts +++ b/src/app/core/tasks/pool-task-data.service.ts @@ -7,7 +7,6 @@ import { Store } from '@ngrx/store'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { CoreState } from '../core.reducers'; import { RequestService } from '../data/request.service'; -import { NormalizedPoolTask } from './models/normalized-pool-task-object.model'; import { PoolTask } from './models/pool-task-object.model'; import { TasksService } from './tasks.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -17,7 +16,7 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; @Injectable() -export class PoolTaskDataService extends TasksService<NormalizedPoolTask, PoolTask> { +export class PoolTaskDataService extends TasksService<PoolTask> { protected linkPath = 'pooltasks'; protected forceBypassCache = true; @@ -30,7 +29,7 @@ export class PoolTaskDataService extends TasksService<NormalizedPoolTask, PoolTa protected halService: HALEndpointService, protected notificationsService: NotificationsService, protected http: HttpClient, - protected comparator: DSOChangeAnalyzer) { + protected comparator: DSOChangeAnalyzer<PoolTask>) { super(); } diff --git a/src/app/core/tasks/tasks.service.ts b/src/app/core/tasks/tasks.service.ts index 7b42d950507d5603189c684afcf899d5a17b7674..19ef81bd190d6ef8bf5fc429b99927055cca4f8c 100644 --- a/src/app/core/tasks/tasks.service.ts +++ b/src/app/core/tasks/tasks.service.ts @@ -9,12 +9,11 @@ import { isNotEmpty } from '../../shared/empty.util'; import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service'; import { ProcessTaskResponse } from './models/process-task-response'; import { RemoteDataError } from '../data/remote-data-error'; -import { NormalizedObject } from '../cache/models/normalized-object.model'; import { getResponseFromEntry } from '../shared/operators'; import { ErrorResponse, MessageResponse, RestResponse } from '../cache/response.models'; import { CacheableObject } from '../cache/object-cache.reducer'; -export abstract class TasksService<TNormalized extends NormalizedObject, TDomain extends CacheableObject> extends DataService<TNormalized, TDomain> { +export abstract class TasksService<T extends CacheableObject> extends DataService<T> { public getBrowseEndpoint(options: FindAllOptions): Observable<string> { return this.halService.getEndpoint(this.linkPath); @@ -34,7 +33,7 @@ export abstract class TasksService<TNormalized extends NormalizedObject, TDomain )); const successResponses = responses.pipe( filter((response: RestResponse) => response.isSuccessful), - map((response: MessageResponse) => new ProcessTaskResponse(response.isSuccessful)), + map((response: MessageResponse) => new ProcessTaskResponse(response.isSuccessful)), distinctUntilChanged() ); return observableMerge(errorResponses, successResponses); diff --git a/src/app/shared/auth-nav-menu/user-menu/user-menu.component.html b/src/app/shared/auth-nav-menu/user-menu/user-menu.component.html index 7c576fee86aadedbc833d4b423ffb15b576d4237..fef47b395b94652910bbfbaccffe2d873eb32a14 100644 --- a/src/app/shared/auth-nav-menu/user-menu/user-menu.component.html +++ b/src/app/shared/auth-nav-menu/user-menu/user-menu.component.html @@ -1,7 +1,7 @@ <ds-loading *ngIf="(loading$ | async)"></ds-loading> <div *ngIf="!(loading$ | async)"> - <span class="dropdown-item-text">{{(user$ | async).name}}</span> - <a class="dropdown-item" [routerLink]="['/mydspace']" routerLinkActive="active">{{'nav.mydspace' | translate}}</a> + <span class="dropdown-item-text">{{(user$ | async)?.name}} ({{(user$ | async)?.email}})</span> + <a class="dropdown-item" [routerLink]="[mydspaceRoute]" routerLinkActive="active">{{'nav.mydspace' | translate}}</a> <div class="dropdown-divider"></div> <ds-log-out></ds-log-out> </div> diff --git a/src/app/shared/auth-nav-menu/user-menu/user-menu.component.ts b/src/app/shared/auth-nav-menu/user-menu/user-menu.component.ts index 452e5b30caa1ec17fd01b5c108049a37a8bc94cb..62391dc780a7534118d4167951ba8b8421e8e53d 100644 --- a/src/app/shared/auth-nav-menu/user-menu/user-menu.component.ts +++ b/src/app/shared/auth-nav-menu/user-menu/user-menu.component.ts @@ -6,6 +6,7 @@ import { select, Store } from '@ngrx/store'; import { EPerson } from '../../../core/eperson/models/eperson.model'; import { AppState } from '../../../app.reducer'; import { getAuthenticatedUser, isAuthenticationLoading } from '../../../core/auth/selectors'; +import { MYDSPACE_ROUTE } from '../../../+my-dspace-page/my-dspace-page.component'; @Component({ selector: 'ds-user-menu', @@ -26,6 +27,12 @@ export class UserMenuComponent implements OnInit { */ public user$: Observable<EPerson>; + /** + * The mydspace page route. + * @type {string} + */ + public mydspaceRoute = MYDSPACE_ROUTE; + constructor(private store: Store<AppState>) { } diff --git a/src/app/shared/input-suggestions/input-suggestions.component.ts b/src/app/shared/input-suggestions/input-suggestions.component.ts index 727421c83ec0e5fe3f1c962c9a9b2e430db7672b..9f59f42cc411731f5fd3d6597700d765feb40d31 100644 --- a/src/app/shared/input-suggestions/input-suggestions.component.ts +++ b/src/app/shared/input-suggestions/input-suggestions.component.ts @@ -12,7 +12,7 @@ import { ViewChildren } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; -import { hasValue, isNotEmpty, isNotUndefined } from '../empty.util'; +import { hasValue, isNotEmpty } from '../empty.util'; import { InputSuggestion } from './input-suggestions.model'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; diff --git a/src/app/shared/message-board/message-board.component.ts b/src/app/shared/message-board/message-board.component.ts index 3b5b2186ebf4331dca37cd2c785402fdca5228e1..e05db8a9d63d9b93477e8c0b0d216fbc1e5841af 100644 --- a/src/app/shared/message-board/message-board.component.ts +++ b/src/app/shared/message-board/message-board.component.ts @@ -12,7 +12,6 @@ import { mergeMap, reduce, startWith, - tap, withLatestFrom } from 'rxjs/operators'; import { select, Store } from '@ngrx/store'; @@ -77,31 +76,26 @@ export class MessageBoardComponent implements OnDestroy { this.user$ = this.store.pipe( select(getAuthenticatedUser), find((user: EPerson) => isNotEmpty(user)), - map((user: EPerson) => user), - tap((u) => console.log(u))); + map((user: EPerson) => user)); this.item$ = this.dso.item.pipe( find((rd: RemoteData<Item>) => (rd.hasSucceeded && isNotEmpty(rd.payload))), - map((rd: RemoteData<Item>) => rd.payload), - tap((u) => console.log(u))); + map((rd: RemoteData<Item>) => rd.payload)); this.submitter$ = (this.dso.submitter as Observable<RemoteData<EPerson[]>>).pipe( find((rd: RemoteData<EPerson>) => rd.hasSucceeded && isNotEmpty(rd.payload)), - map((rd: RemoteData<EPerson>) => rd.payload), - tap((u) => console.log(u))); + map((rd: RemoteData<EPerson>) => rd.payload)); this.isSubmitter$ = combineLatest(this.user$, this.submitter$).pipe( filter(([user, submitter]) => isNotEmpty(user) && isNotEmpty(submitter)), - map(([user, submitter]) => user.uuid === submitter.uuid), - tap((u) => console.log(u))); + map(([user, submitter]) => user.uuid === submitter.uuid)); this.messages$ = this.item$.pipe( find((item: Item) => isNotEmpty(item)), flatMap((item: Item) => item.getBitstreamsByBundleName('MESSAGE')), filter((bitStreams: Bitstream[]) => isNotEmpty(bitStreams)), startWith([]), - distinctUntilChanged(), - tap((u) => console.log(u))); + distinctUntilChanged()); this.unreadMessages$ = this.messages$.pipe( filter((messages: Bitstream[]) => isNotEmpty(messages)), @@ -118,8 +112,7 @@ export class MessageBoardComponent implements OnDestroy { this.itemUUID$ = this.item$.pipe( find((item: Item) => isNotEmpty(item)), - map((item: Item) => item.uuid), - tap((u) => console.log(u))); + map((item: Item) => item.uuid)); } diff --git a/src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.html b/src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.html index ced206ac531c417b13c9a08759abc157184437fc..ae9231703749bf46351e4724d95bf55779629e43 100644 --- a/src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.html +++ b/src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.html @@ -22,7 +22,7 @@ ngbTooltip="{{'submission.workflow.tasks.claimed.return_help' | translate}}" [disabled]="(processingReturnToPool$ | async)" (click)="returnToPool()"> - <span *ngIf="(processingReturnToPool$ | async)"><i class='fa fa-circle-o-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}</span> + <span *ngIf="(processingReturnToPool$ | async)"><i class='fas fa-circle-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}</span> <span *ngIf="!(processingReturnToPool$ | async)"><i class="fa fa-undo"></i> {{'submission.workflow.tasks.claimed.return' | translate}}</span> </button> diff --git a/src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.ts b/src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.ts index 8c3a6497825ffb31a188d63d2f0811bb6a7bb0cc..8c4147f27fcdbb4d8e7f275b151a40a5ada93843 100644 --- a/src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.ts +++ b/src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.ts @@ -13,7 +13,6 @@ import { NotificationOptions } from '../../notifications/models/notification-opt import { isNotUndefined } from '../../empty.util'; import { Workflowitem } from '../../../core/submission/models/workflowitem.model'; import { RemoteData } from '../../../core/data/remote-data'; -import { NormalizedClaimedTask } from '../../../core/tasks/models/normalized-claimed-task-object.model'; import { MyDSpaceActionsComponent } from '../mydspace-actions'; import { ResourceType } from '../../../core/shared/resource-type'; @@ -23,7 +22,7 @@ import { ResourceType } from '../../../core/shared/resource-type'; templateUrl: './claimed-task-actions.component.html', }) -export class ClaimedTaskActionsComponent extends MyDSpaceActionsComponent<ClaimedTask, NormalizedClaimedTask, ClaimedTaskDataService> implements OnInit { +export class ClaimedTaskActionsComponent extends MyDSpaceActionsComponent<ClaimedTask, ClaimedTaskDataService> implements OnInit { @Input() object: ClaimedTask; public workflowitem$: Observable<Workflowitem>; diff --git a/src/app/shared/mydspace-actions/item/item-actions.component.html b/src/app/shared/mydspace-actions/item/item-actions.component.html index 7b762bd71a5f0d54033c63db72034d420a07d2d4..91993466b61e1ca3ba690f40192159e4253606f1 100644 --- a/src/app/shared/mydspace-actions/item/item-actions.component.html +++ b/src/app/shared/mydspace-actions/item/item-actions.component.html @@ -1,11 +1,5 @@ -<a class="btn btn-light mt-1 mb-3" - role="button" - ngbTooltip="{{'submission.workflow.generic.view-help' | translate}}" - [href]="itemUrl"> +<button class="btn btn-primary mt-1 mb-3" + ngbTooltip="{{'submission.workflow.generic.view-help' | translate}}" + [routerLink]="['/items/' + object.id]"> <i class="fa fa-info-circle"></i> {{"submission.workflow.generic.view" | translate}} -</a> -<!--<button class="btn btn-primary mt-1 mb-3"--> - <!--ngbTooltip="{{'submission.workflow.generic.view-help' | translate}}"--> - <!--[routerLink]="['/items/' + object.id]">--> - <!--<i class="fa fa-info-circle"></i> {{"submission.workflow.generic.view" | translate}}--> -<!--</button>--> +</button> diff --git a/src/app/shared/mydspace-actions/item/item-actions.component.ts b/src/app/shared/mydspace-actions/item/item-actions.component.ts index 8c403cc3ef4e8b93dc2a2f76e7e4e995ee9024ce..b2022bbdd4fbf1aa44346633819ff1186ad37488 100644 --- a/src/app/shared/mydspace-actions/item/item-actions.component.ts +++ b/src/app/shared/mydspace-actions/item/item-actions.component.ts @@ -1,14 +1,10 @@ -import { Component, Injector, Input, OnInit } from '@angular/core'; +import { Component, Injector, Input } from '@angular/core'; import { Router } from '@angular/router'; -import { Observable } from 'rxjs'; - import { MyDSpaceActionsComponent } from '../mydspace-actions'; import { ResourceType } from '../../../core/shared/resource-type'; import { ItemDataService } from '../../../core/data/item-data.service'; -import { NormalizedItem } from '../../../core/cache/models/normalized-item.model'; import { Item } from '../../../core/shared/item.model'; -import { RoleService } from '../../../core/roles/role.service'; @Component({ selector: 'ds-item-actions', @@ -16,23 +12,14 @@ import { RoleService } from '../../../core/roles/role.service'; templateUrl: './item-actions.component.html', }) -export class ItemActionsComponent extends MyDSpaceActionsComponent<Item, NormalizedItem, ItemDataService> implements OnInit { +export class ItemActionsComponent extends MyDSpaceActionsComponent<Item, ItemDataService> { @Input() object: Item; - public isAdmin: Observable<boolean>; - public itemUrl: string; - constructor(protected injector: Injector, - protected roleService: RoleService, protected router: Router) { super(ResourceType.Workspaceitem, injector, router); } - ngOnInit() { - this.isAdmin = this.roleService.isAdmin(); - this.itemUrl = this.object.firstMetadataValue('dc.identifier.uri'); - } - initObjects(object: Item) { this.object = object; } diff --git a/src/app/shared/mydspace-actions/mydspace-actions-service.factory.ts b/src/app/shared/mydspace-actions/mydspace-actions-service.factory.ts index e9fae599c9dba41369bae745b36d90e61c172d40..b3efa4c9dbd527786f2bc1e45d453ccc66554885 100644 --- a/src/app/shared/mydspace-actions/mydspace-actions-service.factory.ts +++ b/src/app/shared/mydspace-actions/mydspace-actions-service.factory.ts @@ -4,10 +4,9 @@ import { WorkspaceitemDataService } from '../../core/submission/workspaceitem-da import { ClaimedTaskDataService } from '../../core/tasks/claimed-task-data.service'; import { PoolTaskDataService } from '../../core/tasks/pool-task-data.service'; import { WorkflowitemDataService } from '../../core/submission/workflowitem-data.service'; -import { NormalizedObject } from '../../core/cache/models/normalized-object.model'; import { CacheableObject } from '../../core/cache/object-cache.reducer'; -export class MydspaceActionsServiceFactory<T extends CacheableObject, TNormalized extends NormalizedObject, TService extends DataService<TNormalized, T>> { +export class MydspaceActionsServiceFactory<T extends CacheableObject, TService extends DataService<T>> { public getConstructor(type: ResourceType): TService { switch (type) { case ResourceType.Workspaceitem: { diff --git a/src/app/shared/mydspace-actions/mydspace-actions.ts b/src/app/shared/mydspace-actions/mydspace-actions.ts index 2a231f6bf06c7a1b48bf22e4ce85325956c6dd48..ab76eaf28034259d770ba237889568a4a1170895 100644 --- a/src/app/shared/mydspace-actions/mydspace-actions.ts +++ b/src/app/shared/mydspace-actions/mydspace-actions.ts @@ -5,17 +5,16 @@ import { find } from 'rxjs/operators'; import { MydspaceActionsServiceFactory } from './mydspace-actions-service.factory'; import { RemoteData } from '../../core/data/remote-data'; -import { NormalizedObject } from '../../core/cache/models/normalized-object.model'; import { DataService } from '../../core/data/data.service'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { ResourceType } from '../../core/shared/resource-type'; -export abstract class MyDSpaceActionsComponent<T extends DSpaceObject, TNormalized extends NormalizedObject, TService extends DataService<TNormalized, T>> { +export abstract class MyDSpaceActionsComponent<T extends DSpaceObject, TService extends DataService<T>> { @Input() abstract object: T; protected objectDataService: TService; constructor(protected objectType: ResourceType, protected injector: Injector, protected router: Router) { - const factory = new MydspaceActionsServiceFactory<T, TNormalized, TService>(); + const factory = new MydspaceActionsServiceFactory<T, TService>(); this.objectDataService = injector.get(factory.getConstructor(objectType)); } diff --git a/src/app/shared/mydspace-actions/pool-task/pool-task-actions.component.html b/src/app/shared/mydspace-actions/pool-task/pool-task-actions.component.html index a66bc6877be4c2ba187a6eb371d9e913554f115f..faf1fcc37e3fccdd175ecee98041b9937af25f05 100644 --- a/src/app/shared/mydspace-actions/pool-task/pool-task-actions.component.html +++ b/src/app/shared/mydspace-actions/pool-task/pool-task-actions.component.html @@ -5,8 +5,8 @@ ngbTooltip="{{'submission.workflow.tasks.pool.claim_help' | translate}}" [disabled]="(processingClaim$ | async)" (click)="claim()"> - <span *ngIf="(processingClaim$ | async)"><i class='fa fa-circle-o-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}</span> - <span *ngIf="!(processingClaim$ | async)"><i class="fa fa-hand-paper-o"></i> {{'submission.workflow.tasks.pool.claim' | translate}}</span> + <span *ngIf="(processingClaim$ | async)"><i class='fas fa-circle-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}</span> + <span *ngIf="!(processingClaim$ | async)"><i class="fas fa-hand-paper"></i> {{'submission.workflow.tasks.pool.claim' | translate}}</span> </button> <ds-message-board diff --git a/src/app/shared/mydspace-actions/pool-task/pool-task-actions.component.ts b/src/app/shared/mydspace-actions/pool-task/pool-task-actions.component.ts index 037434fed04cccc4964d599fb0af5d3d8421d94f..eccd4276685f085a125189848f255950251c8ede 100644 --- a/src/app/shared/mydspace-actions/pool-task/pool-task-actions.component.ts +++ b/src/app/shared/mydspace-actions/pool-task/pool-task-actions.component.ts @@ -13,7 +13,6 @@ import { PoolTaskDataService } from '../../../core/tasks/pool-task-data.service' import { NotificationsService } from '../../notifications/notifications.service'; import { NotificationOptions } from '../../notifications/models/notification-options.model'; import { isNotUndefined } from '../../empty.util'; -import { NormalizedPoolTask } from '../../../core/tasks/models/normalized-pool-task-object.model'; import { MyDSpaceActionsComponent } from '../mydspace-actions'; import { ResourceType } from '../../../core/shared/resource-type'; @@ -23,7 +22,7 @@ import { ResourceType } from '../../../core/shared/resource-type'; templateUrl: './pool-task-actions.component.html', }) -export class PoolTaskActionsComponent extends MyDSpaceActionsComponent<PoolTask, NormalizedPoolTask, PoolTaskDataService> { +export class PoolTaskActionsComponent extends MyDSpaceActionsComponent<PoolTask, PoolTaskDataService> { @Input() object: PoolTask; public processingClaim$ = new BehaviorSubject<boolean>(false); diff --git a/src/app/shared/mydspace-actions/workflowitem/workflowitem-actions.component.ts b/src/app/shared/mydspace-actions/workflowitem/workflowitem-actions.component.ts index 932035f730f532bbce9c6436c5f5e1c499459a25..04de5da885d073ce5e27aec31150351c0679add0 100644 --- a/src/app/shared/mydspace-actions/workflowitem/workflowitem-actions.component.ts +++ b/src/app/shared/mydspace-actions/workflowitem/workflowitem-actions.component.ts @@ -1,9 +1,9 @@ import { Component, Injector, Input } from '@angular/core'; import { Router } from '@angular/router'; + import { MyDSpaceActionsComponent } from '../mydspace-actions'; import { ResourceType } from '../../../core/shared/resource-type'; import { Workflowitem } from '../../../core/submission/models/workflowitem.model'; -import { NormalizedWorkflowItem } from '../../../core/submission/models/normalized-workflowitem.model'; import { WorkflowitemDataService } from '../../../core/submission/workflowitem-data.service'; @Component({ @@ -12,7 +12,7 @@ import { WorkflowitemDataService } from '../../../core/submission/workflowitem-d templateUrl: './workflowitem-actions.component.html', }) -export class WorkflowitemActionsComponent extends MyDSpaceActionsComponent<Workflowitem, NormalizedWorkflowItem, WorkflowitemDataService> { +export class WorkflowitemActionsComponent extends MyDSpaceActionsComponent<Workflowitem, WorkflowitemDataService> { @Input() object: Workflowitem; constructor(protected injector: Injector, diff --git a/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.html b/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.html index 3114e070a55949a34c0bab78e1814ee29f0f09a6..02c3384fcd9ce12c6a18017bf555b1dfe67ec5ff 100644 --- a/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.html +++ b/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.html @@ -9,7 +9,7 @@ class="btn btn-danger mt-1 mb-3" ngbTooltip="{{'submission.workflow.generic.delete-help' | translate}}" (click)="$event.preventDefault();confirmDiscard(content)"> - <span *ngIf="(processingDelete$ | async)"><i class='fa fa-circle-o-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}</span> + <span *ngIf="(processingDelete$ | async)"><i class='fas fa-circle-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}</span> <span *ngIf="!(processingDelete$ | async)"><i class="fa fa-trash"></i> {{'submission.workflow.generic.delete' | translate}}</span> </button> diff --git a/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.ts b/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.ts index 1ad229d950119bb4d9fb771ee828951128daa9d0..05eee97d2adbb57a0d7fee60cc2fcebcaa1ae274 100644 --- a/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.ts +++ b/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.ts @@ -7,7 +7,6 @@ import { TranslateService } from '@ngx-translate/core'; import { Workspaceitem } from '../../../core/submission/models/workspaceitem.model'; import { MyDSpaceActionsComponent } from '../mydspace-actions'; -import { NormalizedWorkspaceItem } from '../../../core/submission/models/normalized-workspaceitem.model'; import { SubmissionRestService } from '../../../submission/submission-rest.service'; import { WorkspaceitemDataService } from '../../../core/submission/workspaceitem-data.service'; import { ResourceType } from '../../../core/shared/resource-type'; @@ -20,7 +19,7 @@ import { NotificationOptions } from '../../notifications/models/notification-opt templateUrl: './workspaceitem-actions.component.html', }) -export class WorkspaceitemActionsComponent extends MyDSpaceActionsComponent<Workspaceitem, NormalizedWorkspaceItem, WorkspaceitemDataService> { +export class WorkspaceitemActionsComponent extends MyDSpaceActionsComponent<Workspaceitem, WorkspaceitemDataService> { @Input() object: Workspaceitem; public processingDelete$ = new BehaviorSubject<boolean>(false); diff --git a/src/app/shared/notifications/notifications.service.ts b/src/app/shared/notifications/notifications.service.ts index 85c9d26dfb959eef5a942bc14ced37e4f8a4d296..4a8d5fb9125a74029c2814f93f7a1de94acf7ed4 100644 --- a/src/app/shared/notifications/notifications.service.ts +++ b/src/app/shared/notifications/notifications.service.ts @@ -52,7 +52,6 @@ export class NotificationsService { options: Partial<NotificationOptions> = {}, html: boolean = false): INotification { const notificationOptions = { ...this.getDefaultOptions(), ...options }; - console.log(notificationOptions); const notification = new Notification(uniqueId(), NotificationType.Info, title, content, notificationOptions, html); this.add(notification); return notification; diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/my-dspace-result-detail-element.component.ts b/src/app/shared/object-detail/my-dspace-result-detail-element/my-dspace-result-detail-element.component.ts index f5c2cd089741702eaf2c85b20304dbbdf2cad4e2..3efb668c5abc30205bb2ce3cf8467d53fc2ebe1b 100644 --- a/src/app/shared/object-detail/my-dspace-result-detail-element/my-dspace-result-detail-element.component.ts +++ b/src/app/shared/object-detail/my-dspace-result-detail-element/my-dspace-result-detail-element.component.ts @@ -4,7 +4,7 @@ import { MyDSpaceResult } from '../../../+my-dspace-page/my-dspace-result.model' import { AbstractListableElementComponent } from '../../object-collection/shared/object-collection-element/abstract-listable-element.component'; import { ListableObject } from '../../object-collection/shared/listable-object.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; -import { Metadata } from '../../../core/shared/metadata.model'; +import { Metadata } from '../../../core/shared/metadata.utils'; @Component({ selector: 'ds-my-dspace-result-detail-element', diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/wfi-my-dspace-result/wfi-my-dspace-result-detail-element.component.ts b/src/app/shared/object-detail/my-dspace-result-detail-element/wfi-my-dspace-result/wfi-my-dspace-result-detail-element.component.ts index 398e75889674408d7ec1f79e301fdd84aab922f6..865e9c4fec0c769c8815238b78c4cf622b7d1322 100644 --- a/src/app/shared/object-detail/my-dspace-result-detail-element/wfi-my-dspace-result/wfi-my-dspace-result-detail-element.component.ts +++ b/src/app/shared/object-detail/my-dspace-result-detail-element/wfi-my-dspace-result/wfi-my-dspace-result-detail-element.component.ts @@ -34,11 +34,11 @@ export class WorkflowitemMyDSpaceResultDetailElementComponent extends MyDSpaceRe this.initItem(this.dso.item as Observable<RemoteData<Item>>); } - initItem(itemObs: Observable<RemoteData<Item>>) { - itemObs.pipe( - find((rd: RemoteData<any>) => rd.hasSucceeded && isNotUndefined(rd.payload)) - ).subscribe((rd: RemoteData<any>) => { - this.item = rd.payload[0]; + initItem(item$: Observable<RemoteData<Item>>) { + item$.pipe( + find((rd: RemoteData<Item>) => rd.hasSucceeded && isNotUndefined(rd.payload)) + ).subscribe((rd: RemoteData<Item>) => { + this.item = rd.payload; }); } diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/wsi-my-dspace-result/wsi-my-dspace-result-detail-element.component.ts b/src/app/shared/object-detail/my-dspace-result-detail-element/wsi-my-dspace-result/wsi-my-dspace-result-detail-element.component.ts index 4c2c47eae37a0ccddc92e16dfefd211ba51aea1e..c600ba9773c447b5ddd8557f8732517f8043ea78 100644 --- a/src/app/shared/object-detail/my-dspace-result-detail-element/wsi-my-dspace-result/wsi-my-dspace-result-detail-element.component.ts +++ b/src/app/shared/object-detail/my-dspace-result-detail-element/wsi-my-dspace-result/wsi-my-dspace-result-detail-element.component.ts @@ -34,11 +34,11 @@ export class WorkspaceitemMyDSpaceResultDetailElementComponent extends MyDSpaceR this.initItem(this.dso.item as Observable<RemoteData<Item>>); } - initItem(itemObs: Observable<RemoteData<Item>>) { - itemObs.pipe( - find((rd: RemoteData<any>) => rd.hasSucceeded && isNotUndefined(rd.payload)) - ).subscribe((rd: RemoteData<any>) => { - this.item = rd.payload[0]; + initItem(item$: Observable<RemoteData<Item>>) { + item$.pipe( + find((rd: RemoteData<Item>) => rd.hasSucceeded && isNotUndefined(rd.payload)) + ).subscribe((rd: RemoteData<Item>) => { + this.item = rd.payload; }); } } diff --git a/src/app/shared/object-list/item-list-preview/item-list-preview.component.ts b/src/app/shared/object-list/item-list-preview/item-list-preview.component.ts index 83b8d8fd92b17f3ca8d720b4872492b175eda5a2..0a853b9c5ef03c6bbecbe64029390ccabb6acb61 100644 --- a/src/app/shared/object-list/item-list-preview/item-list-preview.component.ts +++ b/src/app/shared/object-list/item-list-preview/item-list-preview.component.ts @@ -3,7 +3,7 @@ import { Component, Input } from '@angular/core'; import { Item } from '../../../core/shared/item.model'; import { fadeInOut } from '../../animations/fade'; import { MyDspaceItemStatusType } from '../../object-collection/shared/mydspace-item-status/my-dspace-item-status-type'; -import { Metadata } from '../../../core/shared/metadata.model'; +import { Metadata } from '../../../core/shared/metadata.utils'; @Component({ selector: 'ds-item-list-preview', diff --git a/src/app/shared/object-list/my-dspace-result-list-element/my-dspace-result-list-element.component.ts b/src/app/shared/object-list/my-dspace-result-list-element/my-dspace-result-list-element.component.ts index 6c759f8946eb5e6fab554081bb4e038a40c20e02..bddf40d8c204cdc27bc4891aaed94a7c2562d547 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/my-dspace-result-list-element.component.ts +++ b/src/app/shared/object-list/my-dspace-result-list-element/my-dspace-result-list-element.component.ts @@ -4,8 +4,7 @@ import { MyDSpaceResult } from '../../../+my-dspace-page/my-dspace-result.model' import { AbstractListableElementComponent } from '../../object-collection/shared/object-collection-element/abstract-listable-element.component'; import { ListableObject } from '../../object-collection/shared/listable-object.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; -import { Metadata } from '../../../core/shared/metadata.model'; -import { TruncatableService } from '../../truncatable/truncatable.service'; +import { Metadata } from '../../../core/shared/metadata.utils'; @Component({ selector: 'ds-my-dspace-result-list-element', diff --git a/src/app/shared/object-list/my-dspace-result-list-element/pt-my-dspace-result/pt-my-dspace-result-list-element.component.html b/src/app/shared/object-list/my-dspace-result-list-element/pt-my-dspace-result/pt-my-dspace-result-list-element.component.html index b5018615e0ddb5da30cf56ed4540fd5f632ba502..13f1e839622425831cf289fe16db811200dd12c9 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/pt-my-dspace-result/pt-my-dspace-result-list-element.component.html +++ b/src/app/shared/object-list/my-dspace-result-list-element/pt-my-dspace-result/pt-my-dspace-result-list-element.component.html @@ -8,7 +8,7 @@ <button type="button" class="btn btn-primary mt-1 mb-3" (click)="view()"> - <span>{{"mydspace.view-btn" | translate}}</span> + <span><i class='fas fa-eye'></i> {{"mydspace.view-btn" | translate}}</span> </button> </ds-pool-task-actions> diff --git a/src/app/shared/view-mode-switch/view-mode-switch.component.html b/src/app/shared/view-mode-switch/view-mode-switch.component.html index 893047557834d725620e550df3712c97ac108671..905cf29baccbf327d19ac749bd43afe8db44f1ab 100644 --- a/src/app/shared/view-mode-switch/view-mode-switch.component.html +++ b/src/app/shared/view-mode-switch/view-mode-switch.component.html @@ -1,5 +1,6 @@ <div class="btn-group" data-toggle="buttons"> - <a routerLink="." + <a *ngIf="isToShow(viewModeEnum.List)" + routerLink="." [queryParams]="{view: 'list'}" queryParamsHandling="merge" (click)="switchViewTo(viewModeEnum.List)" @@ -8,13 +9,24 @@ class="btn btn-secondary"> <i class="fas fa-list" title="{{'search.view-switch.show-list' | translate}}"></i> </a> - <a routerLink="." + <a *ngIf="isToShow(viewModeEnum.Grid)" + routerLink="." [queryParams]="{view: 'grid'}" queryParamsHandling="merge" (click)="switchViewTo(viewModeEnum.Grid)" routerLinkActive="active" - [class.active]="currentMode !== viewModeEnum.List" + [class.active]="currentMode === viewModeEnum.Grid" class="btn btn-secondary"> <i class="fas fa-th-large" title="{{'search.view-switch.show-grid' | translate}}"></i> </a> -</div> \ No newline at end of file + <a *ngIf="isToShow(viewModeEnum.Detail)" + routerLink="." + [queryParams]="{view: 'detail'}" + queryParamsHandling="merge" + (click)="switchViewTo(viewModeEnum.Detail)" + routerLinkActive="active" + [class.active]="currentMode === viewModeEnum.Detail" + class="btn btn-secondary"> + <i class="far fa-square" title="{{'search.view-switch.show-detail' | translate}}"></i> + </a> +</div> diff --git a/src/app/shared/view-mode-switch/view-mode-switch.component.ts b/src/app/shared/view-mode-switch/view-mode-switch.component.ts index 07c47435ffe14d7c075f490bbd7d61179bb7005d..b011fce6a0cc341fe7a84c682e73a3489cb93402 100644 --- a/src/app/shared/view-mode-switch/view-mode-switch.component.ts +++ b/src/app/shared/view-mode-switch/view-mode-switch.component.ts @@ -1,7 +1,10 @@ +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; + import { Subscription } from 'rxjs'; -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { SearchService } from './../../+search-page/search-service/search.service'; + +import { SearchService } from '../../+search-page/search-service/search.service'; import { ViewMode } from '../../core/shared/view-mode.model'; +import { isEmpty } from '../empty.util'; /** * Component to switch between list and grid views. @@ -12,6 +15,8 @@ import { ViewMode } from '../../core/shared/view-mode.model'; templateUrl: './view-mode-switch.component.html' }) export class ViewModeSwitchComponent implements OnInit, OnDestroy { + @Input() viewModeList: ViewMode[]; + currentMode: ViewMode = ViewMode.List; viewModeEnum = ViewMode; private sub: Subscription; @@ -20,6 +25,10 @@ export class ViewModeSwitchComponent implements OnInit, OnDestroy { } ngOnInit(): void { + if (isEmpty(this.viewModeList)) { + this.viewModeList = [ViewMode.List, ViewMode.Grid]; + } + this.sub = this.searchService.getViewMode().subscribe((viewMode: ViewMode) => { this.currentMode = viewMode; }); @@ -34,4 +43,8 @@ export class ViewModeSwitchComponent implements OnInit, OnDestroy { this.sub.unsubscribe(); } } + + isToShow(viewMode: ViewMode) { + return this.viewModeList && this.viewModeList.includes(viewMode); + } }