forked from hazza/dspace-angular
Merge branch 'main' into issue-815-controlled-vocabulary-hierarchical-facets-7.4
This commit is contained in:
@@ -99,7 +99,7 @@
|
|||||||
"http-proxy-middleware": "^1.0.5",
|
"http-proxy-middleware": "^1.0.5",
|
||||||
"js-cookie": "2.2.1",
|
"js-cookie": "2.2.1",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"json5": "^2.1.3",
|
"json5": "^2.2.2",
|
||||||
"jsonschema": "1.4.0",
|
"jsonschema": "1.4.0",
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"klaro": "^0.7.18",
|
"klaro": "^0.7.18",
|
||||||
|
@@ -42,10 +42,6 @@ import {
|
|||||||
filterReducer,
|
filterReducer,
|
||||||
SearchFiltersState
|
SearchFiltersState
|
||||||
} from './shared/search/search-filters/search-filter/search-filter.reducer';
|
} from './shared/search/search-filters/search-filter/search-filter.reducer';
|
||||||
import {
|
|
||||||
sidebarFilterReducer,
|
|
||||||
SidebarFiltersState
|
|
||||||
} from './shared/sidebar/filter/sidebar-filter.reducer';
|
|
||||||
import { sidebarReducer, SidebarState } from './shared/sidebar/sidebar.reducer';
|
import { sidebarReducer, SidebarState } from './shared/sidebar/sidebar.reducer';
|
||||||
import { truncatableReducer, TruncatablesState } from './shared/truncatable/truncatable.reducer';
|
import { truncatableReducer, TruncatablesState } from './shared/truncatable/truncatable.reducer';
|
||||||
import { ThemeState, themeReducer } from './shared/theme-support/theme.reducer';
|
import { ThemeState, themeReducer } from './shared/theme-support/theme.reducer';
|
||||||
@@ -59,7 +55,6 @@ export interface AppState {
|
|||||||
metadataRegistry: MetadataRegistryState;
|
metadataRegistry: MetadataRegistryState;
|
||||||
notifications: NotificationsState;
|
notifications: NotificationsState;
|
||||||
sidebar: SidebarState;
|
sidebar: SidebarState;
|
||||||
sidebarFilter: SidebarFiltersState;
|
|
||||||
searchFilter: SearchFiltersState;
|
searchFilter: SearchFiltersState;
|
||||||
truncatable: TruncatablesState;
|
truncatable: TruncatablesState;
|
||||||
cssVariables: CSSVariablesState;
|
cssVariables: CSSVariablesState;
|
||||||
@@ -81,7 +76,6 @@ export const appReducers: ActionReducerMap<AppState> = {
|
|||||||
metadataRegistry: metadataRegistryReducer,
|
metadataRegistry: metadataRegistryReducer,
|
||||||
notifications: notificationsReducer,
|
notifications: notificationsReducer,
|
||||||
sidebar: sidebarReducer,
|
sidebar: sidebarReducer,
|
||||||
sidebarFilter: sidebarFilterReducer,
|
|
||||||
searchFilter: filterReducer,
|
searchFilter: filterReducer,
|
||||||
truncatable: truncatableReducer,
|
truncatable: truncatableReducer,
|
||||||
cssVariables: cssVariablesReducer,
|
cssVariables: cssVariablesReducer,
|
||||||
|
@@ -6,7 +6,7 @@ import { Bitstream } from '../../core/shared/bitstream.model';
|
|||||||
import { BitstreamDownloadPageComponent } from './bitstream-download-page.component';
|
import { BitstreamDownloadPageComponent } from './bitstream-download-page.component';
|
||||||
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
|
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
|
||||||
import { HardRedirectService } from '../../core/services/hard-redirect.service';
|
import { HardRedirectService } from '../../core/services/hard-redirect.service';
|
||||||
import { createSuccessfulRemoteDataObject } from '../remote-data.utils';
|
import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { getForbiddenRoute } from '../../app-routing-paths';
|
import { getForbiddenRoute } from '../../app-routing-paths';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
@@ -1,7 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { filter, map, switchMap, take } from 'rxjs/operators';
|
import { filter, map, switchMap, take } from 'rxjs/operators';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { hasValue, isNotEmpty } from '../empty.util';
|
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||||
import { getRemoteDataPayload} from '../../core/shared/operators';
|
import { getRemoteDataPayload} from '../../core/shared/operators';
|
||||||
import { Bitstream } from '../../core/shared/bitstream.model';
|
import { Bitstream } from '../../core/shared/bitstream.model';
|
||||||
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
|
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
|
@@ -3,7 +3,7 @@ import { RouterModule } from '@angular/router';
|
|||||||
import { EditBitstreamPageComponent } from './edit-bitstream-page/edit-bitstream-page.component';
|
import { EditBitstreamPageComponent } from './edit-bitstream-page/edit-bitstream-page.component';
|
||||||
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
|
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
|
||||||
import { BitstreamPageResolver } from './bitstream-page.resolver';
|
import { BitstreamPageResolver } from './bitstream-page.resolver';
|
||||||
import { BitstreamDownloadPageComponent } from '../shared/bitstream-download-page/bitstream-download-page.component';
|
import { BitstreamDownloadPageComponent } from './bitstream-download-page/bitstream-download-page.component';
|
||||||
import { ResourcePolicyTargetResolver } from '../shared/resource-policies/resolvers/resource-policy-target.resolver';
|
import { ResourcePolicyTargetResolver } from '../shared/resource-policies/resolvers/resource-policy-target.resolver';
|
||||||
import { ResourcePolicyCreateComponent } from '../shared/resource-policies/create/resource-policy-create.component';
|
import { ResourcePolicyCreateComponent } from '../shared/resource-policies/create/resource-policy-create.component';
|
||||||
import { ResourcePolicyResolver } from '../shared/resource-policies/resolvers/resource-policy.resolver';
|
import { ResourcePolicyResolver } from '../shared/resource-policies/resolvers/resource-policy.resolver';
|
||||||
|
@@ -6,6 +6,7 @@ import { BitstreamPageRoutingModule } from './bitstream-page-routing.module';
|
|||||||
import { BitstreamAuthorizationsComponent } from './bitstream-authorizations/bitstream-authorizations.component';
|
import { BitstreamAuthorizationsComponent } from './bitstream-authorizations/bitstream-authorizations.component';
|
||||||
import { FormModule } from '../shared/form/form.module';
|
import { FormModule } from '../shared/form/form.module';
|
||||||
import { ResourcePoliciesModule } from '../shared/resource-policies/resource-policies.module';
|
import { ResourcePoliciesModule } from '../shared/resource-policies/resource-policies.module';
|
||||||
|
import { BitstreamDownloadPageComponent } from './bitstream-download-page/bitstream-download-page.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This module handles all components that are necessary for Bitstream related pages
|
* This module handles all components that are necessary for Bitstream related pages
|
||||||
@@ -20,7 +21,8 @@ import { ResourcePoliciesModule } from '../shared/resource-policies/resource-pol
|
|||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
BitstreamAuthorizationsComponent,
|
BitstreamAuthorizationsComponent,
|
||||||
EditBitstreamPageComponent
|
EditBitstreamPageComponent,
|
||||||
|
BitstreamDownloadPageComponent,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class BitstreamPageModule {
|
export class BitstreamPageModule {
|
||||||
|
@@ -23,11 +23,14 @@ li.breadcrumb-item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
li.breadcrumb-item > a {
|
li.breadcrumb-item {
|
||||||
color: var(--ds-breadcrumb-link-color) !important;
|
a {
|
||||||
|
color: var(--ds-breadcrumb-link-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
li.breadcrumb-item.active {
|
li.breadcrumb-item.active {
|
||||||
color: var(--ds-breadcrumb-link-active-color) !important;
|
color: var(--ds-breadcrumb-link-active-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumb-item+ .breadcrumb-item::before {
|
.breadcrumb-item+ .breadcrumb-item::before {
|
||||||
|
@@ -6,6 +6,7 @@ import { CommunityListPageRoutingModule } from './community-list-page.routing.mo
|
|||||||
import { CommunityListComponent } from './community-list/community-list.component';
|
import { CommunityListComponent } from './community-list/community-list.component';
|
||||||
import { ThemedCommunityListPageComponent } from './themed-community-list-page.component';
|
import { ThemedCommunityListPageComponent } from './themed-community-list-page.component';
|
||||||
import { ThemedCommunityListComponent } from './community-list/themed-community-list.component';
|
import { ThemedCommunityListComponent } from './community-list/themed-community-list.component';
|
||||||
|
import { CdkTreeModule } from '@angular/cdk/tree';
|
||||||
|
|
||||||
|
|
||||||
const DECLARATIONS = [
|
const DECLARATIONS = [
|
||||||
@@ -21,13 +22,15 @@ const DECLARATIONS = [
|
|||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
SharedModule,
|
SharedModule,
|
||||||
CommunityListPageRoutingModule
|
CommunityListPageRoutingModule,
|
||||||
|
CdkTreeModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
...DECLARATIONS
|
...DECLARATIONS
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
...DECLARATIONS,
|
...DECLARATIONS,
|
||||||
|
CdkTreeModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class CommunityListPageModule {
|
export class CommunityListPageModule {
|
||||||
|
@@ -196,7 +196,24 @@ export class AuthInterceptor implements HttpInterceptor {
|
|||||||
authStatus.token = new AuthTokenInfo(accessToken);
|
authStatus.token = new AuthTokenInfo(accessToken);
|
||||||
} else {
|
} else {
|
||||||
authStatus.authenticated = false;
|
authStatus.authenticated = false;
|
||||||
authStatus.error = isNotEmpty(error) ? ((typeof error === 'string') ? JSON.parse(error) : error) : null;
|
if (isNotEmpty(error)) {
|
||||||
|
if (typeof error === 'string') {
|
||||||
|
try {
|
||||||
|
authStatus.error = JSON.parse(error);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Unknown auth error "', error, '" caused ', e);
|
||||||
|
authStatus.error = {
|
||||||
|
error: 'Unknown',
|
||||||
|
message: 'Unknown auth error',
|
||||||
|
status: 500,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
path: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
authStatus.error = error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return authStatus;
|
return authStatus;
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
|
|||||||
import { hasValue, isEmpty } from '../../shared/empty.util';
|
import { hasValue, isEmpty } from '../../shared/empty.util';
|
||||||
import { DSpaceObject } from '../shared/dspace-object.model';
|
import { DSpaceObject } from '../shared/dspace-object.model';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { Metadata } from '../shared/metadata.utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a name for a {@link DSpaceObject} based
|
* Returns a name for a {@link DSpaceObject} based
|
||||||
@@ -67,4 +68,45 @@ export class DSONameService {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Hit highlight
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* @param dso
|
||||||
|
*
|
||||||
|
* @returns {string} html embedded hit highlight.
|
||||||
|
*/
|
||||||
|
getHitHighlights(object: any, dso: DSpaceObject): string {
|
||||||
|
const types = dso.getRenderTypes();
|
||||||
|
const entityType = types
|
||||||
|
.filter((type) => typeof type === 'string')
|
||||||
|
.find((type: string) => (['Person', 'OrgUnit']).includes(type)) as string;
|
||||||
|
if (entityType === 'Person') {
|
||||||
|
const familyName = this.firstMetadataValue(object, dso, 'person.familyName');
|
||||||
|
const givenName = this.firstMetadataValue(object, dso, 'person.givenName');
|
||||||
|
if (isEmpty(familyName) && isEmpty(givenName)) {
|
||||||
|
return this.firstMetadataValue(object, dso, 'dc.title') || dso.name;
|
||||||
|
} else if (isEmpty(familyName) || isEmpty(givenName)) {
|
||||||
|
return familyName || givenName;
|
||||||
|
}
|
||||||
|
return `${familyName}, ${givenName}`;
|
||||||
|
} else if (entityType === 'OrgUnit') {
|
||||||
|
return this.firstMetadataValue(object, dso, 'organization.legalName');
|
||||||
|
}
|
||||||
|
return this.firstMetadataValue(object, dso, 'dc.title') || dso.name || this.translateService.instant('dso.name.untitled');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the first matching metadata string value from hitHighlights or dso metadata, preferring hitHighlights.
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* @param dso
|
||||||
|
* @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see [[Metadata]].
|
||||||
|
*
|
||||||
|
* @returns {string} the first matching string value, or `undefined`.
|
||||||
|
*/
|
||||||
|
firstMetadataValue(object: any, dso: DSpaceObject, keyOrKeys: string | string[]): string {
|
||||||
|
return Metadata.firstValue([object.hitHighlights, dso.metadata], keyOrKeys);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,11 @@ export class MediaViewerItem {
|
|||||||
*/
|
*/
|
||||||
format: string;
|
format: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Incoming Bitsream format mime type
|
||||||
|
*/
|
||||||
|
mimetype: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Incoming Bitsream thumbnail
|
* Incoming Bitsream thumbnail
|
||||||
*/
|
*/
|
||||||
|
@@ -61,7 +61,7 @@ export class OrgUnitSearchResultListSubmissionElementComponent extends SearchRes
|
|||||||
this.useNameVariants = this.context === Context.EntitySearchModalWithNameVariants;
|
this.useNameVariants = this.context === Context.EntitySearchModalWithNameVariants;
|
||||||
|
|
||||||
if (this.useNameVariants) {
|
if (this.useNameVariants) {
|
||||||
const defaultValue = this.dsoTitle;
|
const defaultValue = this.dso ? this.dsoNameService.getName(this.dso) : undefined;
|
||||||
const alternatives = this.allMetadataValues(this.alternativeField);
|
const alternatives = this.allMetadataValues(this.alternativeField);
|
||||||
this.allSuggestions = [defaultValue, ...alternatives];
|
this.allSuggestions = [defaultValue, ...alternatives];
|
||||||
|
|
||||||
|
@@ -55,7 +55,7 @@ export class PersonSearchResultListSubmissionElementComponent extends SearchResu
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
const defaultValue = this.dsoTitle;
|
const defaultValue = this.dso ? this.dsoNameService.getName(this.dso) : undefined;
|
||||||
const alternatives = this.allMetadataValues(this.alternativeField);
|
const alternatives = this.allMetadataValues(this.alternativeField);
|
||||||
this.allSuggestions = [defaultValue, ...alternatives];
|
this.allSuggestions = [defaultValue, ...alternatives];
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|||||||
import { ItemAlertsComponent } from './item-alerts.component';
|
import { ItemAlertsComponent } from './item-alerts.component';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { Item } from '../../../core/shared/item.model';
|
import { Item } from '../../core/shared/item.model';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
|
|
||||||
describe('ItemAlertsComponent', () => {
|
describe('ItemAlertsComponent', () => {
|
@@ -1,6 +1,6 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { Item } from '../../../core/shared/item.model';
|
import { Item } from '../../core/shared/item.model';
|
||||||
import { AlertType } from '../../alert/aletr-type';
|
import { AlertType } from '../../shared/alert/aletr-type';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-item-alerts',
|
selector: 'ds-item-alerts',
|
@@ -1,30 +1,30 @@
|
|||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||||
import { AuthService } from '../../core/auth/auth.service';
|
import { AuthService } from '../../../core/auth/auth.service';
|
||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
import { Bitstream } from '../../core/shared/bitstream.model';
|
import { Bitstream } from '../../../core/shared/bitstream.model';
|
||||||
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
|
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||||
import {
|
import {
|
||||||
createFailedRemoteDataObject$,
|
createFailedRemoteDataObject$,
|
||||||
createSuccessfulRemoteDataObject,
|
createSuccessfulRemoteDataObject,
|
||||||
createSuccessfulRemoteDataObject$
|
createSuccessfulRemoteDataObject$
|
||||||
} from '../remote-data.utils';
|
} from '../../../shared/remote-data.utils';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { BitstreamRequestACopyPageComponent } from './bitstream-request-a-copy-page.component';
|
import { BitstreamRequestACopyPageComponent } from './bitstream-request-a-copy-page.component';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { RouterStub } from '../testing/router.stub';
|
import { RouterStub } from '../../../shared/testing/router.stub';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { NotificationsServiceStub } from '../testing/notifications-service.stub';
|
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
|
||||||
import { ItemRequestDataService } from '../../core/data/item-request-data.service';
|
import { ItemRequestDataService } from '../../../core/data/item-request-data.service';
|
||||||
import { NotificationsService } from '../notifications/notifications.service';
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
|
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
||||||
import { DSONameServiceMock } from '../mocks/dso-name.service.mock';
|
import { DSONameServiceMock } from '../../../shared/mocks/dso-name.service.mock';
|
||||||
import { Item } from '../../core/shared/item.model';
|
import { Item } from '../../../core/shared/item.model';
|
||||||
import { EPerson } from '../../core/eperson/models/eperson.model';
|
import { EPerson } from '../../../core/eperson/models/eperson.model';
|
||||||
import { ItemRequest } from '../../core/shared/item-request.model';
|
import { ItemRequest } from '../../../core/shared/item-request.model';
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
|
import { BitstreamDataService } from '../../../core/data/bitstream-data.service';
|
||||||
|
|
||||||
|
|
||||||
describe('BitstreamRequestACopyPageComponent', () => {
|
describe('BitstreamRequestACopyPageComponent', () => {
|
@@ -1,25 +1,25 @@
|
|||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { filter, map, switchMap, take } from 'rxjs/operators';
|
import { filter, map, switchMap, take } from 'rxjs/operators';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { hasValue, isNotEmpty } from '../empty.util';
|
import { hasValue, isNotEmpty } from '../../../shared/empty.util';
|
||||||
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../core/shared/operators';
|
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators';
|
||||||
import { Bitstream } from '../../core/shared/bitstream.model';
|
import { Bitstream } from '../../../core/shared/bitstream.model';
|
||||||
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
|
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||||
import { FeatureID } from '../../core/data/feature-authorization/feature-id';
|
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
|
||||||
import { AuthService } from '../../core/auth/auth.service';
|
import { AuthService } from '../../../core/auth/auth.service';
|
||||||
import { combineLatest as observableCombineLatest, Observable, of as observableOf, Subscription } from 'rxjs';
|
import { combineLatest as observableCombineLatest, Observable, of as observableOf, Subscription } from 'rxjs';
|
||||||
import { getBitstreamDownloadRoute, getForbiddenRoute } from '../../app-routing-paths';
|
import { getBitstreamDownloadRoute, getForbiddenRoute } from '../../../app-routing-paths';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { EPerson } from '../../core/eperson/models/eperson.model';
|
import { EPerson } from '../../../core/eperson/models/eperson.model';
|
||||||
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
|
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
import { ItemRequestDataService } from '../../core/data/item-request-data.service';
|
import { ItemRequestDataService } from '../../../core/data/item-request-data.service';
|
||||||
import { ItemRequest } from '../../core/shared/item-request.model';
|
import { ItemRequest } from '../../../core/shared/item-request.model';
|
||||||
import { Item } from '../../core/shared/item.model';
|
import { Item } from '../../../core/shared/item.model';
|
||||||
import { NotificationsService } from '../notifications/notifications.service';
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
|
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
|
import { BitstreamDataService } from '../../../core/data/bitstream-data.service';
|
||||||
import { getItemPageRoute } from '../../item-page/item-page-routing-paths';
|
import { getItemPageRoute } from '../../item-page-routing-paths';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-bitstream-request-a-copy-page',
|
selector: 'ds-bitstream-request-a-copy-page',
|
@@ -36,6 +36,7 @@ import { ItemVersionHistoryComponent } from './item-version-history/item-version
|
|||||||
import { ItemAuthorizationsComponent } from './item-authorizations/item-authorizations.component';
|
import { ItemAuthorizationsComponent } from './item-authorizations/item-authorizations.component';
|
||||||
import { ObjectValuesPipe } from '../../shared/utils/object-values-pipe';
|
import { ObjectValuesPipe } from '../../shared/utils/object-values-pipe';
|
||||||
import { ResourcePoliciesModule } from '../../shared/resource-policies/resource-policies.module';
|
import { ResourcePoliciesModule } from '../../shared/resource-policies/resource-policies.module';
|
||||||
|
import { ItemVersionsModule } from '../versions/item-versions.module';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,7 +51,8 @@ import { ResourcePoliciesModule } from '../../shared/resource-policies/resource-
|
|||||||
SearchPageModule,
|
SearchPageModule,
|
||||||
DragDropModule,
|
DragDropModule,
|
||||||
ResourcePoliciesModule,
|
ResourcePoliciesModule,
|
||||||
NgbModule
|
NgbModule,
|
||||||
|
ItemVersionsModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
EditItemPageComponent,
|
EditItemPageComponent,
|
||||||
|
@@ -7,7 +7,7 @@ import { TranslateLoaderMock } from '../../../../shared/mocks/translate-loader.m
|
|||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { VarDirective } from '../../../../shared/utils/var.directive';
|
import { VarDirective } from '../../../../shared/utils/var.directive';
|
||||||
import { FileSizePipe } from '../../../../shared/utils/file-size-pipe';
|
import { FileSizePipe } from '../../../../shared/utils/file-size-pipe';
|
||||||
import { MetadataFieldWrapperComponent } from '../../../field-components/metadata-field-wrapper/metadata-field-wrapper.component';
|
import { MetadataFieldWrapperComponent } from '../../../../shared/metadata-field-wrapper/metadata-field-wrapper.component';
|
||||||
import { BitstreamDataService } from '../../../../core/data/bitstream-data.service';
|
import { BitstreamDataService } from '../../../../core/data/bitstream-data.service';
|
||||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { Bitstream } from '../../../../core/shared/bitstream.model';
|
import { Bitstream } from '../../../../core/shared/bitstream.model';
|
||||||
|
@@ -14,9 +14,7 @@ import { ThemedItemPageComponent } from './simple/themed-item-page.component';
|
|||||||
import { ThemedFullItemPageComponent } from './full/themed-full-item-page.component';
|
import { ThemedFullItemPageComponent } from './full/themed-full-item-page.component';
|
||||||
import { MenuItemType } from '../shared/menu/menu-item-type.model';
|
import { MenuItemType } from '../shared/menu/menu-item-type.model';
|
||||||
import { VersionPageComponent } from './version-page/version-page/version-page.component';
|
import { VersionPageComponent } from './version-page/version-page/version-page.component';
|
||||||
import {
|
import { BitstreamRequestACopyPageComponent } from './bitstreams/request-a-copy/bitstream-request-a-copy-page.component';
|
||||||
BitstreamRequestACopyPageComponent
|
|
||||||
} from '../shared/bitstream-request-a-copy-page/bitstream-request-a-copy-page.component';
|
|
||||||
import { REQUEST_COPY_MODULE_PATH } from '../app-routing-paths';
|
import { REQUEST_COPY_MODULE_PATH } from '../app-routing-paths';
|
||||||
import { OrcidPageComponent } from './orcid-page/orcid-page.component';
|
import { OrcidPageComponent } from './orcid-page/orcid-page.component';
|
||||||
import { OrcidPageGuard } from './orcid-page/orcid-page.guard';
|
import { OrcidPageGuard } from './orcid-page/orcid-page.guard';
|
||||||
|
@@ -47,6 +47,11 @@ import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap';
|
|||||||
import { OrcidSyncSettingsComponent } from './orcid-page/orcid-sync-settings/orcid-sync-settings.component';
|
import { OrcidSyncSettingsComponent } from './orcid-page/orcid-sync-settings/orcid-sync-settings.component';
|
||||||
import { OrcidQueueComponent } from './orcid-page/orcid-queue/orcid-queue.component';
|
import { OrcidQueueComponent } from './orcid-page/orcid-queue/orcid-queue.component';
|
||||||
import { UploadModule } from '../shared/upload/upload.module';
|
import { UploadModule } from '../shared/upload/upload.module';
|
||||||
|
import { ItemAlertsComponent } from './alerts/item-alerts.component';
|
||||||
|
import { ItemVersionsModule } from './versions/item-versions.module';
|
||||||
|
import { BitstreamRequestACopyPageComponent } from './bitstreams/request-a-copy/bitstream-request-a-copy-page.component';
|
||||||
|
import { FileSectionComponent } from './simple/field-components/file-section/file-section.component';
|
||||||
|
import { ItemSharedModule } from './item-shared.module';
|
||||||
|
|
||||||
|
|
||||||
const ENTRY_COMPONENTS = [
|
const ENTRY_COMPONENTS = [
|
||||||
@@ -56,6 +61,7 @@ const ENTRY_COMPONENTS = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const DECLARATIONS = [
|
const DECLARATIONS = [
|
||||||
|
FileSectionComponent,
|
||||||
ThemedFileSectionComponent,
|
ThemedFileSectionComponent,
|
||||||
ItemPageComponent,
|
ItemPageComponent,
|
||||||
ThemedItemPageComponent,
|
ThemedItemPageComponent,
|
||||||
@@ -82,7 +88,10 @@ const DECLARATIONS = [
|
|||||||
OrcidPageComponent,
|
OrcidPageComponent,
|
||||||
OrcidAuthComponent,
|
OrcidAuthComponent,
|
||||||
OrcidSyncSettingsComponent,
|
OrcidSyncSettingsComponent,
|
||||||
OrcidQueueComponent
|
OrcidQueueComponent,
|
||||||
|
ItemAlertsComponent,
|
||||||
|
VersionedItemComponent,
|
||||||
|
BitstreamRequestACopyPageComponent,
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -91,6 +100,8 @@ const DECLARATIONS = [
|
|||||||
SharedModule.withEntryComponents(),
|
SharedModule.withEntryComponents(),
|
||||||
ItemPageRoutingModule,
|
ItemPageRoutingModule,
|
||||||
EditItemPageModule,
|
EditItemPageModule,
|
||||||
|
ItemVersionsModule,
|
||||||
|
ItemSharedModule,
|
||||||
StatisticsModule.forRoot(),
|
StatisticsModule.forRoot(),
|
||||||
JournalEntitiesModule.withEntryComponents(),
|
JournalEntitiesModule.withEntryComponents(),
|
||||||
ResearchEntitiesModule.withEntryComponents(),
|
ResearchEntitiesModule.withEntryComponents(),
|
||||||
@@ -100,10 +111,10 @@ const DECLARATIONS = [
|
|||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
...DECLARATIONS,
|
...DECLARATIONS,
|
||||||
VersionedItemComponent
|
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
...DECLARATIONS
|
...DECLARATIONS,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ItemPageModule {
|
export class ItemPageModule {
|
||||||
|
@@ -7,10 +7,32 @@ import { TranslateModule } from '@ngx-translate/core';
|
|||||||
import { DYNAMIC_FORM_CONTROL_MAP_FN } from '@ng-dynamic-forms/core';
|
import { DYNAMIC_FORM_CONTROL_MAP_FN } from '@ng-dynamic-forms/core';
|
||||||
import { dsDynamicFormControlMapFn } from '../shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component';
|
import { dsDynamicFormControlMapFn } from '../shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component';
|
||||||
import { TabbedRelatedEntitiesSearchComponent } from './simple/related-entities/tabbed-related-entities-search/tabbed-related-entities-search.component';
|
import { TabbedRelatedEntitiesSearchComponent } from './simple/related-entities/tabbed-related-entities-search/tabbed-related-entities-search.component';
|
||||||
|
import { ItemVersionsDeleteModalComponent } from './versions/item-versions-delete-modal/item-versions-delete-modal.component';
|
||||||
|
import { ItemVersionsSummaryModalComponent } from './versions/item-versions-summary-modal/item-versions-summary-modal.component';
|
||||||
|
import { MetadataValuesComponent } from './field-components/metadata-values/metadata-values.component';
|
||||||
|
import { DsoPageVersionButtonComponent } from '../shared/dso-page/dso-page-version-button/dso-page-version-button.component';
|
||||||
|
import { PersonPageClaimButtonComponent } from '../shared/dso-page/person-page-claim-button/person-page-claim-button.component';
|
||||||
|
import { GenericItemPageFieldComponent } from './simple/field-components/specific-field/generic/generic-item-page-field.component';
|
||||||
|
import { MetadataRepresentationListComponent } from './simple/metadata-representation-list/metadata-representation-list.component';
|
||||||
|
import { RelatedItemsComponent } from './simple/related-items/related-items-component';
|
||||||
|
import { DsoPageOrcidButtonComponent } from '../shared/dso-page/dso-page-orcid-button/dso-page-orcid-button.component';
|
||||||
|
|
||||||
|
const ENTRY_COMPONENTS = [
|
||||||
|
ItemVersionsDeleteModalComponent,
|
||||||
|
ItemVersionsSummaryModalComponent,
|
||||||
|
];
|
||||||
|
|
||||||
const COMPONENTS = [
|
const COMPONENTS = [
|
||||||
|
...ENTRY_COMPONENTS,
|
||||||
RelatedEntitiesSearchComponent,
|
RelatedEntitiesSearchComponent,
|
||||||
TabbedRelatedEntitiesSearchComponent
|
TabbedRelatedEntitiesSearchComponent,
|
||||||
|
MetadataValuesComponent,
|
||||||
|
DsoPageVersionButtonComponent,
|
||||||
|
PersonPageClaimButtonComponent,
|
||||||
|
GenericItemPageFieldComponent,
|
||||||
|
MetadataRepresentationListComponent,
|
||||||
|
RelatedItemsComponent,
|
||||||
|
DsoPageOrcidButtonComponent
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -30,7 +52,8 @@ const COMPONENTS = [
|
|||||||
{
|
{
|
||||||
provide: DYNAMIC_FORM_CONTROL_MAP_FN,
|
provide: DYNAMIC_FORM_CONTROL_MAP_FN,
|
||||||
useValue: dsDynamicFormControlMapFn
|
useValue: dsDynamicFormControlMapFn
|
||||||
}
|
},
|
||||||
|
...ENTRY_COMPONENTS,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ItemSharedModule { }
|
export class ItemSharedModule { }
|
||||||
|
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
The class is designed to host information related to Video Captioning support
|
||||||
|
and used in HTML 5 video track
|
||||||
|
src: source vtt file
|
||||||
|
srclang: two letter language code
|
||||||
|
langLabel: language label
|
||||||
|
*/
|
||||||
|
export class CaptionInfo {
|
||||||
|
constructor(public src: string, public srclang: string, public langLabel: string ) {
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,190 @@
|
|||||||
|
export const languageHelper = {
|
||||||
|
ab: 'Abkhazian',
|
||||||
|
aa: 'Afar',
|
||||||
|
af: 'Afrikaans',
|
||||||
|
ak: 'Akan',
|
||||||
|
sq: 'Albanian',
|
||||||
|
am: 'Amharic',
|
||||||
|
ar: 'Arabic',
|
||||||
|
an: 'Aragonese',
|
||||||
|
hy: 'Armenian',
|
||||||
|
as: 'Assamese',
|
||||||
|
av: 'Avaric',
|
||||||
|
ae: 'Avestan',
|
||||||
|
ay: 'Aymara',
|
||||||
|
az: 'Azerbaijani',
|
||||||
|
bm: 'Bambara',
|
||||||
|
ba: 'Bashkir',
|
||||||
|
eu: 'Basque',
|
||||||
|
be: 'Belarusian',
|
||||||
|
bn: 'Bengali (Bangla)',
|
||||||
|
bh: 'Bihari',
|
||||||
|
bi: 'Bislama',
|
||||||
|
bs: 'Bosnian',
|
||||||
|
br: 'Breton',
|
||||||
|
bg: 'Bulgarian',
|
||||||
|
my: 'Burmese',
|
||||||
|
ca: 'Catalan',
|
||||||
|
ch: 'Chamorro',
|
||||||
|
ce: 'Chechen',
|
||||||
|
ny: 'Chichewa, Chewa, Nyanja',
|
||||||
|
zh: 'Chinese',
|
||||||
|
cv: 'Chuvash',
|
||||||
|
kw: 'Cornish',
|
||||||
|
co: 'Corsican',
|
||||||
|
cr: 'Cree',
|
||||||
|
hr: 'Croatian',
|
||||||
|
cs: 'Czech',
|
||||||
|
da: 'Danish',
|
||||||
|
dv: 'Divehi, Dhivehi, Maldivian',
|
||||||
|
nl: 'Dutch',
|
||||||
|
dz: 'Dzongkha',
|
||||||
|
en: 'English',
|
||||||
|
eo: 'Esperanto',
|
||||||
|
et: 'Estonian',
|
||||||
|
ee: 'Ewe',
|
||||||
|
fo: 'Faroese',
|
||||||
|
fj: 'Fijian',
|
||||||
|
fi: 'Finnish',
|
||||||
|
fr: 'French',
|
||||||
|
ff: 'Fula, Fulah, Pulaar, Pular',
|
||||||
|
gl: 'Galician',
|
||||||
|
gd: 'Gaelic (Scottish)',
|
||||||
|
gv: 'Gaelic (Manx)',
|
||||||
|
ka: 'Georgian',
|
||||||
|
de: 'German',
|
||||||
|
el: 'Greek',
|
||||||
|
gn: 'Guarani',
|
||||||
|
gu: 'Gujarati',
|
||||||
|
ht: 'Haitian Creole',
|
||||||
|
ha: 'Hausa',
|
||||||
|
he: 'Hebrew',
|
||||||
|
hz: 'Herero',
|
||||||
|
hi: 'Hindi',
|
||||||
|
ho: 'Hiri Motu',
|
||||||
|
hu: 'Hungarian',
|
||||||
|
is: 'Icelandic',
|
||||||
|
io: 'Ido',
|
||||||
|
ig: 'Igbo',
|
||||||
|
in: 'Indonesian',
|
||||||
|
ia: 'Interlingua',
|
||||||
|
ie: 'Interlingue',
|
||||||
|
iu: 'Inuktitut',
|
||||||
|
ik: 'Inupiak',
|
||||||
|
ga: 'Irish',
|
||||||
|
it: 'Italian',
|
||||||
|
ja: 'Japanese',
|
||||||
|
jv: 'Javanese',
|
||||||
|
kl: 'Kalaallisut, Greenlandic',
|
||||||
|
kn: 'Kannada',
|
||||||
|
kr: 'Kanuri',
|
||||||
|
ks: 'Kashmiri',
|
||||||
|
kk: 'Kazakh',
|
||||||
|
km: 'Khmer',
|
||||||
|
ki: 'Kikuyu',
|
||||||
|
rw: 'Kinyarwanda (Rwanda)',
|
||||||
|
rn: 'Kirundi',
|
||||||
|
ky: 'Kyrgyz',
|
||||||
|
kv: 'Komi',
|
||||||
|
kg: 'Kongo',
|
||||||
|
ko: 'Korean',
|
||||||
|
ku: 'Kurdish',
|
||||||
|
kj: 'Kwanyama',
|
||||||
|
lo: 'Lao',
|
||||||
|
la: 'Latin',
|
||||||
|
lv: 'Latvian (Lettish)',
|
||||||
|
li: 'Limburgish ( Limburger)',
|
||||||
|
ln: 'Lingala',
|
||||||
|
lt: 'Lithuanian',
|
||||||
|
lu: 'Luga-Katanga',
|
||||||
|
lg: 'Luganda, Ganda',
|
||||||
|
lb: 'Luxembourgish',
|
||||||
|
mk: 'Macedonian',
|
||||||
|
mg: 'Malagasy',
|
||||||
|
ms: 'Malay',
|
||||||
|
ml: 'Malayalam',
|
||||||
|
mt: 'Maltese',
|
||||||
|
mi: 'Maori',
|
||||||
|
mr: 'Marathi',
|
||||||
|
mh: 'Marshallese',
|
||||||
|
mo: 'Moldavian',
|
||||||
|
mn: 'Mongolian',
|
||||||
|
na: 'Nauru',
|
||||||
|
nv: 'Navajo',
|
||||||
|
ng: 'Ndonga',
|
||||||
|
nd: 'Northern Ndebele',
|
||||||
|
ne: 'Nepali',
|
||||||
|
no: 'Norwegian',
|
||||||
|
nb: 'Norwegian bokmål',
|
||||||
|
nn: 'Norwegian nynorsk',
|
||||||
|
oc: 'Occitan',
|
||||||
|
oj: 'Ojibwe',
|
||||||
|
cu: 'Old Church Slavonic, Old Bulgarian',
|
||||||
|
or: 'Oriya',
|
||||||
|
om: 'Oromo (Afaan Oromo)',
|
||||||
|
os: 'Ossetian',
|
||||||
|
pi: 'Pāli',
|
||||||
|
ps: 'Pashto, Pushto',
|
||||||
|
fa: 'Persian (Farsi)',
|
||||||
|
pl: 'Polish',
|
||||||
|
pt: 'Portuguese',
|
||||||
|
pa: 'Punjabi (Eastern)',
|
||||||
|
qu: 'Quechua',
|
||||||
|
rm: 'Romansh',
|
||||||
|
ro: 'Romanian',
|
||||||
|
ru: 'Russian',
|
||||||
|
se: 'Sami',
|
||||||
|
sm: 'Samoan',
|
||||||
|
sg: 'Sango',
|
||||||
|
sa: 'Sanskrit',
|
||||||
|
sr: 'Serbian',
|
||||||
|
sh: 'Serbo-Croatian',
|
||||||
|
st: 'Sesotho',
|
||||||
|
tn: 'Setswana',
|
||||||
|
sn: 'Shona',
|
||||||
|
ii: 'Sichuan Yi, Nuosu',
|
||||||
|
sd: 'Sindhi',
|
||||||
|
si: 'Sinhalese',
|
||||||
|
ss: 'Siswati (Swati)',
|
||||||
|
sk: 'Slovak',
|
||||||
|
sl: 'Slovenian',
|
||||||
|
so: 'Somali',
|
||||||
|
nr: 'Southern Ndebele',
|
||||||
|
es: 'Spanish',
|
||||||
|
su: 'Sundanese',
|
||||||
|
sw: 'Swahili (Kiswahili)',
|
||||||
|
sv: 'Swedish',
|
||||||
|
tl: 'Tagalog',
|
||||||
|
ty: 'Tahitian',
|
||||||
|
tg: 'Tajik',
|
||||||
|
ta: 'Tamil',
|
||||||
|
tt: 'Tatar',
|
||||||
|
te: 'Telugu',
|
||||||
|
th: 'Thai',
|
||||||
|
bo: 'Tibetan',
|
||||||
|
ti: 'Tigrinya',
|
||||||
|
to: 'Tonga',
|
||||||
|
ts: 'Tsonga',
|
||||||
|
tr: 'Turkish',
|
||||||
|
tk: 'Turkmen',
|
||||||
|
tw: 'Twi',
|
||||||
|
ug: 'Uyghur',
|
||||||
|
uk: 'Ukrainian',
|
||||||
|
ur: 'Urdu',
|
||||||
|
uz: 'Uzbek',
|
||||||
|
ve: 'Venda',
|
||||||
|
vi: 'Vietnamese',
|
||||||
|
vo: 'Volapük',
|
||||||
|
wa: 'Wallon',
|
||||||
|
cy: 'Welsh',
|
||||||
|
wo: 'Wolof',
|
||||||
|
fy: 'Western Frisian',
|
||||||
|
xh: 'Xhosa',
|
||||||
|
yi: 'Yiddish',
|
||||||
|
yo: 'Yoruba',
|
||||||
|
za: 'Zhuang, Chuang',
|
||||||
|
zu: 'Zulu'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -1,4 +1,5 @@
|
|||||||
<video
|
<video
|
||||||
|
crossorigin="anonymous"
|
||||||
#media
|
#media
|
||||||
[src]="filteredMedias[currentIndex].bitstream._links.content.href"
|
[src]="filteredMedias[currentIndex].bitstream._links.content.href"
|
||||||
id="singleVideo"
|
id="singleVideo"
|
||||||
@@ -8,7 +9,14 @@
|
|||||||
"
|
"
|
||||||
preload="none"
|
preload="none"
|
||||||
controls
|
controls
|
||||||
></video>
|
>
|
||||||
|
<ng-container *ngIf="getMediaCap(filteredMedias[currentIndex].bitstream.name) as capInfos">
|
||||||
|
<ng-container *ngFor="let capInfo of capInfos">
|
||||||
|
<track [src]="capInfo.src" [label]="capInfo.langLabel" [srclang]="capInfo.srclang" />
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
</video>
|
||||||
<div class="buttons" *ngIf="filteredMedias?.length > 1">
|
<div class="buttons" *ngIf="filteredMedias?.length > 1">
|
||||||
<button
|
<button
|
||||||
class="btn btn-primary previous"
|
class="btn btn-primary previous"
|
||||||
|
@@ -8,7 +8,7 @@ import { MediaViewerItem } from '../../../core/shared/media-viewer-item.model';
|
|||||||
import { TranslateLoaderMock } from '../../../shared/mocks/translate-loader.mock';
|
import { TranslateLoaderMock } from '../../../shared/mocks/translate-loader.mock';
|
||||||
import { FileSizePipe } from '../../../shared/utils/file-size-pipe';
|
import { FileSizePipe } from '../../../shared/utils/file-size-pipe';
|
||||||
import { VarDirective } from '../../../shared/utils/var.directive';
|
import { VarDirective } from '../../../shared/utils/var.directive';
|
||||||
import { MetadataFieldWrapperComponent } from '../../field-components/metadata-field-wrapper/metadata-field-wrapper.component';
|
import { MetadataFieldWrapperComponent } from '../../../shared/metadata-field-wrapper/metadata-field-wrapper.component';
|
||||||
import { MockBitstreamFormat1 } from '../../../shared/mocks/item.mock';
|
import { MockBitstreamFormat1 } from '../../../shared/mocks/item.mock';
|
||||||
import { MediaViewerVideoComponent } from './media-viewer-video.component';
|
import { MediaViewerVideoComponent } from './media-viewer-video.component';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { MediaViewerItem } from '../../../core/shared/media-viewer-item.model';
|
import { MediaViewerItem } from '../../../core/shared/media-viewer-item.model';
|
||||||
|
import { languageHelper } from './language-helper';
|
||||||
|
import { CaptionInfo} from './caption-info';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This componenet renders a video viewer and playlist for the media viewer
|
* This componenet renders a video viewer and playlist for the media viewer
|
||||||
@@ -26,9 +28,38 @@ export class MediaViewerVideoComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.isCollapsed = false;
|
this.isCollapsed = false;
|
||||||
this.filteredMedias = this.medias.filter(
|
this.filteredMedias = this.medias.filter((media) => media.format === 'audio' || media.format === 'video');
|
||||||
(media) => media.format === 'audio' || media.format === 'video'
|
}
|
||||||
);
|
|
||||||
|
/**
|
||||||
|
* This method check if there is caption file for the media
|
||||||
|
* The caption file name is the media name plus "-" following two letter
|
||||||
|
* language code and .vtt suffix
|
||||||
|
*
|
||||||
|
* html5 video only support WEBVTT format
|
||||||
|
*
|
||||||
|
* Two letter language code reference
|
||||||
|
* https://www.w3schools.com/tags/ref_language_codes.asp
|
||||||
|
*/
|
||||||
|
getMediaCap(name: string): CaptionInfo[] {
|
||||||
|
let filteredCapMedias: MediaViewerItem[];
|
||||||
|
let capInfos: CaptionInfo[] = [];
|
||||||
|
filteredCapMedias = this.medias
|
||||||
|
.filter((media) => media.mimetype === 'text/vtt')
|
||||||
|
.filter((media) => media.bitstream.name.substring(0, (media.bitstream.name.length - 7) ).toLowerCase() === name.toLowerCase());
|
||||||
|
|
||||||
|
if (filteredCapMedias) {
|
||||||
|
filteredCapMedias
|
||||||
|
.forEach((media, index) => {
|
||||||
|
let srclang: string = media.bitstream.name.slice(-6, -4).toLowerCase();
|
||||||
|
capInfos.push(new CaptionInfo(
|
||||||
|
media.bitstream._links.content.href,
|
||||||
|
srclang,
|
||||||
|
languageHelper[srclang]
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return capInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -13,7 +13,7 @@ import { BitstreamDataService } from '../../core/data/bitstream-data.service';
|
|||||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { MediaViewerItem } from '../../core/shared/media-viewer-item.model';
|
import { MediaViewerItem } from '../../core/shared/media-viewer-item.model';
|
||||||
import { VarDirective } from '../../shared/utils/var.directive';
|
import { VarDirective } from '../../shared/utils/var.directive';
|
||||||
import { MetadataFieldWrapperComponent } from '../field-components/metadata-field-wrapper/metadata-field-wrapper.component';
|
import { MetadataFieldWrapperComponent } from '../../shared/metadata-field-wrapper/metadata-field-wrapper.component';
|
||||||
import { FileSizePipe } from '../../shared/utils/file-size-pipe';
|
import { FileSizePipe } from '../../shared/utils/file-size-pipe';
|
||||||
|
|
||||||
describe('MediaViewerComponent', () => {
|
describe('MediaViewerComponent', () => {
|
||||||
|
@@ -108,6 +108,7 @@ export class MediaViewerComponent implements OnInit {
|
|||||||
const mediaItem = new MediaViewerItem();
|
const mediaItem = new MediaViewerItem();
|
||||||
mediaItem.bitstream = original;
|
mediaItem.bitstream = original;
|
||||||
mediaItem.format = format.mimetype.split('/')[0];
|
mediaItem.format = format.mimetype.split('/')[0];
|
||||||
|
mediaItem.mimetype = format.mimetype;
|
||||||
mediaItem.thumbnail = thumbnail ? thumbnail._links.content.href : null;
|
mediaItem.thumbnail = thumbnail ? thumbnail._links.content.href : null;
|
||||||
return mediaItem;
|
return mediaItem;
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,7 @@ import { of as observableOf } from 'rxjs';
|
|||||||
import { MockBitstreamFormat1 } from '../../../../shared/mocks/item.mock';
|
import { MockBitstreamFormat1 } from '../../../../shared/mocks/item.mock';
|
||||||
import { FileSizePipe } from '../../../../shared/utils/file-size-pipe';
|
import { FileSizePipe } from '../../../../shared/utils/file-size-pipe';
|
||||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||||
import { MetadataFieldWrapperComponent } from '../../../field-components/metadata-field-wrapper/metadata-field-wrapper.component';
|
import { MetadataFieldWrapperComponent } from '../../../../shared/metadata-field-wrapper/metadata-field-wrapper.component';
|
||||||
import { createPaginatedList } from '../../../../shared/testing/utils.test';
|
import { createPaginatedList } from '../../../../shared/testing/utils.test';
|
||||||
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
|
||||||
import { NotificationsServiceStub } from '../../../../shared/testing/notifications-service.stub';
|
import { NotificationsServiceStub } from '../../../../shared/testing/notifications-service.stub';
|
||||||
|
@@ -36,7 +36,7 @@ import { VersionDataService } from '../../../../core/data/version-data.service';
|
|||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { WorkspaceitemDataService } from '../../../../core/submission/workspaceitem-data.service';
|
import { WorkspaceitemDataService } from '../../../../core/submission/workspaceitem-data.service';
|
||||||
import { SearchService } from '../../../../core/shared/search/search.service';
|
import { SearchService } from '../../../../core/shared/search/search.service';
|
||||||
import { ItemVersionsSharedService } from '../../../../shared/item/item-versions/item-versions-shared.service';
|
import { ItemVersionsSharedService } from '../../../versions/item-versions-shared.service';
|
||||||
|
|
||||||
const noMetadata = new MetadataMap();
|
const noMetadata = new MetadataMap();
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ import { VersionHistoryDataService } from '../../../../core/data/version-history
|
|||||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||||
import { VersionDataService } from '../../../../core/data/version-data.service';
|
import { VersionDataService } from '../../../../core/data/version-data.service';
|
||||||
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
|
||||||
import { ItemVersionsSharedService } from '../../../../shared/item/item-versions/item-versions-shared.service';
|
import { ItemVersionsSharedService } from '../../../versions/item-versions-shared.service';
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils';
|
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils';
|
||||||
import { buildPaginatedList } from '../../../../core/data/paginated-list.model';
|
import { buildPaginatedList } from '../../../../core/data/paginated-list.model';
|
||||||
@@ -20,6 +20,7 @@ import { ItemDataService } from '../../../../core/data/item-data.service';
|
|||||||
import { Version } from '../../../../core/shared/version.model';
|
import { Version } from '../../../../core/shared/version.model';
|
||||||
import { RouteService } from '../../../../core/services/route.service';
|
import { RouteService } from '../../../../core/services/route.service';
|
||||||
import { TranslateLoaderMock } from '../../../../shared/testing/translate-loader.mock';
|
import { TranslateLoaderMock } from '../../../../shared/testing/translate-loader.mock';
|
||||||
|
import { ItemSharedModule } from '../../../item-shared.module';
|
||||||
|
|
||||||
const mockItem: Item = Object.assign(new Item(), {
|
const mockItem: Item = Object.assign(new Item(), {
|
||||||
bundles: createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [])),
|
bundles: createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [])),
|
||||||
@@ -66,6 +67,7 @@ describe('VersionedItemComponent', () => {
|
|||||||
useClass: TranslateLoaderMock,
|
useClass: TranslateLoaderMock,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
ItemSharedModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: VersionHistoryDataService, useValue: versionHistoryServiceSpy },
|
{ provide: VersionHistoryDataService, useValue: versionHistoryServiceSpy },
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { ItemComponent } from '../shared/item.component';
|
import { ItemComponent } from '../shared/item.component';
|
||||||
import { ItemVersionsSummaryModalComponent } from '../../../../shared/item/item-versions/item-versions-summary-modal/item-versions-summary-modal.component';
|
import { ItemVersionsSummaryModalComponent } from '../../../versions/item-versions-summary-modal/item-versions-summary-modal.component';
|
||||||
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../../../core/shared/operators';
|
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../../../core/shared/operators';
|
||||||
import { RemoteData } from '../../../../core/data/remote-data';
|
import { RemoteData } from '../../../../core/data/remote-data';
|
||||||
import { Version } from '../../../../core/shared/version.model';
|
import { Version } from '../../../../core/shared/version.model';
|
||||||
@@ -9,7 +9,7 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
|||||||
import { VersionHistoryDataService } from '../../../../core/data/version-history-data.service';
|
import { VersionHistoryDataService } from '../../../../core/data/version-history-data.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { VersionDataService } from '../../../../core/data/version-data.service';
|
import { VersionDataService } from '../../../../core/data/version-data.service';
|
||||||
import { ItemVersionsSharedService } from '../../../../shared/item/item-versions/item-versions-shared.service';
|
import { ItemVersionsSharedService } from '../../../versions/item-versions-shared.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { WorkspaceitemDataService } from '../../../../core/submission/workspaceitem-data.service';
|
import { WorkspaceitemDataService } from '../../../../core/submission/workspaceitem-data.service';
|
||||||
import { SearchService } from '../../../../core/shared/search/search.service';
|
import { SearchService } from '../../../../core/shared/search/search.service';
|
||||||
|
@@ -2,15 +2,15 @@ import { TestBed } from '@angular/core/testing';
|
|||||||
|
|
||||||
import { ItemVersionsSharedService } from './item-versions-shared.service';
|
import { ItemVersionsSharedService } from './item-versions-shared.service';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { VersionDataService } from '../../../core/data/version-data.service';
|
import { VersionDataService } from '../../core/data/version-data.service';
|
||||||
import { AuthService } from '../../../core/auth/auth.service';
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
import { NotificationsService } from '../../notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { VersionHistoryDataService } from '../../../core/data/version-history-data.service';
|
import { VersionHistoryDataService } from '../../core/data/version-history-data.service';
|
||||||
import { WorkspaceitemDataService } from '../../../core/submission/workspaceitem-data.service';
|
import { WorkspaceitemDataService } from '../../core/submission/workspaceitem-data.service';
|
||||||
import { WorkflowItemDataService } from '../../../core/submission/workflowitem-data.service';
|
import { WorkflowItemDataService } from '../../core/submission/workflowitem-data.service';
|
||||||
import { createFailedRemoteDataObject, createSuccessfulRemoteDataObject } from '../../remote-data.utils';
|
import { createFailedRemoteDataObject, createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils';
|
||||||
import { Version } from '../../../core/shared/version.model';
|
import { Version } from '../../core/shared/version.model';
|
||||||
|
|
||||||
describe('ItemVersionsSharedService', () => {
|
describe('ItemVersionsSharedService', () => {
|
||||||
let service: ItemVersionsSharedService;
|
let service: ItemVersionsSharedService;
|
@@ -1,8 +1,8 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { NotificationsService } from '../../notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
import { Version } from '../../../core/shared/version.model';
|
import { Version } from '../../core/shared/version.model';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
@@ -1,7 +1,7 @@
|
|||||||
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
import { ModalBeforeDismiss } from '../../../interfaces/modal-before-dismiss.interface';
|
import { ModalBeforeDismiss } from '../../../shared/interfaces/modal-before-dismiss.interface';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-item-versions-summary-modal',
|
selector: 'ds-item-versions-summary-modal',
|
@@ -2,33 +2,33 @@ import { ItemVersionsComponent } from './item-versions.component';
|
|||||||
import {
|
import {
|
||||||
ComponentFixture, TestBed, waitForAsync
|
ComponentFixture, TestBed, waitForAsync
|
||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
import { VarDirective } from '../../utils/var.directive';
|
import { VarDirective } from '../../shared/utils/var.directive';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { Item } from '../../../core/shared/item.model';
|
import { Item } from '../../core/shared/item.model';
|
||||||
import { Version } from '../../../core/shared/version.model';
|
import { Version } from '../../core/shared/version.model';
|
||||||
import { VersionHistory } from '../../../core/shared/version-history.model';
|
import { VersionHistory } from '../../core/shared/version-history.model';
|
||||||
import { VersionHistoryDataService } from '../../../core/data/version-history-data.service';
|
import { VersionHistoryDataService } from '../../core/data/version-history-data.service';
|
||||||
import { BrowserModule, By } from '@angular/platform-browser';
|
import { BrowserModule, By } from '@angular/platform-browser';
|
||||||
import { createSuccessfulRemoteDataObject$ } from '../../remote-data.utils';
|
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||||
import { createPaginatedList } from '../../testing/utils.test';
|
import { createPaginatedList } from '../../shared/testing/utils.test';
|
||||||
import { EMPTY, of, of as observableOf } from 'rxjs';
|
import { EMPTY, of, of as observableOf } from 'rxjs';
|
||||||
import { PaginationService } from '../../../core/pagination/pagination.service';
|
import { PaginationService } from '../../core/pagination/pagination.service';
|
||||||
import { PaginationServiceStub } from '../../testing/pagination-service.stub';
|
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
|
||||||
import { AuthService } from '../../../core/auth/auth.service';
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
import { VersionDataService } from '../../../core/data/version-data.service';
|
import { VersionDataService } from '../../core/data/version-data.service';
|
||||||
import { ItemDataService } from '../../../core/data/item-data.service';
|
import { ItemDataService } from '../../core/data/item-data.service';
|
||||||
import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { NotificationsService } from '../../notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { NotificationsServiceStub } from '../../testing/notifications-service.stub';
|
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
|
||||||
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
|
||||||
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
|
import { FeatureID } from '../../core/data/feature-authorization/feature-id';
|
||||||
import { WorkspaceitemDataService } from '../../../core/submission/workspaceitem-data.service';
|
import { WorkspaceitemDataService } from '../../core/submission/workspaceitem-data.service';
|
||||||
import { WorkflowItemDataService } from '../../../core/submission/workflowitem-data.service';
|
import { WorkflowItemDataService } from '../../core/submission/workflowitem-data.service';
|
||||||
import { ConfigurationDataService } from '../../../core/data/configuration-data.service';
|
import { ConfigurationDataService } from '../../core/data/configuration-data.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { ItemSharedModule } from '../item-shared.module';
|
||||||
|
|
||||||
describe('ItemVersionsComponent', () => {
|
describe('ItemVersionsComponent', () => {
|
||||||
let component: ItemVersionsComponent;
|
let component: ItemVersionsComponent;
|
||||||
@@ -137,7 +137,7 @@ describe('ItemVersionsComponent', () => {
|
|||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [ItemVersionsComponent, VarDirective],
|
declarations: [ItemVersionsComponent, VarDirective],
|
||||||
imports: [TranslateModule.forRoot(), CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule],
|
imports: [TranslateModule.forRoot(), CommonModule, FormsModule, ReactiveFormsModule, BrowserModule, ItemSharedModule],
|
||||||
providers: [
|
providers: [
|
||||||
{provide: PaginationService, useValue: new PaginationServiceStub()},
|
{provide: PaginationService, useValue: new PaginationServiceStub()},
|
||||||
{provide: FormBuilder, useValue: new FormBuilder()},
|
{provide: FormBuilder, useValue: new FormBuilder()},
|
@@ -1,7 +1,7 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { Item } from '../../../core/shared/item.model';
|
import { Item } from '../../core/shared/item.model';
|
||||||
import { Version } from '../../../core/shared/version.model';
|
import { Version } from '../../core/shared/version.model';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
import {
|
import {
|
||||||
BehaviorSubject,
|
BehaviorSubject,
|
||||||
combineLatest,
|
combineLatest,
|
||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
of,
|
of,
|
||||||
Subscription,
|
Subscription,
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
import { VersionHistory } from '../../../core/shared/version-history.model';
|
import { VersionHistory } from '../../core/shared/version-history.model';
|
||||||
import {
|
import {
|
||||||
getAllSucceededRemoteData,
|
getAllSucceededRemoteData,
|
||||||
getAllSucceededRemoteDataPayload,
|
getAllSucceededRemoteDataPayload,
|
||||||
@@ -17,37 +17,37 @@ import {
|
|||||||
getFirstSucceededRemoteData,
|
getFirstSucceededRemoteData,
|
||||||
getFirstSucceededRemoteDataPayload,
|
getFirstSucceededRemoteDataPayload,
|
||||||
getRemoteDataPayload
|
getRemoteDataPayload
|
||||||
} from '../../../core/shared/operators';
|
} from '../../core/shared/operators';
|
||||||
import { map, mergeMap, startWith, switchMap, take, tap } from 'rxjs/operators';
|
import { map, mergeMap, startWith, switchMap, take, tap } from 'rxjs/operators';
|
||||||
import { PaginatedList } from '../../../core/data/paginated-list.model';
|
import { PaginatedList } from '../../core/data/paginated-list.model';
|
||||||
import { PaginationComponentOptions } from '../../pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||||
import { VersionHistoryDataService } from '../../../core/data/version-history-data.service';
|
import { VersionHistoryDataService } from '../../core/data/version-history-data.service';
|
||||||
import { PaginatedSearchOptions } from '../../search/models/paginated-search-options.model';
|
import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model';
|
||||||
import { AlertType } from '../../alert/aletr-type';
|
import { AlertType } from '../../shared/alert/aletr-type';
|
||||||
import { followLink } from '../../utils/follow-link-config.model';
|
import { followLink } from '../../shared/utils/follow-link-config.model';
|
||||||
import { hasValue, hasValueOperator } from '../../empty.util';
|
import { hasValue, hasValueOperator } from '../../shared/empty.util';
|
||||||
import { PaginationService } from '../../../core/pagination/pagination.service';
|
import { PaginationService } from '../../core/pagination/pagination.service';
|
||||||
import {
|
import {
|
||||||
getItemEditVersionhistoryRoute,
|
getItemEditVersionhistoryRoute,
|
||||||
getItemPageRoute,
|
getItemPageRoute,
|
||||||
getItemVersionRoute
|
getItemVersionRoute
|
||||||
} from '../../../item-page/item-page-routing-paths';
|
} from '../item-page-routing-paths';
|
||||||
import { FormBuilder } from '@angular/forms';
|
import { FormBuilder } from '@angular/forms';
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { ItemVersionsSummaryModalComponent } from './item-versions-summary-modal/item-versions-summary-modal.component';
|
import { ItemVersionsSummaryModalComponent } from './item-versions-summary-modal/item-versions-summary-modal.component';
|
||||||
import { NotificationsService } from '../../notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { ItemVersionsDeleteModalComponent } from './item-versions-delete-modal/item-versions-delete-modal.component';
|
import { ItemVersionsDeleteModalComponent } from './item-versions-delete-modal/item-versions-delete-modal.component';
|
||||||
import { VersionDataService } from '../../../core/data/version-data.service';
|
import { VersionDataService } from '../../core/data/version-data.service';
|
||||||
import { ItemDataService } from '../../../core/data/item-data.service';
|
import { ItemDataService } from '../../core/data/item-data.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
|
||||||
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
|
import { FeatureID } from '../../core/data/feature-authorization/feature-id';
|
||||||
import { ItemVersionsSharedService } from './item-versions-shared.service';
|
import { ItemVersionsSharedService } from './item-versions-shared.service';
|
||||||
import { WorkspaceItem } from '../../../core/submission/models/workspaceitem.model';
|
import { WorkspaceItem } from '../../core/submission/models/workspaceitem.model';
|
||||||
import { WorkspaceitemDataService } from '../../../core/submission/workspaceitem-data.service';
|
import { WorkspaceitemDataService } from '../../core/submission/workspaceitem-data.service';
|
||||||
import { WorkflowItemDataService } from '../../../core/submission/workflowitem-data.service';
|
import { WorkflowItemDataService } from '../../core/submission/workflowitem-data.service';
|
||||||
import { ConfigurationDataService } from '../../../core/data/configuration-data.service';
|
import { ConfigurationDataService } from '../../core/data/configuration-data.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-item-versions',
|
selector: 'ds-item-versions',
|
32
src/app/item-page/versions/item-versions.module.ts
Normal file
32
src/app/item-page/versions/item-versions.module.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { SharedModule } from '../../shared/shared.module';
|
||||||
|
import { ItemVersionsComponent } from './item-versions.component';
|
||||||
|
import { ItemVersionsNoticeComponent } from './notice/item-versions-notice.component';
|
||||||
|
|
||||||
|
const DECLARATIONS = [
|
||||||
|
ItemVersionsComponent,
|
||||||
|
ItemVersionsNoticeComponent,
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
SharedModule,
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
...DECLARATIONS,
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
...DECLARATIONS,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class ItemVersionsModule {
|
||||||
|
|
||||||
|
}
|
@@ -3,13 +3,13 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { VersionHistory } from '../../../../core/shared/version-history.model';
|
import { VersionHistory } from '../../../core/shared/version-history.model';
|
||||||
import { Version } from '../../../../core/shared/version.model';
|
import { Version } from '../../../core/shared/version.model';
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../core/shared/item.model';
|
||||||
import { VersionHistoryDataService } from '../../../../core/data/version-history-data.service';
|
import { VersionHistoryDataService } from '../../../core/data/version-history-data.service';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { createSuccessfulRemoteDataObject$ } from '../../../remote-data.utils';
|
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||||
import { createPaginatedList } from '../../../testing/utils.test';
|
import { createPaginatedList } from '../../../shared/testing/utils.test';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
|
|
@@ -1,19 +1,19 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../core/shared/item.model';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { RemoteData } from '../../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
import { VersionHistory } from '../../../../core/shared/version-history.model';
|
import { VersionHistory } from '../../../core/shared/version-history.model';
|
||||||
import { Version } from '../../../../core/shared/version.model';
|
import { Version } from '../../../core/shared/version.model';
|
||||||
import { hasValue, hasValueOperator } from '../../../empty.util';
|
import { hasValue, hasValueOperator } from '../../../shared/empty.util';
|
||||||
import {
|
import {
|
||||||
getAllSucceededRemoteData,
|
getAllSucceededRemoteData,
|
||||||
getFirstSucceededRemoteDataPayload,
|
getFirstSucceededRemoteDataPayload,
|
||||||
getRemoteDataPayload
|
getRemoteDataPayload
|
||||||
} from '../../../../core/shared/operators';
|
} from '../../../core/shared/operators';
|
||||||
import { map, startWith, switchMap } from 'rxjs/operators';
|
import { map, startWith, switchMap } from 'rxjs/operators';
|
||||||
import { VersionHistoryDataService } from '../../../../core/data/version-history-data.service';
|
import { VersionHistoryDataService } from '../../../core/data/version-history-data.service';
|
||||||
import { AlertType } from '../../../alert/aletr-type';
|
import { AlertType } from '../../../shared/alert/aletr-type';
|
||||||
import { getItemPageRoute } from '../../../../item-page/item-page-routing-paths';
|
import { getItemPageRoute } from '../../item-page-routing-paths';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-item-versions-notice',
|
selector: 'ds-item-versions-notice',
|
@@ -17,9 +17,16 @@ import { PoolSearchResultDetailElementComponent } from '../shared/object-detail/
|
|||||||
import { ClaimedApprovedSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-approved-search-result/claimed-approved-search-result-list-element.component';
|
import { ClaimedApprovedSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-approved-search-result/claimed-approved-search-result-list-element.component';
|
||||||
import { ClaimedDeclinedSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-search-result/claimed-declined-search-result-list-element.component';
|
import { ClaimedDeclinedSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-search-result/claimed-declined-search-result-list-element.component';
|
||||||
import { ResearchEntitiesModule } from '../entity-groups/research-entities/research-entities.module';
|
import { ResearchEntitiesModule } from '../entity-groups/research-entities/research-entities.module';
|
||||||
|
import { ItemSubmitterComponent } from '../shared/object-collection/shared/mydspace-item-submitter/item-submitter.component';
|
||||||
|
import { ItemDetailPreviewComponent } from '../shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component';
|
||||||
|
import { ItemDetailPreviewFieldComponent } from '../shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview-field/item-detail-preview-field.component';
|
||||||
|
import { ItemListPreviewComponent } from '../shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component';
|
||||||
|
import { ThemedItemListPreviewComponent } from '../shared/object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component';
|
||||||
|
import { MyDSpaceItemStatusComponent } from '../shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component';
|
||||||
|
import { JournalEntitiesModule } from '../entity-groups/journal-entities/journal-entities.module';
|
||||||
|
import { MyDSpaceActionsModule } from '../shared/mydspace-actions/mydspace-actions.module';
|
||||||
|
|
||||||
const ENTRY_COMPONENTS = [
|
const ENTRY_COMPONENTS = [
|
||||||
// put only entry components that use custom decorator
|
|
||||||
WorkspaceItemSearchResultListElementComponent,
|
WorkspaceItemSearchResultListElementComponent,
|
||||||
WorkflowItemSearchResultListElementComponent,
|
WorkflowItemSearchResultListElementComponent,
|
||||||
ClaimedSearchResultListElementComponent,
|
ClaimedSearchResultListElementComponent,
|
||||||
@@ -31,7 +38,17 @@ const ENTRY_COMPONENTS = [
|
|||||||
WorkflowItemSearchResultDetailElementComponent,
|
WorkflowItemSearchResultDetailElementComponent,
|
||||||
ClaimedTaskSearchResultDetailElementComponent,
|
ClaimedTaskSearchResultDetailElementComponent,
|
||||||
PoolSearchResultDetailElementComponent,
|
PoolSearchResultDetailElementComponent,
|
||||||
ItemSearchResultListElementSubmissionComponent
|
ItemSearchResultListElementSubmissionComponent,
|
||||||
|
];
|
||||||
|
|
||||||
|
const DECLARATIONS = [
|
||||||
|
...ENTRY_COMPONENTS,
|
||||||
|
ItemSubmitterComponent,
|
||||||
|
ItemDetailPreviewComponent,
|
||||||
|
ItemDetailPreviewFieldComponent,
|
||||||
|
ItemListPreviewComponent,
|
||||||
|
ThemedItemListPreviewComponent,
|
||||||
|
MyDSpaceItemStatusComponent,
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -39,10 +56,12 @@ const ENTRY_COMPONENTS = [
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
SharedModule,
|
SharedModule,
|
||||||
MyDspacePageRoutingModule,
|
MyDspacePageRoutingModule,
|
||||||
ResearchEntitiesModule.withEntryComponents()
|
MyDSpaceActionsModule,
|
||||||
|
ResearchEntitiesModule.withEntryComponents(),
|
||||||
|
JournalEntitiesModule.withEntryComponents(),
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
...ENTRY_COMPONENTS
|
...DECLARATIONS,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
nav.navbar {
|
nav.navbar {
|
||||||
border-bottom: 1px var(--bs-gray-400) solid;
|
border-bottom: 1px var(--ds-header-navbar-border-bottom-color) solid;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,7 +7,6 @@ import { ConfigurationSearchPageGuard } from './configuration-search-page.guard'
|
|||||||
import { SearchTrackerComponent } from './search-tracker.component';
|
import { SearchTrackerComponent } from './search-tracker.component';
|
||||||
import { StatisticsModule } from '../statistics/statistics.module';
|
import { StatisticsModule } from '../statistics/statistics.module';
|
||||||
import { SearchPageComponent } from './search-page.component';
|
import { SearchPageComponent } from './search-page.component';
|
||||||
import { SidebarFilterService } from '../shared/sidebar/filter/sidebar-filter.service';
|
|
||||||
import { SearchFilterService } from '../core/shared/search/search-filter.service';
|
import { SearchFilterService } from '../core/shared/search/search-filter.service';
|
||||||
import { SearchConfigurationService } from '../core/shared/search/search-configuration.service';
|
import { SearchConfigurationService } from '../core/shared/search/search-configuration.service';
|
||||||
import { JournalEntitiesModule } from '../entity-groups/journal-entities/journal-entities.module';
|
import { JournalEntitiesModule } from '../entity-groups/journal-entities/journal-entities.module';
|
||||||
@@ -34,7 +33,6 @@ const components = [
|
|||||||
declarations: components,
|
declarations: components,
|
||||||
providers: [
|
providers: [
|
||||||
SidebarService,
|
SidebarService,
|
||||||
SidebarFilterService,
|
|
||||||
SearchFilterService,
|
SearchFilterService,
|
||||||
ConfigurationSearchPageGuard,
|
ConfigurationSearchPageGuard,
|
||||||
SearchConfigurationService
|
SearchConfigurationService
|
||||||
|
@@ -49,7 +49,7 @@ const LAZY_KLARO = new InjectionToken<Promise<any>>(
|
|||||||
'Lazily loaded Klaro',
|
'Lazily loaded Klaro',
|
||||||
{
|
{
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
factory: async () => (await import('klaro')),
|
factory: async () => (await import('klaro/dist/klaro-no-translations')),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -115,7 +115,6 @@ export class BrowserKlaroService extends KlaroService {
|
|||||||
if (hideRegistrationVerification) {
|
if (hideRegistrationVerification) {
|
||||||
servicesToHideArray.push(CAPTCHA_NAME);
|
servicesToHideArray.push(CAPTCHA_NAME);
|
||||||
}
|
}
|
||||||
console.log(servicesToHideArray);
|
|
||||||
return servicesToHideArray;
|
return servicesToHideArray;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@@ -38,6 +38,8 @@ import { DsDynamicTypeBindRelationService } from './builder/ds-dynamic-form-ui/d
|
|||||||
import { FormService } from './form.service';
|
import { FormService } from './form.service';
|
||||||
import { NgxMaskModule } from 'ngx-mask';
|
import { NgxMaskModule } from 'ngx-mask';
|
||||||
import { ThemedExternalSourceEntryImportModalComponent } from './builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/themed-external-source-entry-import-modal.component';
|
import { ThemedExternalSourceEntryImportModalComponent } from './builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/themed-external-source-entry-import-modal.component';
|
||||||
|
import { NgbDatepickerModule, NgbTimepickerModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { CdkTreeModule } from '@angular/cdk/tree';
|
||||||
|
|
||||||
const COMPONENTS = [
|
const COMPONENTS = [
|
||||||
CustomSwitchComponent,
|
CustomSwitchComponent,
|
||||||
@@ -86,6 +88,9 @@ const DIRECTIVES = [
|
|||||||
TranslateModule,
|
TranslateModule,
|
||||||
SortablejsModule,
|
SortablejsModule,
|
||||||
NgxMaskModule.forRoot(),
|
NgxMaskModule.forRoot(),
|
||||||
|
NgbDatepickerModule,
|
||||||
|
NgbTimepickerModule,
|
||||||
|
CdkTreeModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
...COMPONENTS,
|
...COMPONENTS,
|
||||||
|
@@ -0,0 +1,3 @@
|
|||||||
|
<button class="btn btn-lg btn-primary btn-block mt-2 text-white" (click)="redirectToExternalProvider()">
|
||||||
|
<i class="fas fa-sign-in-alt"></i> {{getButtonLabel() | translate}}
|
||||||
|
</button>
|
@@ -14,18 +14,17 @@ import { AuthServiceStub } from '../../../testing/auth-service.stub';
|
|||||||
import { storeModuleConfig } from '../../../../app.reducer';
|
import { storeModuleConfig } from '../../../../app.reducer';
|
||||||
import { AuthMethod } from '../../../../core/auth/models/auth.method';
|
import { AuthMethod } from '../../../../core/auth/models/auth.method';
|
||||||
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
||||||
import { LogInOrcidComponent } from './log-in-orcid.component';
|
import { LogInExternalProviderComponent } from './log-in-external-provider.component';
|
||||||
import { NativeWindowService } from '../../../../core/services/window.service';
|
import { NativeWindowService } from '../../../../core/services/window.service';
|
||||||
import { RouterStub } from '../../../testing/router.stub';
|
import { RouterStub } from '../../../testing/router.stub';
|
||||||
import { ActivatedRouteStub } from '../../../testing/active-router.stub';
|
import { ActivatedRouteStub } from '../../../testing/active-router.stub';
|
||||||
import { NativeWindowMockFactory } from '../../../mocks/mock-native-window-ref';
|
import { NativeWindowMockFactory } from '../../../mocks/mock-native-window-ref';
|
||||||
import { HardRedirectService } from '../../../../core/services/hard-redirect.service';
|
import { HardRedirectService } from '../../../../core/services/hard-redirect.service';
|
||||||
|
|
||||||
|
describe('LogInExternalProviderComponent', () => {
|
||||||
|
|
||||||
describe('LogInOrcidComponent', () => {
|
let component: LogInExternalProviderComponent;
|
||||||
|
let fixture: ComponentFixture<LogInExternalProviderComponent>;
|
||||||
let component: LogInOrcidComponent;
|
|
||||||
let fixture: ComponentFixture<LogInOrcidComponent>;
|
|
||||||
let page: Page;
|
let page: Page;
|
||||||
let user: EPerson;
|
let user: EPerson;
|
||||||
let componentAsAny: any;
|
let componentAsAny: any;
|
||||||
@@ -66,7 +65,7 @@ describe('LogInOrcidComponent', () => {
|
|||||||
TranslateModule.forRoot()
|
TranslateModule.forRoot()
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
LogInOrcidComponent
|
LogInExternalProviderComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: AuthService, useClass: AuthServiceStub },
|
{ provide: AuthService, useClass: AuthServiceStub },
|
||||||
@@ -88,7 +87,7 @@ describe('LogInOrcidComponent', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// create component and test fixture
|
// create component and test fixture
|
||||||
fixture = TestBed.createComponent(LogInOrcidComponent);
|
fixture = TestBed.createComponent(LogInExternalProviderComponent);
|
||||||
|
|
||||||
// get test component from the fixture
|
// get test component from the fixture
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
@@ -109,7 +108,7 @@ describe('LogInOrcidComponent', () => {
|
|||||||
expect(componentAsAny.injectedAuthMethodModel.location).toBe(location);
|
expect(componentAsAny.injectedAuthMethodModel.location).toBe(location);
|
||||||
expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl);
|
expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl);
|
||||||
|
|
||||||
component.redirectToOrcid();
|
component.redirectToExternalProvider();
|
||||||
|
|
||||||
expect(setHrefSpy).toHaveBeenCalledWith(currentUrl);
|
expect(setHrefSpy).toHaveBeenCalledWith(currentUrl);
|
||||||
|
|
||||||
@@ -124,7 +123,7 @@ describe('LogInOrcidComponent', () => {
|
|||||||
expect(componentAsAny.injectedAuthMethodModel.location).toBe(location);
|
expect(componentAsAny.injectedAuthMethodModel.location).toBe(location);
|
||||||
expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl);
|
expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl);
|
||||||
|
|
||||||
component.redirectToOrcid();
|
component.redirectToExternalProvider();
|
||||||
|
|
||||||
expect(setHrefSpy).toHaveBeenCalledWith(currentUrl);
|
expect(setHrefSpy).toHaveBeenCalledWith(currentUrl);
|
||||||
|
|
||||||
@@ -143,7 +142,7 @@ class Page {
|
|||||||
public navigateSpy: jasmine.Spy;
|
public navigateSpy: jasmine.Spy;
|
||||||
public passwordInput: HTMLInputElement;
|
public passwordInput: HTMLInputElement;
|
||||||
|
|
||||||
constructor(private component: LogInOrcidComponent, private fixture: ComponentFixture<LogInOrcidComponent>) {
|
constructor(private component: LogInExternalProviderComponent, private fixture: ComponentFixture<LogInExternalProviderComponent>) {
|
||||||
// use injector to get services
|
// use injector to get services
|
||||||
const injector = fixture.debugElement.injector;
|
const injector = fixture.debugElement.injector;
|
||||||
const store = injector.get(Store);
|
const store = injector.get(Store);
|
@@ -4,22 +4,27 @@ import { Observable } from 'rxjs';
|
|||||||
import { take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
import { select, Store } from '@ngrx/store';
|
import { select, Store } from '@ngrx/store';
|
||||||
|
|
||||||
import { AuthMethod } from '../../../core/auth/models/auth.method';
|
import { AuthMethod } from '../../../../core/auth/models/auth.method';
|
||||||
|
|
||||||
import { isAuthenticated, isAuthenticationLoading } from '../../../core/auth/selectors';
|
import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/selectors';
|
||||||
import { NativeWindowRef, NativeWindowService } from '../../../core/services/window.service';
|
import { NativeWindowRef, NativeWindowService } from '../../../../core/services/window.service';
|
||||||
import { isEmpty, isNotNull } from '../../empty.util';
|
import { isEmpty, isNotNull } from '../../../empty.util';
|
||||||
import { AuthService } from '../../../core/auth/auth.service';
|
import { AuthService } from '../../../../core/auth/auth.service';
|
||||||
import { HardRedirectService } from '../../../core/services/hard-redirect.service';
|
import { HardRedirectService } from '../../../../core/services/hard-redirect.service';
|
||||||
import { URLCombiner } from '../../../core/url-combiner/url-combiner';
|
import { URLCombiner } from '../../../../core/url-combiner/url-combiner';
|
||||||
import { CoreState } from '../../../core/core-state.model';
|
import { CoreState } from '../../../../core/core-state.model';
|
||||||
|
import { renderAuthMethodFor } from '../log-in.methods-decorator';
|
||||||
|
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-log-in-external-provider',
|
selector: 'ds-log-in-external-provider',
|
||||||
template: ''
|
templateUrl: './log-in-external-provider.component.html',
|
||||||
|
styleUrls: ['./log-in-external-provider.component.scss']
|
||||||
})
|
})
|
||||||
export abstract class LogInExternalProviderComponent implements OnInit {
|
@renderAuthMethodFor(AuthMethodType.Oidc)
|
||||||
|
@renderAuthMethodFor(AuthMethodType.Shibboleth)
|
||||||
|
@renderAuthMethodFor(AuthMethodType.Orcid)
|
||||||
|
export class LogInExternalProviderComponent implements OnInit {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The authentication method data.
|
* The authentication method data.
|
||||||
@@ -107,4 +112,7 @@ export abstract class LogInExternalProviderComponent implements OnInit {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getButtonLabel() {
|
||||||
|
return `login.form.${this.authMethod.authMethodType}`;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -1,3 +0,0 @@
|
|||||||
<button class="btn btn-lg btn-primary btn-block mt-2 text-white" (click)="redirectToOidc()">
|
|
||||||
<i class="fas fa-sign-in-alt"></i> {{"login.form.oidc" | translate}}
|
|
||||||
</button>
|
|
@@ -1,155 +0,0 @@
|
|||||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
|
||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { provideMockStore } from '@ngrx/store/testing';
|
|
||||||
import { Store, StoreModule } from '@ngrx/store';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
import { EPerson } from '../../../../core/eperson/models/eperson.model';
|
|
||||||
import { EPersonMock } from '../../../testing/eperson.mock';
|
|
||||||
import { authReducer } from '../../../../core/auth/auth.reducer';
|
|
||||||
import { AuthService } from '../../../../core/auth/auth.service';
|
|
||||||
import { AuthServiceStub } from '../../../testing/auth-service.stub';
|
|
||||||
import { storeModuleConfig } from '../../../../app.reducer';
|
|
||||||
import { AuthMethod } from '../../../../core/auth/models/auth.method';
|
|
||||||
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
|
||||||
import { LogInOidcComponent } from './log-in-oidc.component';
|
|
||||||
import { NativeWindowService } from '../../../../core/services/window.service';
|
|
||||||
import { RouterStub } from '../../../testing/router.stub';
|
|
||||||
import { ActivatedRouteStub } from '../../../testing/active-router.stub';
|
|
||||||
import { NativeWindowMockFactory } from '../../../mocks/mock-native-window-ref';
|
|
||||||
import { HardRedirectService } from '../../../../core/services/hard-redirect.service';
|
|
||||||
|
|
||||||
|
|
||||||
describe('LogInOidcComponent', () => {
|
|
||||||
|
|
||||||
let component: LogInOidcComponent;
|
|
||||||
let fixture: ComponentFixture<LogInOidcComponent>;
|
|
||||||
let page: Page;
|
|
||||||
let user: EPerson;
|
|
||||||
let componentAsAny: any;
|
|
||||||
let setHrefSpy;
|
|
||||||
let oidcBaseUrl;
|
|
||||||
let location;
|
|
||||||
let initialState: any;
|
|
||||||
let hardRedirectService: HardRedirectService;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
user = EPersonMock;
|
|
||||||
oidcBaseUrl = 'dspace-rest.test/oidc?redirectUrl=';
|
|
||||||
location = oidcBaseUrl + 'http://dspace-angular.test/home';
|
|
||||||
|
|
||||||
hardRedirectService = jasmine.createSpyObj('hardRedirectService', {
|
|
||||||
getCurrentRoute: {},
|
|
||||||
redirect: {}
|
|
||||||
});
|
|
||||||
|
|
||||||
initialState = {
|
|
||||||
core: {
|
|
||||||
auth: {
|
|
||||||
authenticated: false,
|
|
||||||
loaded: false,
|
|
||||||
blocking: false,
|
|
||||||
loading: false,
|
|
||||||
authMethods: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
|
||||||
// refine the test module by declaring the test component
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
imports: [
|
|
||||||
StoreModule.forRoot({ auth: authReducer }, storeModuleConfig),
|
|
||||||
TranslateModule.forRoot()
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
LogInOidcComponent
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
{ provide: AuthService, useClass: AuthServiceStub },
|
|
||||||
{ provide: 'authMethodProvider', useValue: new AuthMethod(AuthMethodType.Oidc, location) },
|
|
||||||
{ provide: 'isStandalonePage', useValue: true },
|
|
||||||
{ provide: NativeWindowService, useFactory: NativeWindowMockFactory },
|
|
||||||
{ provide: Router, useValue: new RouterStub() },
|
|
||||||
{ provide: ActivatedRoute, useValue: new ActivatedRouteStub() },
|
|
||||||
{ provide: HardRedirectService, useValue: hardRedirectService },
|
|
||||||
provideMockStore({ initialState }),
|
|
||||||
],
|
|
||||||
schemas: [
|
|
||||||
CUSTOM_ELEMENTS_SCHEMA
|
|
||||||
]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
// create component and test fixture
|
|
||||||
fixture = TestBed.createComponent(LogInOidcComponent);
|
|
||||||
|
|
||||||
// get test component from the fixture
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
componentAsAny = component;
|
|
||||||
|
|
||||||
// create page
|
|
||||||
page = new Page(component, fixture);
|
|
||||||
setHrefSpy = spyOnProperty(componentAsAny._window.nativeWindow.location, 'href', 'set').and.callThrough();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set the properly a new redirectUrl', () => {
|
|
||||||
const currentUrl = 'http://dspace-angular.test/collections/12345';
|
|
||||||
componentAsAny._window.nativeWindow.location.href = currentUrl;
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(componentAsAny.injectedAuthMethodModel.location).toBe(location);
|
|
||||||
expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl);
|
|
||||||
|
|
||||||
component.redirectToOidc();
|
|
||||||
|
|
||||||
expect(setHrefSpy).toHaveBeenCalledWith(currentUrl);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not set a new redirectUrl', () => {
|
|
||||||
const currentUrl = 'http://dspace-angular.test/home';
|
|
||||||
componentAsAny._window.nativeWindow.location.href = currentUrl;
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(componentAsAny.injectedAuthMethodModel.location).toBe(location);
|
|
||||||
expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl);
|
|
||||||
|
|
||||||
component.redirectToOidc();
|
|
||||||
|
|
||||||
expect(setHrefSpy).toHaveBeenCalledWith(currentUrl);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* I represent the DOM elements and attach spies.
|
|
||||||
*
|
|
||||||
* @class Page
|
|
||||||
*/
|
|
||||||
class Page {
|
|
||||||
|
|
||||||
public emailInput: HTMLInputElement;
|
|
||||||
public navigateSpy: jasmine.Spy;
|
|
||||||
public passwordInput: HTMLInputElement;
|
|
||||||
|
|
||||||
constructor(private component: LogInOidcComponent, private fixture: ComponentFixture<LogInOidcComponent>) {
|
|
||||||
// use injector to get services
|
|
||||||
const injector = fixture.debugElement.injector;
|
|
||||||
const store = injector.get(Store);
|
|
||||||
|
|
||||||
// add spies
|
|
||||||
this.navigateSpy = spyOn(store, 'dispatch');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,21 +0,0 @@
|
|||||||
import { Component, } from '@angular/core';
|
|
||||||
|
|
||||||
import { renderAuthMethodFor } from '../log-in.methods-decorator';
|
|
||||||
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
|
||||||
import { LogInExternalProviderComponent } from '../log-in-external-provider.component';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'ds-log-in-oidc',
|
|
||||||
templateUrl: './log-in-oidc.component.html',
|
|
||||||
})
|
|
||||||
@renderAuthMethodFor(AuthMethodType.Oidc)
|
|
||||||
export class LogInOidcComponent extends LogInExternalProviderComponent {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redirect to orcid authentication url
|
|
||||||
*/
|
|
||||||
redirectToOidc() {
|
|
||||||
this.redirectToExternalProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
<button class="btn btn-lg btn-primary btn-block mt-2 text-white" (click)="redirectToOrcid()">
|
|
||||||
<i class="fas fa-sign-in-alt"></i> {{"login.form.orcid" | translate}}
|
|
||||||
</button>
|
|
@@ -1,21 +0,0 @@
|
|||||||
import { Component, } from '@angular/core';
|
|
||||||
|
|
||||||
import { renderAuthMethodFor } from '../log-in.methods-decorator';
|
|
||||||
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
|
||||||
import { LogInExternalProviderComponent } from '../log-in-external-provider.component';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'ds-log-in-orcid',
|
|
||||||
templateUrl: './log-in-orcid.component.html',
|
|
||||||
})
|
|
||||||
@renderAuthMethodFor(AuthMethodType.Orcid)
|
|
||||||
export class LogInOrcidComponent extends LogInExternalProviderComponent {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redirect to orcid authentication url
|
|
||||||
*/
|
|
||||||
redirectToOrcid() {
|
|
||||||
this.redirectToExternalProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
<button class="btn btn-lg btn-primary btn-block mt-2 text-white" (click)="redirectToShibboleth()">
|
|
||||||
<i class="fas fa-sign-in-alt"></i> {{"login.form.shibboleth" | translate}}
|
|
||||||
</button>
|
|
@@ -1,155 +0,0 @@
|
|||||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
|
||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { provideMockStore } from '@ngrx/store/testing';
|
|
||||||
import { Store, StoreModule } from '@ngrx/store';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
import { EPerson } from '../../../../core/eperson/models/eperson.model';
|
|
||||||
import { EPersonMock } from '../../../testing/eperson.mock';
|
|
||||||
import { authReducer } from '../../../../core/auth/auth.reducer';
|
|
||||||
import { AuthService } from '../../../../core/auth/auth.service';
|
|
||||||
import { AuthServiceStub } from '../../../testing/auth-service.stub';
|
|
||||||
import { storeModuleConfig } from '../../../../app.reducer';
|
|
||||||
import { AuthMethod } from '../../../../core/auth/models/auth.method';
|
|
||||||
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
|
||||||
import { LogInShibbolethComponent } from './log-in-shibboleth.component';
|
|
||||||
import { NativeWindowService } from '../../../../core/services/window.service';
|
|
||||||
import { RouterStub } from '../../../testing/router.stub';
|
|
||||||
import { ActivatedRouteStub } from '../../../testing/active-router.stub';
|
|
||||||
import { NativeWindowMockFactory } from '../../../mocks/mock-native-window-ref';
|
|
||||||
import { HardRedirectService } from '../../../../core/services/hard-redirect.service';
|
|
||||||
|
|
||||||
|
|
||||||
describe('LogInShibbolethComponent', () => {
|
|
||||||
|
|
||||||
let component: LogInShibbolethComponent;
|
|
||||||
let fixture: ComponentFixture<LogInShibbolethComponent>;
|
|
||||||
let page: Page;
|
|
||||||
let user: EPerson;
|
|
||||||
let componentAsAny: any;
|
|
||||||
let setHrefSpy;
|
|
||||||
let shibbolethBaseUrl;
|
|
||||||
let location;
|
|
||||||
let initialState: any;
|
|
||||||
let hardRedirectService: HardRedirectService;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
user = EPersonMock;
|
|
||||||
shibbolethBaseUrl = 'dspace-rest.test/shibboleth?redirectUrl=';
|
|
||||||
location = shibbolethBaseUrl + 'http://dspace-angular.test/home';
|
|
||||||
|
|
||||||
hardRedirectService = jasmine.createSpyObj('hardRedirectService', {
|
|
||||||
getCurrentRoute: {},
|
|
||||||
redirect: {}
|
|
||||||
});
|
|
||||||
|
|
||||||
initialState = {
|
|
||||||
core: {
|
|
||||||
auth: {
|
|
||||||
authenticated: false,
|
|
||||||
loaded: false,
|
|
||||||
blocking: false,
|
|
||||||
loading: false,
|
|
||||||
authMethods: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
|
||||||
// refine the test module by declaring the test component
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
imports: [
|
|
||||||
StoreModule.forRoot({ auth: authReducer }, storeModuleConfig),
|
|
||||||
TranslateModule.forRoot()
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
LogInShibbolethComponent
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
{ provide: AuthService, useClass: AuthServiceStub },
|
|
||||||
{ provide: 'authMethodProvider', useValue: new AuthMethod(AuthMethodType.Shibboleth, location) },
|
|
||||||
{ provide: 'isStandalonePage', useValue: true },
|
|
||||||
{ provide: NativeWindowService, useFactory: NativeWindowMockFactory },
|
|
||||||
{ provide: Router, useValue: new RouterStub() },
|
|
||||||
{ provide: ActivatedRoute, useValue: new ActivatedRouteStub() },
|
|
||||||
{ provide: HardRedirectService, useValue: hardRedirectService },
|
|
||||||
provideMockStore({ initialState }),
|
|
||||||
],
|
|
||||||
schemas: [
|
|
||||||
CUSTOM_ELEMENTS_SCHEMA
|
|
||||||
]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
// create component and test fixture
|
|
||||||
fixture = TestBed.createComponent(LogInShibbolethComponent);
|
|
||||||
|
|
||||||
// get test component from the fixture
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
componentAsAny = component;
|
|
||||||
|
|
||||||
// create page
|
|
||||||
page = new Page(component, fixture);
|
|
||||||
setHrefSpy = spyOnProperty(componentAsAny._window.nativeWindow.location, 'href', 'set').and.callThrough();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set the properly a new redirectUrl', () => {
|
|
||||||
const currentUrl = 'http://dspace-angular.test/collections/12345';
|
|
||||||
componentAsAny._window.nativeWindow.location.href = currentUrl;
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(componentAsAny.injectedAuthMethodModel.location).toBe(location);
|
|
||||||
expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl);
|
|
||||||
|
|
||||||
component.redirectToShibboleth();
|
|
||||||
|
|
||||||
expect(setHrefSpy).toHaveBeenCalledWith(currentUrl);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not set a new redirectUrl', () => {
|
|
||||||
const currentUrl = 'http://dspace-angular.test/home';
|
|
||||||
componentAsAny._window.nativeWindow.location.href = currentUrl;
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(componentAsAny.injectedAuthMethodModel.location).toBe(location);
|
|
||||||
expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl);
|
|
||||||
|
|
||||||
component.redirectToShibboleth();
|
|
||||||
|
|
||||||
expect(setHrefSpy).toHaveBeenCalledWith(currentUrl);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* I represent the DOM elements and attach spies.
|
|
||||||
*
|
|
||||||
* @class Page
|
|
||||||
*/
|
|
||||||
class Page {
|
|
||||||
|
|
||||||
public emailInput: HTMLInputElement;
|
|
||||||
public navigateSpy: jasmine.Spy;
|
|
||||||
public passwordInput: HTMLInputElement;
|
|
||||||
|
|
||||||
constructor(private component: LogInShibbolethComponent, private fixture: ComponentFixture<LogInShibbolethComponent>) {
|
|
||||||
// use injector to get services
|
|
||||||
const injector = fixture.debugElement.injector;
|
|
||||||
const store = injector.get(Store);
|
|
||||||
|
|
||||||
// add spies
|
|
||||||
this.navigateSpy = spyOn(store, 'dispatch');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,23 +0,0 @@
|
|||||||
import { Component, } from '@angular/core';
|
|
||||||
|
|
||||||
import { renderAuthMethodFor } from '../log-in.methods-decorator';
|
|
||||||
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
|
||||||
import { LogInExternalProviderComponent } from '../log-in-external-provider.component';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'ds-log-in-shibboleth',
|
|
||||||
templateUrl: './log-in-shibboleth.component.html',
|
|
||||||
styleUrls: ['./log-in-shibboleth.component.scss'],
|
|
||||||
|
|
||||||
})
|
|
||||||
@renderAuthMethodFor(AuthMethodType.Shibboleth)
|
|
||||||
export class LogInShibbolethComponent extends LogInExternalProviderComponent {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redirect to shibboleth authentication url
|
|
||||||
*/
|
|
||||||
redirectToShibboleth() {
|
|
||||||
this.redirectToExternalProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -6,4 +6,23 @@ export class DSONameServiceMock {
|
|||||||
public getName(dso: DSpaceObject) {
|
public getName(dso: DSpaceObject) {
|
||||||
return UNDEFINED_NAME;
|
return UNDEFINED_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getHitHighlights(object: any, dso: DSpaceObject) {
|
||||||
|
if (object.hitHighlights && object.hitHighlights['dc.title']) {
|
||||||
|
return object.hitHighlights['dc.title'][0].value;
|
||||||
|
} else if (object.hitHighlights && object.hitHighlights['organization.legalName']) {
|
||||||
|
return object.hitHighlights['organization.legalName'][0].value;
|
||||||
|
} else if (object.hitHighlights && (object.hitHighlights['person.familyName'] || object.hitHighlights['person.givenName'])) {
|
||||||
|
if (object.hitHighlights['person.familyName'] && object.hitHighlights['person.givenName']) {
|
||||||
|
return `${object.hitHighlights['person.familyName'][0].value}, ${object.hitHighlights['person.givenName'][0].value}`;
|
||||||
|
}
|
||||||
|
if (object.hitHighlights['person.familyName']) {
|
||||||
|
return `${object.hitHighlights['person.familyName'][0].value}`;
|
||||||
|
}
|
||||||
|
if (object.hitHighlights['person.givenName']) {
|
||||||
|
return `${object.hitHighlights['person.givenName'][0].value}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return UNDEFINED_NAME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
59
src/app/shared/mydspace-actions/mydspace-actions.module.ts
Normal file
59
src/app/shared/mydspace-actions/mydspace-actions.module.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { SharedModule } from '../shared.module';
|
||||||
|
import { ClaimedTaskActionsApproveComponent } from './claimed-task/approve/claimed-task-actions-approve.component';
|
||||||
|
import { ClaimedTaskActionsRejectComponent } from './claimed-task/reject/claimed-task-actions-reject.component';
|
||||||
|
import { ClaimedTaskActionsReturnToPoolComponent } from './claimed-task/return-to-pool/claimed-task-actions-return-to-pool.component';
|
||||||
|
import { ClaimedTaskActionsEditMetadataComponent } from './claimed-task/edit-metadata/claimed-task-actions-edit-metadata.component';
|
||||||
|
import { ClaimedTaskActionsComponent } from './claimed-task/claimed-task-actions.component';
|
||||||
|
import { ClaimedTaskActionsLoaderComponent } from './claimed-task/switcher/claimed-task-actions-loader.component';
|
||||||
|
import { ItemActionsComponent } from './item/item-actions.component';
|
||||||
|
import { PoolTaskActionsComponent } from './pool-task/pool-task-actions.component';
|
||||||
|
import { WorkflowitemActionsComponent } from './workflowitem/workflowitem-actions.component';
|
||||||
|
import { WorkspaceitemActionsComponent } from './workspaceitem/workspaceitem-actions.component';
|
||||||
|
|
||||||
|
const ENTRY_COMPONENTS = [
|
||||||
|
ClaimedTaskActionsApproveComponent,
|
||||||
|
ClaimedTaskActionsRejectComponent,
|
||||||
|
ClaimedTaskActionsReturnToPoolComponent,
|
||||||
|
ClaimedTaskActionsEditMetadataComponent,
|
||||||
|
];
|
||||||
|
|
||||||
|
const DECLARATIONS = [
|
||||||
|
...ENTRY_COMPONENTS,
|
||||||
|
ClaimedTaskActionsComponent,
|
||||||
|
ClaimedTaskActionsLoaderComponent,
|
||||||
|
ItemActionsComponent,
|
||||||
|
PoolTaskActionsComponent,
|
||||||
|
WorkflowitemActionsComponent,
|
||||||
|
WorkspaceitemActionsComponent,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module contains Item actions used in MyDSpace
|
||||||
|
*/
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
SharedModule,
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
...DECLARATIONS,
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
...ENTRY_COMPONENTS,
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
...DECLARATIONS,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class MyDSpaceActionsModule {
|
||||||
|
|
||||||
|
}
|
@@ -55,34 +55,34 @@ describe('MyDSpaceItemStatusComponent', () => {
|
|||||||
component.status = MyDspaceItemStatusType.VALIDATION;
|
component.status = MyDspaceItemStatusType.VALIDATION;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(component.badgeContent).toBe(MyDspaceItemStatusType.VALIDATION);
|
expect(component.badgeContent).toBe(MyDspaceItemStatusType.VALIDATION);
|
||||||
expect(component.badgeClass).toBe('text-light badge badge-warning');
|
expect(component.badgeClass).toBe('text-light badge badge-validation');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should init badge content and class', () => {
|
it('should init badge content and class', () => {
|
||||||
component.status = MyDspaceItemStatusType.WAITING_CONTROLLER;
|
component.status = MyDspaceItemStatusType.WAITING_CONTROLLER;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(component.badgeContent).toBe(MyDspaceItemStatusType.WAITING_CONTROLLER);
|
expect(component.badgeContent).toBe(MyDspaceItemStatusType.WAITING_CONTROLLER);
|
||||||
expect(component.badgeClass).toBe('text-light badge badge-info');
|
expect(component.badgeClass).toBe('text-light badge badge-waiting-controller');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should init badge content and class', () => {
|
it('should init badge content and class', () => {
|
||||||
component.status = MyDspaceItemStatusType.WORKSPACE;
|
component.status = MyDspaceItemStatusType.WORKSPACE;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(component.badgeContent).toBe(MyDspaceItemStatusType.WORKSPACE);
|
expect(component.badgeContent).toBe(MyDspaceItemStatusType.WORKSPACE);
|
||||||
expect(component.badgeClass).toBe('text-light badge badge-primary');
|
expect(component.badgeClass).toBe('text-light badge badge-workspace');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should init badge content and class', () => {
|
it('should init badge content and class', () => {
|
||||||
component.status = MyDspaceItemStatusType.ARCHIVED;
|
component.status = MyDspaceItemStatusType.ARCHIVED;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(component.badgeContent).toBe(MyDspaceItemStatusType.ARCHIVED);
|
expect(component.badgeContent).toBe(MyDspaceItemStatusType.ARCHIVED);
|
||||||
expect(component.badgeClass).toBe('text-light badge badge-success');
|
expect(component.badgeClass).toBe('text-light badge badge-archived');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should init badge content and class', () => {
|
it('should init badge content and class', () => {
|
||||||
component.status = MyDspaceItemStatusType.WORKFLOW;
|
component.status = MyDspaceItemStatusType.WORKFLOW;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(component.badgeContent).toBe(MyDspaceItemStatusType.WORKFLOW);
|
expect(component.badgeContent).toBe(MyDspaceItemStatusType.WORKFLOW);
|
||||||
expect(component.badgeClass).toBe('text-light badge badge-info');
|
expect(component.badgeClass).toBe('text-light badge badge-workflow');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -34,19 +34,19 @@ export class MyDSpaceItemStatusComponent implements OnInit {
|
|||||||
this.badgeClass = 'text-light badge ';
|
this.badgeClass = 'text-light badge ';
|
||||||
switch (this.status) {
|
switch (this.status) {
|
||||||
case MyDspaceItemStatusType.VALIDATION:
|
case MyDspaceItemStatusType.VALIDATION:
|
||||||
this.badgeClass += 'badge-warning';
|
this.badgeClass += 'badge-validation';
|
||||||
break;
|
break;
|
||||||
case MyDspaceItemStatusType.WAITING_CONTROLLER:
|
case MyDspaceItemStatusType.WAITING_CONTROLLER:
|
||||||
this.badgeClass += 'badge-info';
|
this.badgeClass += 'badge-waiting-controller';
|
||||||
break;
|
break;
|
||||||
case MyDspaceItemStatusType.WORKSPACE:
|
case MyDspaceItemStatusType.WORKSPACE:
|
||||||
this.badgeClass += 'badge-primary';
|
this.badgeClass += 'badge-workspace';
|
||||||
break;
|
break;
|
||||||
case MyDspaceItemStatusType.ARCHIVED:
|
case MyDspaceItemStatusType.ARCHIVED:
|
||||||
this.badgeClass += 'badge-success';
|
this.badgeClass += 'badge-archived';
|
||||||
break;
|
break;
|
||||||
case MyDspaceItemStatusType.WORKFLOW:
|
case MyDspaceItemStatusType.WORKFLOW:
|
||||||
this.badgeClass += 'badge-info';
|
this.badgeClass += 'badge-workflow';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,13 +28,19 @@ import { ItemSearchResultGridElementComponent } from './item-search-result-grid-
|
|||||||
|
|
||||||
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
|
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
|
||||||
mockItemWithMetadata.hitHighlights = {};
|
mockItemWithMetadata.hitHighlights = {};
|
||||||
|
const dcTitle = 'This is just another <em>title</em>';
|
||||||
mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
|
mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
|
||||||
|
hitHighlights: {
|
||||||
|
'dc.title': [{
|
||||||
|
value: dcTitle
|
||||||
|
}],
|
||||||
|
},
|
||||||
bundles: createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [])),
|
bundles: createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [])),
|
||||||
metadata: {
|
metadata: {
|
||||||
'dc.title': [
|
'dc.title': [
|
||||||
{
|
{
|
||||||
language: 'en_US',
|
language: 'en_US',
|
||||||
value: 'This is just another title'
|
value: dcTitle
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'dc.contributor.author': [
|
'dc.contributor.author': [
|
||||||
@@ -57,6 +63,114 @@ mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const mockPerson: ItemSearchResult = Object.assign(new ItemSearchResult(), {
|
||||||
|
hitHighlights: {
|
||||||
|
'person.familyName': [{
|
||||||
|
value: '<em>Michel</em>'
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
indexableObject:
|
||||||
|
Object.assign(new Item(), {
|
||||||
|
bundles: createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [])),
|
||||||
|
entityType: 'Person',
|
||||||
|
metadata: {
|
||||||
|
'dc.title': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'This is just another title'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.contributor.author': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'Smith, Donald'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.publisher': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'a publisher'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.date.issued': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: '2015-06-26'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.description.abstract': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'This is the abstract'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dspace.entity.type': [
|
||||||
|
{
|
||||||
|
value: 'Person'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'person.familyName': [
|
||||||
|
{
|
||||||
|
value: 'Michel'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
const mockOrgUnit: ItemSearchResult = Object.assign(new ItemSearchResult(), {
|
||||||
|
hitHighlights: {
|
||||||
|
'organization.legalName': [{
|
||||||
|
value: '<em>Science</em>'
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
indexableObject:
|
||||||
|
Object.assign(new Item(), {
|
||||||
|
bundles: createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [])),
|
||||||
|
entityType: 'OrgUnit',
|
||||||
|
metadata: {
|
||||||
|
'dc.title': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'This is just another title'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.contributor.author': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'Smith, Donald'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.publisher': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'a publisher'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.date.issued': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: '2015-06-26'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.description.abstract': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'This is the abstract'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'organization.legalName': [
|
||||||
|
{
|
||||||
|
value: 'Science'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dspace.entity.type': [
|
||||||
|
{
|
||||||
|
value: 'OrgUnit'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
|
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
|
||||||
mockItemWithoutMetadata.hitHighlights = {};
|
mockItemWithoutMetadata.hitHighlights = {};
|
||||||
@@ -154,6 +268,41 @@ export function getEntityGridElementTestComponent(component, searchResultWithMet
|
|||||||
expect(itemAuthorField).toBeNull();
|
expect(itemAuthorField).toBeNull();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('When the item has title', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
comp.object = mockItemWithMetadata;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
it('should show highlighted title', () => {
|
||||||
|
const titleField = fixture.debugElement.query(By.css('.card-title'));
|
||||||
|
expect(titleField.nativeNode.innerHTML).toEqual(dcTitle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('When the item is Person and has title', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
comp.object = mockPerson;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show highlighted title', () => {
|
||||||
|
const titleField = fixture.debugElement.query(By.css('.card-title'));
|
||||||
|
expect(titleField.nativeNode.innerHTML).toEqual('<em>Michel</em>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('When the item is orgUnit and has title', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
comp.object = mockOrgUnit;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show highlighted title', () => {
|
||||||
|
const titleField = fixture.debugElement.query(By.css('.card-title'));
|
||||||
|
expect(titleField.nativeNode.innerHTML).toEqual('<em>Science</em>');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,6 @@ export class ItemSearchResultGridElementComponent extends SearchResultGridElemen
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
this.itemPageRoute = getItemPageRoute(this.dso);
|
this.itemPageRoute = getItemPageRoute(this.dso);
|
||||||
this.dsoTitle = this.dsoNameService.getName(this.dso);
|
this.dsoTitle = this.dsoNameService.getHitHighlights(this.object, this.dso);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -55,7 +55,7 @@ export class ItemListPreviewComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.showThumbnails = this.appConfig.browseBy.showThumbnails;
|
this.showThumbnails = this.appConfig.browseBy.showThumbnails;
|
||||||
this.dsoTitle = this.dsoNameService.getName(this.item);
|
this.dsoTitle = this.dsoNameService.getHitHighlights(this.object, this.item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -13,8 +13,13 @@ import { APP_CONFIG } from '../../../../../../../config/app-config.interface';
|
|||||||
|
|
||||||
let publicationListElementComponent: ItemSearchResultListElementComponent;
|
let publicationListElementComponent: ItemSearchResultListElementComponent;
|
||||||
let fixture: ComponentFixture<ItemSearchResultListElementComponent>;
|
let fixture: ComponentFixture<ItemSearchResultListElementComponent>;
|
||||||
|
const dcTitle = 'This is just another <em>title</em>';
|
||||||
const mockItemWithMetadata: ItemSearchResult = Object.assign(new ItemSearchResult(), {
|
const mockItemWithMetadata: ItemSearchResult = Object.assign(new ItemSearchResult(), {
|
||||||
|
hitHighlights: {
|
||||||
|
'dc.title': [{
|
||||||
|
value: dcTitle
|
||||||
|
}],
|
||||||
|
},
|
||||||
indexableObject:
|
indexableObject:
|
||||||
Object.assign(new Item(), {
|
Object.assign(new Item(), {
|
||||||
bundles: observableOf({}),
|
bundles: observableOf({}),
|
||||||
@@ -22,7 +27,7 @@ const mockItemWithMetadata: ItemSearchResult = Object.assign(new ItemSearchResul
|
|||||||
'dc.title': [
|
'dc.title': [
|
||||||
{
|
{
|
||||||
language: 'en_US',
|
language: 'en_US',
|
||||||
value: 'This is just another title'
|
value: dcTitle
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'dc.contributor.author': [
|
'dc.contributor.author': [
|
||||||
@@ -59,7 +64,114 @@ const mockItemWithoutMetadata: ItemSearchResult = Object.assign(new ItemSearchRe
|
|||||||
metadata: {}
|
metadata: {}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
const mockPerson: ItemSearchResult = Object.assign(new ItemSearchResult(), {
|
||||||
|
hitHighlights: {
|
||||||
|
'person.familyName': [{
|
||||||
|
value: '<em>Michel</em>'
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
indexableObject:
|
||||||
|
Object.assign(new Item(), {
|
||||||
|
bundles: observableOf({}),
|
||||||
|
entityType: 'Person',
|
||||||
|
metadata: {
|
||||||
|
'dc.title': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'This is just another title'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.contributor.author': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'Smith, Donald'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.publisher': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'a publisher'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.date.issued': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: '2015-06-26'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.description.abstract': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'This is the abstract'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'person.familyName': [
|
||||||
|
{
|
||||||
|
value: 'Michel'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dspace.entity.type': [
|
||||||
|
{
|
||||||
|
value: 'Person'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
const mockOrgUnit: ItemSearchResult = Object.assign(new ItemSearchResult(), {
|
||||||
|
hitHighlights: {
|
||||||
|
'organization.legalName': [{
|
||||||
|
value: '<em>Science</em>'
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
indexableObject:
|
||||||
|
Object.assign(new Item(), {
|
||||||
|
bundles: observableOf({}),
|
||||||
|
entityType: 'OrgUnit',
|
||||||
|
metadata: {
|
||||||
|
'dc.title': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'This is just another title'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.contributor.author': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'Smith, Donald'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.publisher': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'a publisher'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.date.issued': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: '2015-06-26'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dc.description.abstract': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'This is the abstract'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'organization.legalName': [
|
||||||
|
{
|
||||||
|
value: 'Science'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dspace.entity.type': [
|
||||||
|
{
|
||||||
|
value: 'OrgUnit'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
const environmentUseThumbs = {
|
const environmentUseThumbs = {
|
||||||
browseBy: {
|
browseBy: {
|
||||||
showThumbnails: true
|
showThumbnails: true
|
||||||
@@ -205,6 +317,42 @@ describe('ItemSearchResultListElementComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('When the item has title', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
publicationListElementComponent.object = mockItemWithMetadata;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show highlighted title', () => {
|
||||||
|
const titleField = fixture.debugElement.query(By.css('.item-list-title'));
|
||||||
|
expect(titleField.nativeNode.innerHTML).toEqual(dcTitle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('When the item is Person and has title', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
publicationListElementComponent.object = mockPerson;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show highlighted title', () => {
|
||||||
|
const titleField = fixture.debugElement.query(By.css('.item-list-title'));
|
||||||
|
expect(titleField.nativeNode.innerHTML).toEqual('<em>Michel</em>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('When the item is orgUnit and has title', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
publicationListElementComponent.object = mockOrgUnit;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show highlighted title', () => {
|
||||||
|
const titleField = fixture.debugElement.query(By.css('.item-list-title'));
|
||||||
|
expect(titleField.nativeNode.innerHTML).toEqual('<em>Science</em>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('When the item has no title', () => {
|
describe('When the item has no title', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
publicationListElementComponent.object = mockItemWithoutMetadata;
|
publicationListElementComponent.object = mockItemWithoutMetadata;
|
||||||
|
@@ -33,7 +33,7 @@ export class SearchResultListElementComponent<T extends SearchResult<K>, K exten
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (hasValue(this.object)) {
|
if (hasValue(this.object)) {
|
||||||
this.dso = this.object.indexableObject;
|
this.dso = this.object.indexableObject;
|
||||||
this.dsoTitle = this.dsoNameService.getName(this.dso);
|
this.dsoTitle = this.dsoNameService.getHitHighlights(this.object, this.dso);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,6 +31,7 @@ import { SearchComponent } from './search.component';
|
|||||||
import { ThemedSearchComponent } from './themed-search.component';
|
import { ThemedSearchComponent } from './themed-search.component';
|
||||||
import { ThemedSearchResultsComponent } from './search-results/themed-search-results.component';
|
import { ThemedSearchResultsComponent } from './search-results/themed-search-results.component';
|
||||||
import { ThemedSearchSettingsComponent } from './search-settings/themed-search-settings.component';
|
import { ThemedSearchSettingsComponent } from './search-settings/themed-search-settings.component';
|
||||||
|
import { NouisliderModule } from 'ng2-nouislider';
|
||||||
|
|
||||||
const COMPONENTS = [
|
const COMPONENTS = [
|
||||||
SearchComponent,
|
SearchComponent,
|
||||||
@@ -91,7 +92,8 @@ export const MODELS = [
|
|||||||
missingTranslationHandler: { provide: MissingTranslationHandler, useClass: MissingTranslationHelper },
|
missingTranslationHandler: { provide: MissingTranslationHandler, useClass: MissingTranslationHelper },
|
||||||
useDefaultLang: true
|
useDefaultLang: true
|
||||||
}),
|
}),
|
||||||
SharedModule.withEntryComponents()
|
SharedModule.withEntryComponents(),
|
||||||
|
NouisliderModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
...COMPONENTS
|
...COMPONENTS
|
||||||
|
@@ -2,21 +2,15 @@ import { NgModule } from '@angular/core';
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { CdkTreeModule } from '@angular/cdk/tree';
|
|
||||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||||
|
|
||||||
import { NouisliderModule } from 'ng2-nouislider';
|
|
||||||
import {
|
import {
|
||||||
NgbDatepickerModule,
|
|
||||||
NgbDropdownModule,
|
NgbDropdownModule,
|
||||||
NgbNavModule,
|
NgbNavModule,
|
||||||
NgbPaginationModule,
|
NgbPaginationModule,
|
||||||
NgbTimepickerModule,
|
|
||||||
NgbTooltipModule,
|
NgbTooltipModule,
|
||||||
NgbTypeaheadModule,
|
NgbTypeaheadModule,
|
||||||
} from '@ng-bootstrap/ng-bootstrap';
|
} from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { MissingTranslationHandler, TranslateModule } from '@ngx-translate/core';
|
import { MissingTranslationHandler, TranslateModule } from '@ngx-translate/core';
|
||||||
import { NgxPaginationModule } from 'ngx-pagination';
|
|
||||||
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
||||||
import { ConfirmationModalComponent } from './confirmation-modal/confirmation-modal.component';
|
import { ConfirmationModalComponent } from './confirmation-modal/confirmation-modal.component';
|
||||||
import {
|
import {
|
||||||
@@ -75,25 +69,7 @@ import { AlertComponent } from './alert/alert.component';
|
|||||||
import {
|
import {
|
||||||
SearchResultDetailElementComponent
|
SearchResultDetailElementComponent
|
||||||
} from './object-detail/my-dspace-result-detail-element/search-result-detail-element.component';
|
} from './object-detail/my-dspace-result-detail-element/search-result-detail-element.component';
|
||||||
import { ClaimedTaskActionsComponent } from './mydspace-actions/claimed-task/claimed-task-actions.component';
|
|
||||||
import { PoolTaskActionsComponent } from './mydspace-actions/pool-task/pool-task-actions.component';
|
|
||||||
import { ObjectDetailComponent } from './object-detail/object-detail.component';
|
import { ObjectDetailComponent } from './object-detail/object-detail.component';
|
||||||
import {
|
|
||||||
ItemDetailPreviewComponent
|
|
||||||
} from './object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component';
|
|
||||||
import {
|
|
||||||
MyDSpaceItemStatusComponent
|
|
||||||
} from './object-collection/shared/mydspace-item-status/my-dspace-item-status.component';
|
|
||||||
import { WorkspaceitemActionsComponent } from './mydspace-actions/workspaceitem/workspaceitem-actions.component';
|
|
||||||
import { WorkflowitemActionsComponent } from './mydspace-actions/workflowitem/workflowitem-actions.component';
|
|
||||||
import { ItemSubmitterComponent } from './object-collection/shared/mydspace-item-submitter/item-submitter.component';
|
|
||||||
import { ItemActionsComponent } from './mydspace-actions/item/item-actions.component';
|
|
||||||
import {
|
|
||||||
ClaimedTaskActionsApproveComponent
|
|
||||||
} from './mydspace-actions/claimed-task/approve/claimed-task-actions-approve.component';
|
|
||||||
import {
|
|
||||||
ClaimedTaskActionsRejectComponent
|
|
||||||
} from './mydspace-actions/claimed-task/reject/claimed-task-actions-reject.component';
|
|
||||||
import { ObjNgFor } from './utils/object-ngfor.pipe';
|
import { ObjNgFor } from './utils/object-ngfor.pipe';
|
||||||
import { BrowseByComponent } from './browse-by/browse-by.component';
|
import { BrowseByComponent } from './browse-by/browse-by.component';
|
||||||
import {
|
import {
|
||||||
@@ -163,21 +139,8 @@ import {
|
|||||||
import {
|
import {
|
||||||
ThemedEditCollectionSelectorComponent
|
ThemedEditCollectionSelectorComponent
|
||||||
} from './dso-selector/modal-wrappers/edit-collection-selector/themed-edit-collection-selector.component';
|
} from './dso-selector/modal-wrappers/edit-collection-selector/themed-edit-collection-selector.component';
|
||||||
import {
|
|
||||||
ItemListPreviewComponent
|
|
||||||
} from './object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component';
|
|
||||||
import {
|
|
||||||
MetadataFieldWrapperComponent
|
|
||||||
} from '../item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component';
|
|
||||||
import { MetadataValuesComponent } from '../item-page/field-components/metadata-values/metadata-values.component';
|
|
||||||
import { RoleDirective } from './roles/role.directive';
|
import { RoleDirective } from './roles/role.directive';
|
||||||
import { UserMenuComponent } from './auth-nav-menu/user-menu/user-menu.component';
|
import { UserMenuComponent } from './auth-nav-menu/user-menu/user-menu.component';
|
||||||
import {
|
|
||||||
ClaimedTaskActionsReturnToPoolComponent
|
|
||||||
} from './mydspace-actions/claimed-task/return-to-pool/claimed-task-actions-return-to-pool.component';
|
|
||||||
import {
|
|
||||||
ItemDetailPreviewFieldComponent
|
|
||||||
} from './object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview-field/item-detail-preview-field.component';
|
|
||||||
import {
|
import {
|
||||||
CollectionSearchResultGridElementComponent
|
CollectionSearchResultGridElementComponent
|
||||||
} from './object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component';
|
} from './object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component';
|
||||||
@@ -216,35 +179,22 @@ import {
|
|||||||
} from './object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component';
|
} from './object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component';
|
||||||
import { PageWithSidebarComponent } from './sidebar/page-with-sidebar.component';
|
import { PageWithSidebarComponent } from './sidebar/page-with-sidebar.component';
|
||||||
import { SidebarDropdownComponent } from './sidebar/sidebar-dropdown.component';
|
import { SidebarDropdownComponent } from './sidebar/sidebar-dropdown.component';
|
||||||
import { SidebarFilterComponent } from './sidebar/filter/sidebar-filter.component';
|
|
||||||
import { SidebarFilterSelectedOptionComponent } from './sidebar/filter/sidebar-filter-selected-option.component';
|
|
||||||
import {
|
import {
|
||||||
SelectableListItemControlComponent
|
SelectableListItemControlComponent
|
||||||
} from './object-collection/shared/selectable-list-item-control/selectable-list-item-control.component';
|
} from './object-collection/shared/selectable-list-item-control/selectable-list-item-control.component';
|
||||||
import {
|
import {
|
||||||
ImportableListItemControlComponent
|
ImportableListItemControlComponent
|
||||||
} from './object-collection/shared/importable-list-item-control/importable-list-item-control.component';
|
} from './object-collection/shared/importable-list-item-control/importable-list-item-control.component';
|
||||||
import { ItemVersionsComponent } from './item/item-versions/item-versions.component';
|
|
||||||
import { LogInContainerComponent } from './log-in/container/log-in-container.component';
|
import { LogInContainerComponent } from './log-in/container/log-in-container.component';
|
||||||
import { LogInShibbolethComponent } from './log-in/methods/shibboleth/log-in-shibboleth.component';
|
|
||||||
import { LogInPasswordComponent } from './log-in/methods/password/log-in-password.component';
|
import { LogInPasswordComponent } from './log-in/methods/password/log-in-password.component';
|
||||||
import { LogInComponent } from './log-in/log-in.component';
|
import { LogInComponent } from './log-in/log-in.component';
|
||||||
import { BundleListElementComponent } from './object-list/bundle-list-element/bundle-list-element.component';
|
|
||||||
import { MissingTranslationHelper } from './translate/missing-translation.helper';
|
import { MissingTranslationHelper } from './translate/missing-translation.helper';
|
||||||
import { ItemVersionsNoticeComponent } from './item/item-versions/notice/item-versions-notice.component';
|
|
||||||
import { FileValidator } from './utils/require-file.validator';
|
import { FileValidator } from './utils/require-file.validator';
|
||||||
import { FileValueAccessorDirective } from './utils/file-value-accessor.directive';
|
import { FileValueAccessorDirective } from './utils/file-value-accessor.directive';
|
||||||
import { FileSectionComponent } from '../item-page/simple/field-components/file-section/file-section.component';
|
|
||||||
import {
|
import {
|
||||||
ModifyItemOverviewComponent
|
ModifyItemOverviewComponent
|
||||||
} from '../item-page/edit-item-page/modify-item-overview/modify-item-overview.component';
|
} from '../item-page/edit-item-page/modify-item-overview/modify-item-overview.component';
|
||||||
import {
|
|
||||||
ClaimedTaskActionsLoaderComponent
|
|
||||||
} from './mydspace-actions/claimed-task/switcher/claimed-task-actions-loader.component';
|
|
||||||
import { ClaimedTaskActionsDirective } from './mydspace-actions/claimed-task/switcher/claimed-task-actions.directive';
|
import { ClaimedTaskActionsDirective } from './mydspace-actions/claimed-task/switcher/claimed-task-actions.directive';
|
||||||
import {
|
|
||||||
ClaimedTaskActionsEditMetadataComponent
|
|
||||||
} from './mydspace-actions/claimed-task/edit-metadata/claimed-task-actions-edit-metadata.component';
|
|
||||||
import { ImpersonateNavbarComponent } from './impersonate-navbar/impersonate-navbar.component';
|
import { ImpersonateNavbarComponent } from './impersonate-navbar/impersonate-navbar.component';
|
||||||
import { NgForTrackByIdDirective } from './ng-for-track-by-id.directive';
|
import { NgForTrackByIdDirective } from './ng-for-track-by-id.directive';
|
||||||
import { FileDownloadLinkComponent } from './file-download-link/file-download-link.component';
|
import { FileDownloadLinkComponent } from './file-download-link/file-download-link.component';
|
||||||
@@ -267,44 +217,20 @@ import {
|
|||||||
AuthorizedCollectionSelectorComponent
|
AuthorizedCollectionSelectorComponent
|
||||||
} from './dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component';
|
} from './dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component';
|
||||||
import { DsoPageEditButtonComponent } from './dso-page/dso-page-edit-button/dso-page-edit-button.component';
|
import { DsoPageEditButtonComponent } from './dso-page/dso-page-edit-button/dso-page-edit-button.component';
|
||||||
import { DsoPageVersionButtonComponent } from './dso-page/dso-page-version-button/dso-page-version-button.component';
|
|
||||||
import { HoverClassDirective } from './hover-class.directive';
|
import { HoverClassDirective } from './hover-class.directive';
|
||||||
import {
|
import {
|
||||||
ValidationSuggestionsComponent
|
ValidationSuggestionsComponent
|
||||||
} from './input-suggestions/validation-suggestions/validation-suggestions.component';
|
} from './input-suggestions/validation-suggestions/validation-suggestions.component';
|
||||||
import { ItemAlertsComponent } from './item/item-alerts/item-alerts.component';
|
|
||||||
import {
|
import {
|
||||||
ItemSearchResultGridElementComponent
|
ItemSearchResultGridElementComponent
|
||||||
} from './object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component';
|
} from './object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component';
|
||||||
import { BitstreamDownloadPageComponent } from './bitstream-download-page/bitstream-download-page.component';
|
|
||||||
import {
|
|
||||||
GenericItemPageFieldComponent
|
|
||||||
} from '../item-page/simple/field-components/specific-field/generic/generic-item-page-field.component';
|
|
||||||
import {
|
|
||||||
MetadataRepresentationListComponent
|
|
||||||
} from '../item-page/simple/metadata-representation-list/metadata-representation-list.component';
|
|
||||||
import { RelatedItemsComponent } from '../item-page/simple/related-items/related-items-component';
|
|
||||||
import { SearchNavbarComponent } from '../search-navbar/search-navbar.component';
|
import { SearchNavbarComponent } from '../search-navbar/search-navbar.component';
|
||||||
import { ThemedSearchNavbarComponent } from '../search-navbar/themed-search-navbar.component';
|
import { ThemedSearchNavbarComponent } from '../search-navbar/themed-search-navbar.component';
|
||||||
import {
|
|
||||||
ItemVersionsSummaryModalComponent
|
|
||||||
} from './item/item-versions/item-versions-summary-modal/item-versions-summary-modal.component';
|
|
||||||
import {
|
|
||||||
ItemVersionsDeleteModalComponent
|
|
||||||
} from './item/item-versions/item-versions-delete-modal/item-versions-delete-modal.component';
|
|
||||||
import { ScopeSelectorModalComponent } from './search-form/scope-selector-modal/scope-selector-modal.component';
|
import { ScopeSelectorModalComponent } from './search-form/scope-selector-modal/scope-selector-modal.component';
|
||||||
import {
|
|
||||||
BitstreamRequestACopyPageComponent
|
|
||||||
} from './bitstream-request-a-copy-page/bitstream-request-a-copy-page.component';
|
|
||||||
import { DsSelectComponent } from './ds-select/ds-select.component';
|
import { DsSelectComponent } from './ds-select/ds-select.component';
|
||||||
import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component';
|
|
||||||
import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component';
|
|
||||||
import { RSSComponent } from './rss-feed/rss.component';
|
import { RSSComponent } from './rss-feed/rss.component';
|
||||||
import { DsoPageOrcidButtonComponent } from './dso-page/dso-page-orcid-button/dso-page-orcid-button.component';
|
|
||||||
import { LogInOrcidComponent } from './log-in/methods/orcid/log-in-orcid.component';
|
|
||||||
import { BrowserOnlyPipe } from './utils/browser-only.pipe';
|
import { BrowserOnlyPipe } from './utils/browser-only.pipe';
|
||||||
import { ThemedLoadingComponent } from './loading/themed-loading.component';
|
import { ThemedLoadingComponent } from './loading/themed-loading.component';
|
||||||
import { PersonPageClaimButtonComponent } from './dso-page/person-page-claim-button/person-page-claim-button.component';
|
|
||||||
import { SearchExportCsvComponent } from './search/search-export-csv/search-export-csv.component';
|
import { SearchExportCsvComponent } from './search/search-export-csv/search-export-csv.component';
|
||||||
import {
|
import {
|
||||||
ItemPageTitleFieldComponent
|
ItemPageTitleFieldComponent
|
||||||
@@ -316,24 +242,22 @@ import {
|
|||||||
ListableNotificationObjectComponent
|
ListableNotificationObjectComponent
|
||||||
} from './object-list/listable-notification-object/listable-notification-object.component';
|
} from './object-list/listable-notification-object/listable-notification-object.component';
|
||||||
import { ThemedCollectionDropdownComponent } from './collection-dropdown/themed-collection-dropdown.component';
|
import { ThemedCollectionDropdownComponent } from './collection-dropdown/themed-collection-dropdown.component';
|
||||||
|
import { MetadataFieldWrapperComponent } from './metadata-field-wrapper/metadata-field-wrapper.component';
|
||||||
|
import { LogInExternalProviderComponent } from './log-in/methods/log-in-external-provider/log-in-external-provider.component';
|
||||||
|
|
||||||
|
|
||||||
const MODULES = [
|
const MODULES = [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
InfiniteScrollModule,
|
InfiniteScrollModule,
|
||||||
NgbNavModule,
|
NgbNavModule,
|
||||||
NgbDatepickerModule,
|
|
||||||
NgbTimepickerModule,
|
|
||||||
NgbTypeaheadModule,
|
NgbTypeaheadModule,
|
||||||
NgxPaginationModule,
|
|
||||||
NgbPaginationModule,
|
NgbPaginationModule,
|
||||||
NgbDropdownModule,
|
NgbDropdownModule,
|
||||||
NgbTooltipModule,
|
NgbTooltipModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
NouisliderModule,
|
|
||||||
DragDropModule,
|
DragDropModule,
|
||||||
CdkTreeModule,
|
|
||||||
GoogleRecaptchaModule,
|
GoogleRecaptchaModule,
|
||||||
MenuModule,
|
MenuModule,
|
||||||
];
|
];
|
||||||
@@ -369,7 +293,6 @@ const COMPONENTS = [
|
|||||||
UserMenuComponent,
|
UserMenuComponent,
|
||||||
DsSelectComponent,
|
DsSelectComponent,
|
||||||
ErrorComponent,
|
ErrorComponent,
|
||||||
FileSectionComponent,
|
|
||||||
LangSwitchComponent,
|
LangSwitchComponent,
|
||||||
LoadingComponent,
|
LoadingComponent,
|
||||||
ThemedLoadingComponent,
|
ThemedLoadingComponent,
|
||||||
@@ -386,21 +309,7 @@ const COMPONENTS = [
|
|||||||
SearchFormComponent,
|
SearchFormComponent,
|
||||||
PageWithSidebarComponent,
|
PageWithSidebarComponent,
|
||||||
SidebarDropdownComponent,
|
SidebarDropdownComponent,
|
||||||
SidebarFilterComponent,
|
|
||||||
SidebarFilterSelectedOptionComponent,
|
|
||||||
ThumbnailComponent,
|
ThumbnailComponent,
|
||||||
ItemListPreviewComponent,
|
|
||||||
ThemedItemListPreviewComponent,
|
|
||||||
MyDSpaceItemStatusComponent,
|
|
||||||
ItemSubmitterComponent,
|
|
||||||
ItemDetailPreviewComponent,
|
|
||||||
ItemDetailPreviewFieldComponent,
|
|
||||||
ClaimedTaskActionsComponent,
|
|
||||||
ClaimedTaskActionsLoaderComponent,
|
|
||||||
ItemActionsComponent,
|
|
||||||
PoolTaskActionsComponent,
|
|
||||||
WorkflowitemActionsComponent,
|
|
||||||
WorkspaceitemActionsComponent,
|
|
||||||
ViewModeSwitchComponent,
|
ViewModeSwitchComponent,
|
||||||
TruncatableComponent,
|
TruncatableComponent,
|
||||||
TruncatablePartComponent,
|
TruncatablePartComponent,
|
||||||
@@ -423,8 +332,6 @@ const COMPONENTS = [
|
|||||||
SelectableListItemControlComponent,
|
SelectableListItemControlComponent,
|
||||||
ImportableListItemControlComponent,
|
ImportableListItemControlComponent,
|
||||||
LogInContainerComponent,
|
LogInContainerComponent,
|
||||||
ItemVersionsComponent,
|
|
||||||
ItemVersionsNoticeComponent,
|
|
||||||
ModifyItemOverviewComponent,
|
ModifyItemOverviewComponent,
|
||||||
ImpersonateNavbarComponent,
|
ImpersonateNavbarComponent,
|
||||||
EntityDropdownComponent,
|
EntityDropdownComponent,
|
||||||
@@ -437,6 +344,8 @@ const COMPONENTS = [
|
|||||||
ItemPageTitleFieldComponent,
|
ItemPageTitleFieldComponent,
|
||||||
ThemedSearchNavbarComponent,
|
ThemedSearchNavbarComponent,
|
||||||
ListableNotificationObjectComponent,
|
ListableNotificationObjectComponent,
|
||||||
|
DsoPageEditButtonComponent,
|
||||||
|
MetadataFieldWrapperComponent,
|
||||||
];
|
];
|
||||||
|
|
||||||
const ENTRY_COMPONENTS = [
|
const ENTRY_COMPONENTS = [
|
||||||
@@ -476,19 +385,10 @@ const ENTRY_COMPONENTS = [
|
|||||||
MetadataRepresentationListElementComponent,
|
MetadataRepresentationListElementComponent,
|
||||||
ItemMetadataRepresentationListElementComponent,
|
ItemMetadataRepresentationListElementComponent,
|
||||||
LogInPasswordComponent,
|
LogInPasswordComponent,
|
||||||
LogInShibbolethComponent,
|
LogInExternalProviderComponent,
|
||||||
LogInOidcComponent,
|
|
||||||
LogInOrcidComponent,
|
|
||||||
BundleListElementComponent,
|
|
||||||
ClaimedTaskActionsApproveComponent,
|
|
||||||
ClaimedTaskActionsRejectComponent,
|
|
||||||
ClaimedTaskActionsReturnToPoolComponent,
|
|
||||||
ClaimedTaskActionsEditMetadataComponent,
|
|
||||||
CollectionDropdownComponent,
|
CollectionDropdownComponent,
|
||||||
ThemedCollectionDropdownComponent,
|
ThemedCollectionDropdownComponent,
|
||||||
FileDownloadLinkComponent,
|
FileDownloadLinkComponent,
|
||||||
BitstreamDownloadPageComponent,
|
|
||||||
BitstreamRequestACopyPageComponent,
|
|
||||||
CurationFormComponent,
|
CurationFormComponent,
|
||||||
ExportMetadataSelectorComponent,
|
ExportMetadataSelectorComponent,
|
||||||
ImportBatchSelectorComponent,
|
ImportBatchSelectorComponent,
|
||||||
@@ -502,20 +402,6 @@ const ENTRY_COMPONENTS = [
|
|||||||
ListableNotificationObjectComponent,
|
ListableNotificationObjectComponent,
|
||||||
];
|
];
|
||||||
|
|
||||||
const SHARED_ITEM_PAGE_COMPONENTS = [
|
|
||||||
MetadataFieldWrapperComponent,
|
|
||||||
MetadataValuesComponent,
|
|
||||||
DsoPageEditButtonComponent,
|
|
||||||
DsoPageVersionButtonComponent,
|
|
||||||
PersonPageClaimButtonComponent,
|
|
||||||
ItemAlertsComponent,
|
|
||||||
GenericItemPageFieldComponent,
|
|
||||||
MetadataRepresentationListComponent,
|
|
||||||
RelatedItemsComponent,
|
|
||||||
DsoPageOrcidButtonComponent
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
const PROVIDERS = [
|
const PROVIDERS = [
|
||||||
TruncatableService,
|
TruncatableService,
|
||||||
MockAdminGuard,
|
MockAdminGuard,
|
||||||
@@ -551,9 +437,6 @@ const DIRECTIVES = [
|
|||||||
...COMPONENTS,
|
...COMPONENTS,
|
||||||
...ENTRY_COMPONENTS,
|
...ENTRY_COMPONENTS,
|
||||||
...DIRECTIVES,
|
...DIRECTIVES,
|
||||||
...SHARED_ITEM_PAGE_COMPONENTS,
|
|
||||||
ItemVersionsSummaryModalComponent,
|
|
||||||
ItemVersionsDeleteModalComponent,
|
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
...PROVIDERS
|
...PROVIDERS
|
||||||
@@ -563,7 +446,6 @@ const DIRECTIVES = [
|
|||||||
...PIPES,
|
...PIPES,
|
||||||
...COMPONENTS,
|
...COMPONENTS,
|
||||||
...ENTRY_COMPONENTS,
|
...ENTRY_COMPONENTS,
|
||||||
...SHARED_ITEM_PAGE_COMPONENTS,
|
|
||||||
...DIRECTIVES,
|
...DIRECTIVES,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
]
|
]
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
<a class="d-flex flex-row" (click)="click.emit($event)">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" [checked]="true" class="my-1 align-self-stretch"/>
|
|
||||||
<span class="filter-value pl-1 text-capitalize">{{label}}</span>
|
|
||||||
</label>
|
|
||||||
</a>
|
|
@@ -1,11 +0,0 @@
|
|||||||
a {
|
|
||||||
color: var(--bs-body-color);
|
|
||||||
|
|
||||||
&:hover, &focus {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.badge {
|
|
||||||
vertical-align: text-top;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'ds-sidebar-filter-selected-option',
|
|
||||||
styleUrls: ['./sidebar-filter-selected-option.component.scss'],
|
|
||||||
templateUrl: './sidebar-filter-selected-option.component.html',
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a single selected option in a sidebar filter
|
|
||||||
*/
|
|
||||||
export class SidebarFilterSelectedOptionComponent {
|
|
||||||
@Input() label: string;
|
|
||||||
@Output() click: EventEmitter<any> = new EventEmitter<any>();
|
|
||||||
}
|
|
@@ -1,73 +0,0 @@
|
|||||||
/* eslint-disable max-classes-per-file */
|
|
||||||
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 SidebarFilterActionTypes = {
|
|
||||||
INITIALIZE: type('dspace/sidebar-filter/INITIALIZE'),
|
|
||||||
COLLAPSE: type('dspace/sidebar-filter/COLLAPSE'),
|
|
||||||
EXPAND: type('dspace/sidebar-filter/EXPAND'),
|
|
||||||
TOGGLE: type('dspace/sidebar-filter/TOGGLE'),
|
|
||||||
};
|
|
||||||
|
|
||||||
export class SidebarFilterAction implements Action {
|
|
||||||
/**
|
|
||||||
* Name of the filter the action is performed on, used to identify the filter
|
|
||||||
*/
|
|
||||||
filterName: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type of action that will be performed
|
|
||||||
*/
|
|
||||||
type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize with the filter's name
|
|
||||||
* @param {string} name of the filter
|
|
||||||
*/
|
|
||||||
constructor(name: string) {
|
|
||||||
this.filterName = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to initialize a filter
|
|
||||||
*/
|
|
||||||
export class FilterInitializeAction extends SidebarFilterAction {
|
|
||||||
type = SidebarFilterActionTypes.INITIALIZE;
|
|
||||||
initiallyExpanded;
|
|
||||||
|
|
||||||
constructor(name: string, initiallyExpanded: boolean) {
|
|
||||||
super(name);
|
|
||||||
this.initiallyExpanded = initiallyExpanded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to collapse a filter
|
|
||||||
*/
|
|
||||||
export class FilterCollapseAction extends SidebarFilterAction {
|
|
||||||
type = SidebarFilterActionTypes.COLLAPSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to expand a filter
|
|
||||||
*/
|
|
||||||
export class FilterExpandAction extends SidebarFilterAction {
|
|
||||||
type = SidebarFilterActionTypes.EXPAND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to collapse a filter when it's expanded and expand it when it's collapsed
|
|
||||||
*/
|
|
||||||
export class FilterToggleAction extends SidebarFilterAction {
|
|
||||||
type = SidebarFilterActionTypes.TOGGLE;
|
|
||||||
}
|
|
@@ -1,26 +0,0 @@
|
|||||||
<div class="facet-filter d-block mb-3 p-3">
|
|
||||||
<div (click)="toggle()" class="filter-name" [attr.data-test]="'filter-toggle' | dsBrowserOnly">
|
|
||||||
<h5 class="d-inline-block mb-0">
|
|
||||||
{{ label | translate }}
|
|
||||||
</h5>
|
|
||||||
<span class="filter-toggle fas float-right"
|
|
||||||
[ngClass]="(collapsed$ | async) ? 'fa-plus' : 'fa-minus'">
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div [@slide]="(collapsed$ | async) ? 'collapsed' : 'expanded'"
|
|
||||||
(@slide.start)="startSlide($event)" (@slide.done)="finishSlide($event)"
|
|
||||||
class="sidebar-filter-wrapper" [ngClass]="{'closed' : closed}">
|
|
||||||
<div>
|
|
||||||
<div class="filters py-2">
|
|
||||||
<ng-template *ngIf="!singleValue">
|
|
||||||
<ds-sidebar-filter-selected-option
|
|
||||||
*ngFor="let value of (selectedValues | async)"
|
|
||||||
[label]="value"
|
|
||||||
(click)="removeValue.emit(value)">
|
|
||||||
</ds-sidebar-filter-selected-option>
|
|
||||||
</ng-template>
|
|
||||||
</div>
|
|
||||||
<ng-content></ng-content>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@@ -1,12 +0,0 @@
|
|||||||
:host .facet-filter {
|
|
||||||
border: 1px solid var(--bs-light);
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
.sidebar-filter-wrapper.closed {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-toggle {
|
|
||||||
line-height: var(--bs-line-height-base);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,89 +0,0 @@
|
|||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { SidebarFilterService } from './sidebar-filter.service';
|
|
||||||
import { slide } from '../../animations/slide';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'ds-sidebar-filter',
|
|
||||||
styleUrls: ['./sidebar-filter.component.scss'],
|
|
||||||
templateUrl: './sidebar-filter.component.html',
|
|
||||||
animations: [slide],
|
|
||||||
})
|
|
||||||
/**
|
|
||||||
* This components renders a sidebar filter including the label and the selected values.
|
|
||||||
* The filter input itself should still be provided in the content.
|
|
||||||
*/
|
|
||||||
export class SidebarFilterComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() name: string;
|
|
||||||
@Input() type: string;
|
|
||||||
@Input() label: string;
|
|
||||||
@Input() expanded = true;
|
|
||||||
@Input() singleValue = false;
|
|
||||||
@Input() selectedValues: Observable<string[]>;
|
|
||||||
@Output() removeValue: EventEmitter<any> = new EventEmitter<any>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True when the filter is 100% collapsed in the UI
|
|
||||||
*/
|
|
||||||
closed = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emits true when the filter is currently collapsed in the store
|
|
||||||
*/
|
|
||||||
collapsed$: Observable<boolean>;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
protected filterService: SidebarFilterService,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes the state for this filter to collapsed when it's expanded and to expanded it when it's collapsed
|
|
||||||
*/
|
|
||||||
toggle() {
|
|
||||||
this.filterService.toggle(this.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to change this.collapsed to false when the slide animation ends and is sliding open
|
|
||||||
* @param event The animation event
|
|
||||||
*/
|
|
||||||
finishSlide(event: any): void {
|
|
||||||
if (event.fromState === 'collapsed') {
|
|
||||||
this.closed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to change this.collapsed to true when the slide animation starts and is sliding closed
|
|
||||||
* @param event The animation event
|
|
||||||
*/
|
|
||||||
startSlide(event: any): void {
|
|
||||||
if (event.toState === 'collapsed') {
|
|
||||||
this.closed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.closed = !this.expanded;
|
|
||||||
this.initializeFilter();
|
|
||||||
this.collapsed$ = this.isCollapsed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the initial state of the filter
|
|
||||||
*/
|
|
||||||
initializeFilter() {
|
|
||||||
this.filterService.initializeFilter(this.name, this.expanded);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the filter is currently collapsed
|
|
||||||
* @returns {Observable<boolean>} Emits true when the current state of the filter is collapsed, false when it's expanded
|
|
||||||
*/
|
|
||||||
private isCollapsed(): Observable<boolean> {
|
|
||||||
return this.filterService.isCollapsed(this.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,70 +0,0 @@
|
|||||||
import {
|
|
||||||
FilterInitializeAction,
|
|
||||||
SidebarFilterAction,
|
|
||||||
SidebarFilterActionTypes
|
|
||||||
} from './sidebar-filter.actions';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface that represents the state for a single filters
|
|
||||||
*/
|
|
||||||
export interface SidebarFilterState {
|
|
||||||
filterCollapsed: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface that represents the state for all available filters
|
|
||||||
*/
|
|
||||||
export interface SidebarFiltersState {
|
|
||||||
[name: string]: SidebarFilterState;
|
|
||||||
}
|
|
||||||
|
|
||||||
const initialState: SidebarFiltersState = Object.create(null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs a filter action on the current state
|
|
||||||
* @param {SidebarFiltersState} state The state before the action is performed
|
|
||||||
* @param {SidebarFilterAction} action The action that should be performed
|
|
||||||
* @returns {SidebarFiltersState} The state after the action is performed
|
|
||||||
*/
|
|
||||||
export function sidebarFilterReducer(state = initialState, action: SidebarFilterAction): SidebarFiltersState {
|
|
||||||
|
|
||||||
switch (action.type) {
|
|
||||||
|
|
||||||
case SidebarFilterActionTypes.INITIALIZE: {
|
|
||||||
const initAction = (action as FilterInitializeAction);
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
[action.filterName]: {
|
|
||||||
filterCollapsed: !initAction.initiallyExpanded,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case SidebarFilterActionTypes.COLLAPSE: {
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
[action.filterName]: {
|
|
||||||
filterCollapsed: true,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case SidebarFilterActionTypes.EXPAND: {
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
[action.filterName]: {
|
|
||||||
filterCollapsed: false,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case SidebarFilterActionTypes.TOGGLE: {
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
[action.filterName]: {
|
|
||||||
filterCollapsed: !state[action.filterName].filterCollapsed,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,107 +0,0 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
import { Store, StoreModule } from '@ngrx/store';
|
|
||||||
import { provideMockStore } from '@ngrx/store/testing';
|
|
||||||
import { cold } from 'jasmine-marbles';
|
|
||||||
|
|
||||||
import { sidebarFilterReducer } from './sidebar-filter.reducer';
|
|
||||||
import { SidebarFilterService } from './sidebar-filter.service';
|
|
||||||
import {
|
|
||||||
FilterCollapseAction,
|
|
||||||
FilterExpandAction,
|
|
||||||
FilterInitializeAction,
|
|
||||||
FilterToggleAction
|
|
||||||
} from './sidebar-filter.actions';
|
|
||||||
import { storeModuleConfig } from '../../../app.reducer';
|
|
||||||
|
|
||||||
describe('SidebarFilterService', () => {
|
|
||||||
let service: SidebarFilterService;
|
|
||||||
let store: any;
|
|
||||||
let initialState;
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
|
|
||||||
initialState = {
|
|
||||||
sidebarFilter: {
|
|
||||||
filter_1: {
|
|
||||||
filterCollapsed: true
|
|
||||||
},
|
|
||||||
filter_2: {
|
|
||||||
filterCollapsed: false
|
|
||||||
},
|
|
||||||
filter_3: {
|
|
||||||
filterCollapsed: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
|
||||||
init();
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
imports: [
|
|
||||||
StoreModule.forRoot({ sidebarFilter: sidebarFilterReducer }, storeModuleConfig)
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
provideMockStore({ initialState }),
|
|
||||||
{ provide: SidebarFilterService, useValue: service }
|
|
||||||
]
|
|
||||||
}).compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
store = TestBed.inject(Store);
|
|
||||||
service = new SidebarFilterService(store);
|
|
||||||
spyOn(store, 'dispatch');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('initializeFilter', () => {
|
|
||||||
it('should dispatch an FilterInitializeAction with the correct arguments', () => {
|
|
||||||
service.initializeFilter('fakeFilter', true);
|
|
||||||
expect(store.dispatch).toHaveBeenCalledWith(new FilterInitializeAction('fakeFilter', true));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('collapse', () => {
|
|
||||||
it('should dispatch an FilterInitializeAction with the correct arguments', () => {
|
|
||||||
service.collapse('fakeFilter');
|
|
||||||
expect(store.dispatch).toHaveBeenCalledWith(new FilterCollapseAction('fakeFilter'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('expand', () => {
|
|
||||||
it('should dispatch an FilterInitializeAction with the correct arguments', () => {
|
|
||||||
service.expand('fakeFilter');
|
|
||||||
expect(store.dispatch).toHaveBeenCalledWith(new FilterExpandAction('fakeFilter'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('toggle', () => {
|
|
||||||
it('should dispatch an FilterInitializeAction with the correct arguments', () => {
|
|
||||||
service.toggle('fakeFilter');
|
|
||||||
expect(store.dispatch).toHaveBeenCalledWith(new FilterToggleAction('fakeFilter'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isCollapsed', () => {
|
|
||||||
it('should return true', () => {
|
|
||||||
|
|
||||||
const result = service.isCollapsed('filter_1');
|
|
||||||
const expected = cold('b', {
|
|
||||||
b: true
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result).toBeObservable(expected);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false', () => {
|
|
||||||
|
|
||||||
const result = service.isCollapsed('filter_2');
|
|
||||||
const expected = cold('b', {
|
|
||||||
b: false
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result).toBeObservable(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@@ -1,90 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import {
|
|
||||||
FilterCollapseAction,
|
|
||||||
FilterExpandAction, FilterInitializeAction,
|
|
||||||
FilterToggleAction
|
|
||||||
} from './sidebar-filter.actions';
|
|
||||||
import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store';
|
|
||||||
import { SidebarFiltersState, SidebarFilterState } from './sidebar-filter.reducer';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { distinctUntilChanged, map } from 'rxjs/operators';
|
|
||||||
import { hasValue } from '../../empty.util';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service that performs all actions that have to do with sidebar filters like collapsing or expanding them.
|
|
||||||
*/
|
|
||||||
@Injectable()
|
|
||||||
export class SidebarFilterService {
|
|
||||||
|
|
||||||
constructor(private store: Store<SidebarFiltersState>) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatches an initialize action to the store for a given filter
|
|
||||||
* @param {string} filter The filter for which the action is dispatched
|
|
||||||
* @param {boolean} expanded If the filter should be open from the start
|
|
||||||
*/
|
|
||||||
public initializeFilter(filter: string, expanded: boolean): void {
|
|
||||||
this.store.dispatch(new FilterInitializeAction(filter, expanded));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatches a collapse action to the store for a given filter
|
|
||||||
* @param {string} filterName The filter for which the action is dispatched
|
|
||||||
*/
|
|
||||||
public collapse(filterName: string): void {
|
|
||||||
this.store.dispatch(new FilterCollapseAction(filterName));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatches an expand action to the store for a given filter
|
|
||||||
* @param {string} filterName The filter for which the action is dispatched
|
|
||||||
*/
|
|
||||||
public expand(filterName: string): void {
|
|
||||||
this.store.dispatch(new FilterExpandAction(filterName));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatches a toggle action to the store for a given filter
|
|
||||||
* @param {string} filterName The filter for which the action is dispatched
|
|
||||||
*/
|
|
||||||
public toggle(filterName: string): void {
|
|
||||||
this.store.dispatch(new FilterToggleAction(filterName));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the state of a given filter is currently collapsed or not
|
|
||||||
* @param {string} filterName The filtername for which the collapsed state is checked
|
|
||||||
* @returns {Observable<boolean>} Emits the current collapsed state of the given filter, if it's unavailable, return false
|
|
||||||
*/
|
|
||||||
isCollapsed(filterName: string): Observable<boolean> {
|
|
||||||
return this.store.pipe(
|
|
||||||
select(filterByNameSelector(filterName)),
|
|
||||||
map((object: SidebarFilterState) => {
|
|
||||||
if (object) {
|
|
||||||
return object.filterCollapsed;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
distinctUntilChanged()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const filterStateSelector = (state: SidebarFiltersState) => state.sidebarFilter;
|
|
||||||
|
|
||||||
function filterByNameSelector(name: string): MemoizedSelector<SidebarFiltersState, SidebarFilterState> {
|
|
||||||
return keySelector<SidebarFilterState>(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function keySelector<T>(key: string): MemoizedSelector<SidebarFiltersState, T> {
|
|
||||||
return createSelector(filterStateSelector, (state: SidebarFilterState) => {
|
|
||||||
if (hasValue(state)) {
|
|
||||||
return state[key];
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
@@ -3836,6 +3836,8 @@
|
|||||||
|
|
||||||
"submission.import-external.source.crossref": "CrossRef",
|
"submission.import-external.source.crossref": "CrossRef",
|
||||||
|
|
||||||
|
"submission.import-external.source.datacite": "DataCite",
|
||||||
|
|
||||||
"submission.import-external.source.scielo": "SciELO",
|
"submission.import-external.source.scielo": "SciELO",
|
||||||
|
|
||||||
"submission.import-external.source.scopus": "Scopus",
|
"submission.import-external.source.scopus": "Scopus",
|
||||||
|
@@ -204,3 +204,27 @@ ds-dynamic-form-control-container.d-none {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.badge-validation {
|
||||||
|
background-color: #{map-get($theme-colors, warning)};
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-waiting-controller {
|
||||||
|
background-color: #{map-get($theme-colors, info)};
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-workspace {
|
||||||
|
background-color: #{map-get($theme-colors, primary)};
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-archived {
|
||||||
|
background-color: #{map-get($theme-colors, success)};
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-workflow {
|
||||||
|
background-color: #{map-get($theme-colors, info)};
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-item-type {
|
||||||
|
background-color: #{map-get($theme-colors, info)};
|
||||||
|
}
|
||||||
|
@@ -1,13 +1,11 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
import { SharedModule } from '../../app/shared/shared.module';
|
import { SharedModule } from '../../app/shared/shared.module';
|
||||||
import { HomeNewsComponent } from './app/home-page/home-news/home-news.component';
|
import { HomeNewsComponent } from './app/home-page/home-news/home-news.component';
|
||||||
import { NavbarComponent } from './app/navbar/navbar.component';
|
import { NavbarComponent } from './app/navbar/navbar.component';
|
||||||
import { SearchNavbarComponent } from './app/search-navbar/search-navbar.component';
|
import { SearchNavbarComponent } from './app/search-navbar/search-navbar.component';
|
||||||
import { HeaderComponent } from './app/header/header.component';
|
import { HeaderComponent } from './app/header/header.component';
|
||||||
import { HeaderNavbarWrapperComponent } from './app/header-nav-wrapper/header-navbar-wrapper.component';
|
import { HeaderNavbarWrapperComponent } from './app/header-nav-wrapper/header-navbar-wrapper.component';
|
||||||
import { SearchModule } from '../../app/shared/search/search.module';
|
|
||||||
import { RootModule } from '../../app/root.module';
|
import { RootModule } from '../../app/root.module';
|
||||||
import { NavbarModule } from '../../app/navbar/navbar.module';
|
import { NavbarModule } from '../../app/navbar/navbar.module';
|
||||||
import { PublicationComponent } from './app/item-page/simple/item-types/publication/publication.component';
|
import { PublicationComponent } from './app/item-page/simple/item-types/publication/publication.component';
|
||||||
@@ -42,7 +40,7 @@ import {
|
|||||||
} from './app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component';
|
} from './app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component';
|
||||||
|
|
||||||
import { CommunityListElementComponent } from './app/shared/object-list/community-list-element/community-list-element.component';
|
import { CommunityListElementComponent } from './app/shared/object-list/community-list-element/community-list-element.component';
|
||||||
import { CollectionListElementComponent} from './app/shared/object-list/collection-list-element/collection-list-element.component';
|
import { CollectionListElementComponent } from './app/shared/object-list/collection-list-element/collection-list-element.component';
|
||||||
import { CollectionDropdownComponent } from './app/shared/collection-dropdown/collection-dropdown.component';
|
import { CollectionDropdownComponent } from './app/shared/collection-dropdown/collection-dropdown.component';
|
||||||
|
|
||||||
|
|
||||||
@@ -82,8 +80,6 @@ const DECLARATIONS = [
|
|||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
SharedModule,
|
SharedModule,
|
||||||
SearchModule,
|
|
||||||
FormsModule,
|
|
||||||
RootModule,
|
RootModule,
|
||||||
NavbarModule,
|
NavbarModule,
|
||||||
ItemPageModule,
|
ItemPageModule,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user