mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Merge pull request #3027 from alexandrevryghem/discovery-backports_contribute-7_x
[Port dspace-7_x] Multiple discovery backports
This commit is contained in:
@@ -8,6 +8,7 @@ import { SearchConfigurationService } from '../core/shared/search/search-configu
|
|||||||
import { RouteService } from '../core/services/route.service';
|
import { RouteService } from '../core/services/route.service';
|
||||||
import { SearchService } from '../core/shared/search/search.service';
|
import { SearchService } from '../core/shared/search/search.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
import { APP_CONFIG, AppConfig } from '../../config/app-config.interface';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component renders a search page using a configuration as input.
|
* This component renders a search page using a configuration as input.
|
||||||
@@ -32,7 +33,9 @@ export class ConfigurationSearchPageComponent extends SearchComponent {
|
|||||||
protected windowService: HostWindowService,
|
protected windowService: HostWindowService,
|
||||||
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
|
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
|
||||||
protected routeService: RouteService,
|
protected routeService: RouteService,
|
||||||
protected router: Router) {
|
protected router: Router,
|
||||||
super(service, sidebarService, windowService, searchConfigService, routeService, router);
|
@Inject(APP_CONFIG) protected appConfig: AppConfig,
|
||||||
|
) {
|
||||||
|
super(service, sidebarService, windowService, searchConfigService, routeService, router, appConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,18 +1,31 @@
|
|||||||
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
||||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
|
||||||
import { ListableObjectComponentLoaderComponent } from './listable-object-component-loader.component';
|
import { ListableObjectComponentLoaderComponent } from './listable-object-component-loader.component';
|
||||||
import { ListableObject } from '../listable-object.model';
|
import { ListableObject } from '../listable-object.model';
|
||||||
import { GenericConstructor } from '../../../../core/shared/generic-constructor';
|
import { GenericConstructor } from '../../../../core/shared/generic-constructor';
|
||||||
import { Context } from '../../../../core/shared/context.model';
|
import { Context } from '../../../../core/shared/context.model';
|
||||||
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
||||||
import {
|
|
||||||
ItemListElementComponent
|
|
||||||
} from '../../../object-list/item-list-element/item-types/item/item-list-element.component';
|
|
||||||
import { ListableObjectDirective } from './listable-object.directive';
|
import { ListableObjectDirective } from './listable-object.directive';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { provideMockStore } from '@ngrx/store/testing';
|
|
||||||
import { ThemeService } from '../../../theme-support/theme.service';
|
import { ThemeService } from '../../../theme-support/theme.service';
|
||||||
|
import { ItemSearchResultListElementComponent } from '../../../object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component';
|
||||||
|
import { ActivatedRouteStub } from '../../../testing/active-router.stub';
|
||||||
|
import { AuthServiceStub } from '../../../testing/auth-service.stub';
|
||||||
|
import { AuthorizationDataServiceStub } from '../../../testing/authorization-service.stub';
|
||||||
|
import { FileServiceStub } from '../../../testing/file-service.stub';
|
||||||
|
import { TruncatableServiceStub } from '../../../testing/truncatable-service.stub';
|
||||||
|
import { getMockThemeService } from '../../../mocks/theme-service.mock';
|
||||||
|
import { APP_CONFIG } from '../../../../../config/app-config.interface';
|
||||||
|
import { environment } from '../../../../../environments/environment.test';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { AuthService } from '../../../../core/auth/auth.service';
|
||||||
|
import { AuthorizationDataService } from '../../../../core/data/feature-authorization/authorization-data.service';
|
||||||
|
import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service';
|
||||||
|
import { DSONameServiceMock } from '../../../mocks/dso-name.service.mock';
|
||||||
|
import { FileService } from '../../../../core/shared/file.service';
|
||||||
|
import { TruncatableService } from '../../../truncatable/truncatable.service';
|
||||||
|
import { ChangeDetectionStrategy } from '@angular/core';
|
||||||
|
import { SearchResultListElementComponent } from '../../../object-list/search-result-list-element/search-result-list-element.component';
|
||||||
|
|
||||||
const testType = 'TestType';
|
const testType = 'TestType';
|
||||||
const testContext = Context.Search;
|
const testContext = Context.Search;
|
||||||
@@ -28,24 +41,41 @@ describe('ListableObjectComponentLoaderComponent', () => {
|
|||||||
let comp: ListableObjectComponentLoaderComponent;
|
let comp: ListableObjectComponentLoaderComponent;
|
||||||
let fixture: ComponentFixture<ListableObjectComponentLoaderComponent>;
|
let fixture: ComponentFixture<ListableObjectComponentLoaderComponent>;
|
||||||
|
|
||||||
|
let activatedRoute: ActivatedRouteStub;
|
||||||
|
let authService: AuthServiceStub;
|
||||||
|
let authorizationService: AuthorizationDataServiceStub;
|
||||||
|
let fileService: FileServiceStub;
|
||||||
let themeService: ThemeService;
|
let themeService: ThemeService;
|
||||||
|
let truncatableService: TruncatableServiceStub;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
themeService = jasmine.createSpyObj('themeService', {
|
activatedRoute = new ActivatedRouteStub();
|
||||||
getThemeName: 'dspace',
|
authService = new AuthServiceStub();
|
||||||
});
|
authorizationService = new AuthorizationDataServiceStub();
|
||||||
TestBed.configureTestingModule({
|
fileService = new FileServiceStub();
|
||||||
|
themeService = getMockThemeService();
|
||||||
|
truncatableService = new TruncatableServiceStub();
|
||||||
|
|
||||||
|
void TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot()],
|
imports: [TranslateModule.forRoot()],
|
||||||
declarations: [ListableObjectComponentLoaderComponent, ItemListElementComponent, ListableObjectDirective],
|
declarations: [
|
||||||
schemas: [NO_ERRORS_SCHEMA],
|
ItemSearchResultListElementComponent,
|
||||||
|
ListableObjectComponentLoaderComponent,
|
||||||
|
ListableObjectDirective,
|
||||||
|
],
|
||||||
providers: [
|
providers: [
|
||||||
provideMockStore({}),
|
{ provide: APP_CONFIG, useValue: environment },
|
||||||
|
{ provide: ActivatedRoute, useValue: activatedRoute },
|
||||||
|
{ provide: AuthService, useValue: authService },
|
||||||
|
{ provide: AuthorizationDataService, useValue: authorizationService },
|
||||||
|
{ provide: DSONameService, useValue: new DSONameServiceMock() },
|
||||||
|
{ provide: FileService, useValue: fileService },
|
||||||
{ provide: ThemeService, useValue: themeService },
|
{ provide: ThemeService, useValue: themeService },
|
||||||
|
{ provide: TruncatableService, useValue: truncatableService },
|
||||||
]
|
]
|
||||||
}).overrideComponent(ListableObjectComponentLoaderComponent, {
|
}).overrideComponent(ListableObjectComponentLoaderComponent, {
|
||||||
set: {
|
set: {
|
||||||
changeDetection: ChangeDetectionStrategy.Default,
|
changeDetection: ChangeDetectionStrategy.Default,
|
||||||
entryComponents: [ItemListElementComponent]
|
|
||||||
}
|
}
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
@@ -57,7 +87,7 @@ describe('ListableObjectComponentLoaderComponent', () => {
|
|||||||
comp.object = new TestType();
|
comp.object = new TestType();
|
||||||
comp.viewMode = testViewMode;
|
comp.viewMode = testViewMode;
|
||||||
comp.context = testContext;
|
comp.context = testContext;
|
||||||
spyOn(comp, 'getComponent').and.returnValue(ItemListElementComponent as any);
|
spyOn(comp, 'getComponent').and.returnValue(SearchResultListElementComponent as any);
|
||||||
spyOn(comp as any, 'connectInputsAndOutputs').and.callThrough();
|
spyOn(comp as any, 'connectInputsAndOutputs').and.callThrough();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
@@ -81,7 +111,7 @@ describe('ListableObjectComponentLoaderComponent', () => {
|
|||||||
spyOn((comp as any), 'instantiateComponent').and.returnValue(null);
|
spyOn((comp as any), 'instantiateComponent').and.returnValue(null);
|
||||||
spyOn((comp as any).contentChange, 'emit').and.returnValue(null);
|
spyOn((comp as any).contentChange, 'emit').and.returnValue(null);
|
||||||
|
|
||||||
listableComponent = fixture.debugElement.query(By.css('ds-item-list-element')).componentInstance;
|
listableComponent = fixture.debugElement.query(By.css('ds-search-result-list-element')).componentInstance;
|
||||||
reloadedObject = 'object';
|
reloadedObject = 'object';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1 +1,5 @@
|
|||||||
<ds-item-search-result-list-element [showLabel]="showLabel" [object]="{ indexableObject: object, hitHighlights: {} }" [linkType]="linkType"></ds-item-search-result-list-element>
|
<ds-listable-object-component-loader
|
||||||
|
[object]="itemSearchResult"
|
||||||
|
[viewMode]="viewMode"
|
||||||
|
[linkType]="linkType">
|
||||||
|
</ds-listable-object-component-loader>
|
||||||
|
@@ -1,13 +1,26 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed, waitForAsync, ComponentFixture } from '@angular/core/testing';
|
||||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
import { ChangeDetectionStrategy } from '@angular/core';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { ItemListElementComponent } from './item-list-element.component';
|
import { ItemListElementComponent } from './item-list-element.component';
|
||||||
import { Item } from '../../../../../core/shared/item.model';
|
import { Item } from '../../../../../core/shared/item.model';
|
||||||
import { TruncatePipe } from '../../../../utils/truncate.pipe';
|
|
||||||
import { TruncatableService } from '../../../../truncatable/truncatable.service';
|
import { TruncatableService } from '../../../../truncatable/truncatable.service';
|
||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
|
import { ListableObjectComponentLoaderComponent } from '../../../../object-collection/shared/listable-object/listable-object-component-loader.component';
|
||||||
import { DSONameServiceMock } from '../../../../mocks/dso-name.service.mock';
|
import { getMockThemeService } from '../../../../mocks/theme-service.mock';
|
||||||
|
import { ThemeService } from '../../../../theme-support/theme.service';
|
||||||
|
import { ListableObjectDirective } from '../../../../object-collection/shared/listable-object/listable-object.directive';
|
||||||
|
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
|
||||||
|
import { environment } from '../../../../../../environments/environment.test';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { ActivatedRouteStub } from '../../../../testing/active-router.stub';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { AuthService } from '../../../../../core/auth/auth.service';
|
||||||
|
import { AuthServiceStub } from '../../../../testing/auth-service.stub';
|
||||||
|
import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service';
|
||||||
|
import { AuthorizationDataServiceStub } from '../../../../testing/authorization-service.stub';
|
||||||
|
import { FileService } from '../../../../../core/shared/file.service';
|
||||||
|
import { FileServiceStub } from '../../../../testing/file-service.stub';
|
||||||
|
import { TruncatableServiceStub } from '../../../../testing/truncatable-service.stub';
|
||||||
|
|
||||||
const mockItem: Item = Object.assign(new Item(), {
|
const mockItem: Item = Object.assign(new Item(), {
|
||||||
bundles: observableOf({}),
|
bundles: observableOf({}),
|
||||||
@@ -46,21 +59,42 @@ const mockItem: Item = Object.assign(new Item(), {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('ItemListElementComponent', () => {
|
describe('ItemListElementComponent', () => {
|
||||||
let comp;
|
let comp: ItemListElementComponent;
|
||||||
let fixture;
|
let fixture: ComponentFixture<ItemListElementComponent>;
|
||||||
|
|
||||||
const truncatableServiceStub: any = {
|
let activatedRoute: ActivatedRouteStub;
|
||||||
isCollapsed: (id: number) => observableOf(true),
|
let authService: AuthServiceStub;
|
||||||
};
|
let authorizationService: AuthorizationDataServiceStub;
|
||||||
|
let fileService: FileServiceStub;
|
||||||
|
let themeService: ThemeService;
|
||||||
|
let truncatableService: TruncatableServiceStub;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
activatedRoute = new ActivatedRouteStub();
|
||||||
declarations: [ItemListElementComponent, TruncatePipe],
|
authService = new AuthServiceStub();
|
||||||
providers: [
|
authorizationService = new AuthorizationDataServiceStub();
|
||||||
{ provide: DSONameService, useValue: new DSONameServiceMock() },
|
fileService = new FileServiceStub();
|
||||||
{ provide: TruncatableService, useValue: truncatableServiceStub },
|
themeService = getMockThemeService();
|
||||||
|
truncatableService = new TruncatableServiceStub();
|
||||||
|
|
||||||
|
void TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
TranslateModule.forRoot(),
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
ItemListElementComponent,
|
||||||
|
ListableObjectComponentLoaderComponent,
|
||||||
|
ListableObjectDirective,
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: APP_CONFIG, useValue: environment },
|
||||||
|
{ provide: ActivatedRoute, useValue: activatedRoute },
|
||||||
|
{ provide: AuthService, useValue: authService },
|
||||||
|
{ provide: AuthorizationDataService, useValue: authorizationService },
|
||||||
|
{ provide: FileService, useValue: fileService },
|
||||||
|
{ provide: ThemeService, useValue: themeService },
|
||||||
|
{ provide: TruncatableService, useValue: truncatableService },
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
|
||||||
}).overrideComponent(ItemListElementComponent, {
|
}).overrideComponent(ItemListElementComponent, {
|
||||||
set: { changeDetection: ChangeDetectionStrategy.Default }
|
set: { changeDetection: ChangeDetectionStrategy.Default }
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
@@ -74,6 +108,7 @@ describe('ItemListElementComponent', () => {
|
|||||||
describe(`when the publication is rendered`, () => {
|
describe(`when the publication is rendered`, () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
comp.object = mockItem;
|
comp.object = mockItem;
|
||||||
|
comp.ngOnChanges();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,8 +1,14 @@
|
|||||||
import { Component } from '@angular/core';
|
import {
|
||||||
|
Component,
|
||||||
|
OnChanges,
|
||||||
|
} from '@angular/core';
|
||||||
|
|
||||||
import { ViewMode } from '../../../../../core/shared/view-mode.model';
|
import { ViewMode } from '../../../../../core/shared/view-mode.model';
|
||||||
import { listableObjectComponent } from '../../../../object-collection/shared/listable-object/listable-object.decorator';
|
import { listableObjectComponent } from '../../../../object-collection/shared/listable-object/listable-object.decorator';
|
||||||
import { AbstractListableElementComponent } from '../../../../object-collection/shared/object-collection-element/abstract-listable-element.component';
|
import { AbstractListableElementComponent } from '../../../../object-collection/shared/object-collection-element/abstract-listable-element.component';
|
||||||
import { Item } from '../../../../../core/shared/item.model';
|
import { Item } from '../../../../../core/shared/item.model';
|
||||||
|
import { ItemSearchResult } from '../../../../object-collection/shared/item-search-result.model';
|
||||||
|
import { hasValue } from '../../../../empty.util';
|
||||||
|
|
||||||
@listableObjectComponent('Publication', ViewMode.ListElement)
|
@listableObjectComponent('Publication', ViewMode.ListElement)
|
||||||
@listableObjectComponent(Item, ViewMode.ListElement)
|
@listableObjectComponent(Item, ViewMode.ListElement)
|
||||||
@@ -14,5 +20,16 @@ import { Item } from '../../../../../core/shared/item.model';
|
|||||||
/**
|
/**
|
||||||
* The component for displaying a list element for an item of the type Publication
|
* The component for displaying a list element for an item of the type Publication
|
||||||
*/
|
*/
|
||||||
export class ItemListElementComponent extends AbstractListableElementComponent<Item> {
|
export class ItemListElementComponent extends AbstractListableElementComponent<Item> implements OnChanges {
|
||||||
|
|
||||||
|
itemSearchResult: ItemSearchResult;
|
||||||
|
|
||||||
|
ngOnChanges(): void {
|
||||||
|
if (hasValue(this.object)) {
|
||||||
|
this.itemSearchResult = Object.assign(new ItemSearchResult(), {
|
||||||
|
indexableObject: this.object,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,8 @@ import { SearchConfigurationServiceStub } from '../../../../testing/search-confi
|
|||||||
import { VocabularyEntryDetail } from '../../../../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
|
import { VocabularyEntryDetail } from '../../../../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
|
||||||
import { FacetValue} from '../../../models/facet-value.model';
|
import { FacetValue} from '../../../models/facet-value.model';
|
||||||
import { SearchFilterConfig } from '../../../models/search-filter-config.model';
|
import { SearchFilterConfig } from '../../../models/search-filter-config.model';
|
||||||
|
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
|
||||||
|
import { environment } from '../../../../../../environments/environment.test';
|
||||||
|
|
||||||
describe('SearchHierarchyFilterComponent', () => {
|
describe('SearchHierarchyFilterComponent', () => {
|
||||||
|
|
||||||
@@ -34,7 +36,7 @@ describe('SearchHierarchyFilterComponent', () => {
|
|||||||
let showVocabularyTreeLink: DebugElement;
|
let showVocabularyTreeLink: DebugElement;
|
||||||
|
|
||||||
const testSearchLink = 'test-search';
|
const testSearchLink = 'test-search';
|
||||||
const testSearchFilter = 'test-search-filter';
|
const testSearchFilter = 'subject';
|
||||||
const VocabularyTreeViewComponent = {
|
const VocabularyTreeViewComponent = {
|
||||||
select: new EventEmitter<VocabularyEntryDetail>(),
|
select: new EventEmitter<VocabularyEntryDetail>(),
|
||||||
};
|
};
|
||||||
@@ -73,6 +75,7 @@ describe('SearchHierarchyFilterComponent', () => {
|
|||||||
{ provide: Router, useValue: router },
|
{ provide: Router, useValue: router },
|
||||||
{ provide: NgbModal, useValue: ngbModal },
|
{ provide: NgbModal, useValue: ngbModal },
|
||||||
{ provide: VocabularyService, useValue: vocabularyService },
|
{ provide: VocabularyService, useValue: vocabularyService },
|
||||||
|
{ provide: APP_CONFIG, useValue: environment },
|
||||||
{ provide: SEARCH_CONFIG_SERVICE, useValue: new SearchConfigurationServiceStub() },
|
{ provide: SEARCH_CONFIG_SERVICE, useValue: new SearchConfigurationServiceStub() },
|
||||||
{ provide: IN_PLACE_SEARCH, useValue: false },
|
{ provide: IN_PLACE_SEARCH, useValue: false },
|
||||||
{ provide: FILTER_CONFIG, useValue: Object.assign(new SearchFilterConfig(), { name: testSearchFilter }) },
|
{ provide: FILTER_CONFIG, useValue: Object.assign(new SearchFilterConfig(), { name: testSearchFilter }) },
|
||||||
@@ -86,7 +89,7 @@ describe('SearchHierarchyFilterComponent', () => {
|
|||||||
function init() {
|
function init() {
|
||||||
fixture = TestBed.createComponent(SearchHierarchyFilterComponent);
|
fixture = TestBed.createComponent(SearchHierarchyFilterComponent);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
showVocabularyTreeLink = fixture.debugElement.query(By.css('a#show-test-search-filter-tree'));
|
showVocabularyTreeLink = fixture.debugElement.query(By.css(`a#show-${testSearchFilter}-tree`));
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('if the vocabulary doesn\'t exist', () => {
|
describe('if the vocabulary doesn\'t exist', () => {
|
||||||
|
@@ -24,9 +24,11 @@ import { filter, map, take } from 'rxjs/operators';
|
|||||||
import { VocabularyService } from '../../../../../core/submission/vocabularies/vocabulary.service';
|
import { VocabularyService } from '../../../../../core/submission/vocabularies/vocabulary.service';
|
||||||
import { Observable, BehaviorSubject } from 'rxjs';
|
import { Observable, BehaviorSubject } from 'rxjs';
|
||||||
import { PageInfo } from '../../../../../core/shared/page-info.model';
|
import { PageInfo } from '../../../../../core/shared/page-info.model';
|
||||||
import { environment } from '../../../../../../environments/environment';
|
|
||||||
import { addOperatorToFilterValue } from '../../../search.utils';
|
import { addOperatorToFilterValue } from '../../../search.utils';
|
||||||
import { VocabularyTreeviewModalComponent } from '../../../../form/vocabulary-treeview-modal/vocabulary-treeview-modal.component';
|
import { VocabularyTreeviewModalComponent } from '../../../../form/vocabulary-treeview-modal/vocabulary-treeview-modal.component';
|
||||||
|
import { hasValue } from '../../../../empty.util';
|
||||||
|
import { APP_CONFIG, AppConfig } from '../../../../../../config/app-config.interface';
|
||||||
|
import { FilterVocabularyConfig } from '../../../../../../config/filter-vocabulary-config';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-search-hierarchy-filter',
|
selector: 'ds-search-hierarchy-filter',
|
||||||
@@ -47,6 +49,7 @@ export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent i
|
|||||||
protected router: Router,
|
protected router: Router,
|
||||||
protected modalService: NgbModal,
|
protected modalService: NgbModal,
|
||||||
protected vocabularyService: VocabularyService,
|
protected vocabularyService: VocabularyService,
|
||||||
|
@Inject(APP_CONFIG) protected appConfig: AppConfig,
|
||||||
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
|
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
|
||||||
@Inject(IN_PLACE_SEARCH) public inPlaceSearch: boolean,
|
@Inject(IN_PLACE_SEARCH) public inPlaceSearch: boolean,
|
||||||
@Inject(FILTER_CONFIG) public filterConfig: SearchFilterConfig,
|
@Inject(FILTER_CONFIG) public filterConfig: SearchFilterConfig,
|
||||||
@@ -67,17 +70,20 @@ export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent i
|
|||||||
super.onSubmit(addOperatorToFilterValue(data, 'query'));
|
super.onSubmit(addOperatorToFilterValue(data, 'query'));
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit(): void {
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
this.vocabularyExists$ = this.vocabularyService.searchTopEntries(
|
const vocabularyName: string = this.getVocabularyEntry();
|
||||||
this.getVocabularyEntry(), new PageInfo(), true, false,
|
if (hasValue(vocabularyName)) {
|
||||||
).pipe(
|
this.vocabularyExists$ = this.vocabularyService.searchTopEntries(
|
||||||
filter(rd => rd.hasCompleted),
|
vocabularyName, new PageInfo(), true, false,
|
||||||
take(1),
|
).pipe(
|
||||||
map(rd => {
|
filter(rd => rd.hasCompleted),
|
||||||
return rd.hasSucceeded;
|
take(1),
|
||||||
}),
|
map(rd => {
|
||||||
);
|
return rd.hasSucceeded;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,11 +99,11 @@ export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent i
|
|||||||
name: this.getVocabularyEntry(),
|
name: this.getVocabularyEntry(),
|
||||||
closed: true
|
closed: true
|
||||||
};
|
};
|
||||||
modalRef.result.then((detail: VocabularyEntryDetail) => {
|
void modalRef.result.then((detail: VocabularyEntryDetail) => {
|
||||||
this.selectedValues$
|
this.subs.push(this.selectedValues$
|
||||||
.pipe(take(1))
|
.pipe(take(1))
|
||||||
.subscribe((selectedValues) => {
|
.subscribe((selectedValues) => {
|
||||||
this.router.navigate(
|
void this.router.navigate(
|
||||||
[this.searchService.getSearchLink()],
|
[this.searchService.getSearchLink()],
|
||||||
{
|
{
|
||||||
queryParams: {
|
queryParams: {
|
||||||
@@ -107,16 +113,16 @@ export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent i
|
|||||||
queryParamsHandling: 'merge',
|
queryParamsHandling: 'merge',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
}));
|
||||||
}).catch();
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the matching vocabulary entry for the given search filter.
|
* Returns the matching vocabulary entry for the given search filter.
|
||||||
* These are configurable in the config file.
|
* These are configurable in the config file.
|
||||||
*/
|
*/
|
||||||
getVocabularyEntry() {
|
getVocabularyEntry(): string {
|
||||||
const foundVocabularyConfig = environment.vocabularies.filter((v) => v.filter === this.filterConfig.name);
|
const foundVocabularyConfig: FilterVocabularyConfig[] = this.appConfig.vocabularies.filter((v: FilterVocabularyConfig) => v.filter === this.filterConfig.name);
|
||||||
if (foundVocabularyConfig.length > 0 && foundVocabularyConfig[0].enabled === true) {
|
if (foundVocabularyConfig.length > 0 && foundVocabularyConfig[0].enabled === true) {
|
||||||
return foundVocabularyConfig[0].vocabulary;
|
return foundVocabularyConfig[0].vocabulary;
|
||||||
}
|
}
|
||||||
|
@@ -33,6 +33,8 @@ import { SearchFilterConfig } from './models/search-filter-config.model';
|
|||||||
import { FilterType } from './models/filter-type.model';
|
import { FilterType } from './models/filter-type.model';
|
||||||
import { getCommunityPageRoute } from '../../community-page/community-page-routing-paths';
|
import { getCommunityPageRoute } from '../../community-page/community-page-routing-paths';
|
||||||
import { getCollectionPageRoute } from '../../collection-page/collection-page-routing-paths';
|
import { getCollectionPageRoute } from '../../collection-page/collection-page-routing-paths';
|
||||||
|
import { environment } from '../../../environments/environment.test';
|
||||||
|
import { APP_CONFIG } from '../../../config/app-config.interface';
|
||||||
|
|
||||||
let comp: SearchComponent;
|
let comp: SearchComponent;
|
||||||
let fixture: ComponentFixture<SearchComponent>;
|
let fixture: ComponentFixture<SearchComponent>;
|
||||||
@@ -209,7 +211,8 @@ export function configureSearchComponentTestingModule(compType, additionalDeclar
|
|||||||
{
|
{
|
||||||
provide: SEARCH_CONFIG_SERVICE,
|
provide: SEARCH_CONFIG_SERVICE,
|
||||||
useValue: searchConfigurationServiceStub
|
useValue: searchConfigurationServiceStub
|
||||||
}
|
},
|
||||||
|
{ provide: APP_CONFIG, useValue: environment },
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).overrideComponent(compType, {
|
}).overrideComponent(compType, {
|
||||||
|
@@ -31,13 +31,13 @@ import { ViewMode } from '../../core/shared/view-mode.model';
|
|||||||
import { SelectionConfig } from './search-results/search-results.component';
|
import { SelectionConfig } from './search-results/search-results.component';
|
||||||
import { ListableObject } from '../object-collection/shared/listable-object.model';
|
import { ListableObject } from '../object-collection/shared/listable-object.model';
|
||||||
import { CollectionElementLinkType } from '../object-collection/collection-element-link.type';
|
import { CollectionElementLinkType } from '../object-collection/collection-element-link.type';
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
import { SubmissionObject } from '../../core/submission/models/submission-object.model';
|
import { SubmissionObject } from '../../core/submission/models/submission-object.model';
|
||||||
import { SearchFilterConfig } from './models/search-filter-config.model';
|
import { SearchFilterConfig } from './models/search-filter-config.model';
|
||||||
import { WorkspaceItem } from '../../core/submission/models/workspaceitem.model';
|
import { WorkspaceItem } from '../../core/submission/models/workspaceitem.model';
|
||||||
import { ITEM_MODULE_PATH } from '../../item-page/item-page-routing-paths';
|
import { ITEM_MODULE_PATH } from '../../item-page/item-page-routing-paths';
|
||||||
import { COLLECTION_MODULE_PATH } from '../../collection-page/collection-page-routing-paths';
|
import { COLLECTION_MODULE_PATH } from '../../collection-page/collection-page-routing-paths';
|
||||||
import { COMMUNITY_MODULE_PATH } from '../../community-page/community-page-routing-paths';
|
import { COMMUNITY_MODULE_PATH } from '../../community-page/community-page-routing-paths';
|
||||||
|
import { AppConfig, APP_CONFIG } from '../../../config/app-config.interface';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-search',
|
selector: 'ds-search',
|
||||||
@@ -278,7 +278,9 @@ export class SearchComponent implements OnDestroy, OnInit {
|
|||||||
protected windowService: HostWindowService,
|
protected windowService: HostWindowService,
|
||||||
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
|
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
|
||||||
protected routeService: RouteService,
|
protected routeService: RouteService,
|
||||||
protected router: Router) {
|
protected router: Router,
|
||||||
|
@Inject(APP_CONFIG) protected appConfig: AppConfig,
|
||||||
|
) {
|
||||||
this.isXsOrSm$ = this.windowService.isXsOrSm();
|
this.isXsOrSm$ = this.windowService.isXsOrSm();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,8 +447,10 @@ export class SearchComponent implements OnDestroy, OnInit {
|
|||||||
let followLinks = [
|
let followLinks = [
|
||||||
followLink<Item>('thumbnail', { isOptional: true }),
|
followLink<Item>('thumbnail', { isOptional: true }),
|
||||||
followLink<SubmissionObject>('item', { isOptional: true }, followLink<Item>('thumbnail', { isOptional: true })) as any,
|
followLink<SubmissionObject>('item', { isOptional: true }, followLink<Item>('thumbnail', { isOptional: true })) as any,
|
||||||
followLink<Item>('accessStatus', { isOptional: true, shouldEmbed: environment.item.showAccessStatuses }),
|
|
||||||
];
|
];
|
||||||
|
if (this.appConfig.item.showAccessStatuses) {
|
||||||
|
followLinks.push(followLink<Item>('accessStatus', { isOptional: true }));
|
||||||
|
}
|
||||||
if (this.configuration === 'supervision') {
|
if (this.configuration === 'supervision') {
|
||||||
followLinks.push(followLink<WorkspaceItem>('supervisionOrders', { isOptional: true }) as any);
|
followLinks.push(followLink<WorkspaceItem>('supervisionOrders', { isOptional: true }) as any);
|
||||||
}
|
}
|
||||||
|
@@ -3,10 +3,12 @@
|
|||||||
<div class="row-with-sidebar row-offcanvas row-offcanvas-left"
|
<div class="row-with-sidebar row-offcanvas row-offcanvas-left"
|
||||||
[@pushInOut]="(isSidebarCollapsed$ | async) ? 'collapsed' : 'expanded'">
|
[@pushInOut]="(isSidebarCollapsed$ | async) ? 'collapsed' : 'expanded'">
|
||||||
<div id="{{id}}-sidebar-content"
|
<div id="{{id}}-sidebar-content"
|
||||||
|
[class.invisible]="(isSidebarCollapsed$ | async) === true && (isXsOrSm$ | async) === true"
|
||||||
class="col-12 col-md-{{sideBarWidth}} sidebar-content {{sidebarClasses | async}}">
|
class="col-12 col-md-{{sideBarWidth}} sidebar-content {{sidebarClasses | async}}">
|
||||||
<ng-container *ngTemplateOutlet="sidebarContent"></ng-container>
|
<ng-container *ngTemplateOutlet="sidebarContent"></ng-container>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-{{12 - sideBarWidth}}">
|
<div class="col-12 col-md-{{12 - sideBarWidth}}"
|
||||||
|
[class.invisible]="(isSidebarCollapsed$ | async) === false && (isXsOrSm$ | async) === true">
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
21
src/app/shared/testing/truncatable-service.stub.ts
Normal file
21
src/app/shared/testing/truncatable-service.stub.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { Observable, of as observableOf } from 'rxjs';
|
||||||
|
|
||||||
|
export class TruncatableServiceStub {
|
||||||
|
|
||||||
|
isCollapsed(_id: string): Observable<boolean> {
|
||||||
|
return observableOf(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-empty, @typescript-eslint/no-empty-function
|
||||||
|
public toggle(_id: string): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-empty, @typescript-eslint/no-empty-function
|
||||||
|
public collapse(_id: string): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-empty, @typescript-eslint/no-empty-function
|
||||||
|
public expand(_id: string): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Angulartics2 } from 'angulartics2';
|
import { Angulartics2, EventTrack } from 'angulartics2';
|
||||||
import { StatisticsService } from '../statistics.service';
|
import { StatisticsService } from '../statistics.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,7 +23,7 @@ export class Angulartics2DSpace {
|
|||||||
.subscribe((event) => this.eventTrack(event));
|
.subscribe((event) => this.eventTrack(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
private eventTrack(event) {
|
private eventTrack(event: Partial<EventTrack>): void {
|
||||||
if (event.action === 'page_view') {
|
if (event.action === 'page_view') {
|
||||||
this.statisticsService.trackViewEvent(event.properties.object, event.properties.referrer);
|
this.statisticsService.trackViewEvent(event.properties.object, event.properties.referrer);
|
||||||
} else if (event.action === 'search') {
|
} else if (event.action === 'search') {
|
||||||
@@ -32,7 +32,7 @@ export class Angulartics2DSpace {
|
|||||||
event.properties.page,
|
event.properties.page,
|
||||||
event.properties.sort,
|
event.properties.sort,
|
||||||
event.properties.filters,
|
event.properties.filters,
|
||||||
event.properties.clickedObject,
|
event.properties.clickedObject?.split('?')[0],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user