mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
reinstated select multiple behavior
This commit is contained in:
@@ -5,7 +5,6 @@ import { GenericItemPageFieldComponent } from '../../field-components/specific-f
|
||||
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
|
||||
import { ITEM } from '../../../../shared/items/switcher/item-type-switcher.component';
|
||||
import { ItemDataService } from '../../../../core/data/item-data.service';
|
||||
import { SearchFixedFilterService } from '../../../../core/shared/search/search-fixed-filter.service';
|
||||
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
@@ -28,12 +27,6 @@ describe('PublicationComponent', () => {
|
||||
let comp: PublicationComponent;
|
||||
let fixture: ComponentFixture<PublicationComponent>;
|
||||
|
||||
const searchFixedFilterServiceStub = {
|
||||
/* tslint:disable:no-empty */
|
||||
getQueryByRelations: () => {}
|
||||
/* tslint:enable:no-empty */
|
||||
};
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot({
|
||||
@@ -46,7 +39,6 @@ describe('PublicationComponent', () => {
|
||||
providers: [
|
||||
{provide: ITEM, useValue: mockItem},
|
||||
{provide: ItemDataService, useValue: {}},
|
||||
{provide: SearchFixedFilterService, useValue: searchFixedFilterServiceStub},
|
||||
{provide: TruncatableService, useValue: {}}
|
||||
],
|
||||
|
||||
|
@@ -10,7 +10,6 @@ import { ChangeDetectionStrategy, DebugElement, NO_ERRORS_SCHEMA } from '@angula
|
||||
import { ITEM } from '../../../../shared/items/switcher/item-type-switcher.component';
|
||||
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
|
||||
import { isNotEmpty } from '../../../../shared/empty.util';
|
||||
import { SearchFixedFilterService } from '../../../../core/shared/search/search-fixed-filter.service';
|
||||
import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
@@ -39,12 +38,6 @@ export function getItemPageFieldsTest(mockItem: Item, component) {
|
||||
let comp: any;
|
||||
let fixture: ComponentFixture<any>;
|
||||
|
||||
const searchFixedFilterServiceStub = {
|
||||
/* tslint:disable:no-empty */
|
||||
getQueryByRelations: () => {}
|
||||
/* tslint:enable:no-empty */
|
||||
};
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot({
|
||||
@@ -57,7 +50,6 @@ export function getItemPageFieldsTest(mockItem: Item, component) {
|
||||
providers: [
|
||||
{provide: ITEM, useValue: mockItem},
|
||||
{provide: ItemDataService, useValue: {}},
|
||||
{provide: SearchFixedFilterService, useValue: searchFixedFilterServiceStub},
|
||||
{provide: TruncatableService, useValue: {}}
|
||||
],
|
||||
|
||||
@@ -366,13 +358,6 @@ describe('ItemComponent', () => {
|
||||
authority: '123'
|
||||
}
|
||||
] as MetadataValue[];
|
||||
const mockItemDataService = Object.assign({
|
||||
findById: (id) => {
|
||||
if (id === relatedItem.id) {
|
||||
return observableOf(new RemoteData(false, false, true, null, relatedItem))
|
||||
}
|
||||
}
|
||||
}) as ItemDataService;
|
||||
|
||||
let representations: Observable<MetadataRepresentation[]>;
|
||||
|
||||
|
@@ -4,13 +4,11 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { SearchFixedFilterService } from '../../../../core/shared/search/search-fixed-filter.service';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
|
||||
describe('RelatedEntitiesSearchComponent', () => {
|
||||
let comp: RelatedEntitiesSearchComponent;
|
||||
let fixture: ComponentFixture<RelatedEntitiesSearchComponent>;
|
||||
let fixedFilterService: SearchFixedFilterService;
|
||||
|
||||
const mockItem = Object.assign(new Item(), {
|
||||
id: 'id1'
|
||||
@@ -18,17 +16,11 @@ describe('RelatedEntitiesSearchComponent', () => {
|
||||
const mockRelationType = 'publicationsOfAuthor';
|
||||
const mockRelationEntityType = 'publication';
|
||||
const mockFilter= `f.${mockRelationType}=${mockItem.id}`;
|
||||
const fixedFilterServiceStub = {
|
||||
getFilterByRelation: () => mockFilter
|
||||
};
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule],
|
||||
declarations: [RelatedEntitiesSearchComponent],
|
||||
providers: [
|
||||
{ provide: SearchFixedFilterService, useValue: fixedFilterServiceStub }
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).compileComponents();
|
||||
}));
|
||||
@@ -36,7 +28,6 @@ describe('RelatedEntitiesSearchComponent', () => {
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(RelatedEntitiesSearchComponent);
|
||||
comp = fixture.componentInstance;
|
||||
fixedFilterService = (comp as any).fixedFilterService;
|
||||
comp.relationType = mockRelationType;
|
||||
comp.item = mockItem;
|
||||
comp.relationEntityType = mockRelationEntityType;
|
||||
|
@@ -28,7 +28,6 @@ import { SearchFilterService } from '../core/shared/search/search-filter.service
|
||||
import { RoleDirective } from '../shared/roles/role.directive';
|
||||
import { RoleService } from '../core/roles/role.service';
|
||||
import { MockRoleService } from '../shared/mocks/mock-role-service';
|
||||
import { SearchFixedFilterService } from '../core/shared/search/search-fixed-filter.service';
|
||||
|
||||
describe('MyDSpacePageComponent', () => {
|
||||
let comp: MyDSpacePageComponent;
|
||||
@@ -80,11 +79,6 @@ describe('MyDSpacePageComponent', () => {
|
||||
collapse: () => this.isCollapsed = observableOf(true),
|
||||
expand: () => this.isCollapsed = observableOf(false)
|
||||
};
|
||||
const mockFixedFilterService: SearchFixedFilterService = {
|
||||
getQueryByFilterName: (filter: string) => {
|
||||
return observableOf(undefined)
|
||||
}
|
||||
} as SearchFixedFilterService;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@@ -124,10 +118,6 @@ describe('MyDSpacePageComponent', () => {
|
||||
provide: RoleService,
|
||||
useValue: new MockRoleService()
|
||||
},
|
||||
{
|
||||
provide: SearchFixedFilterService,
|
||||
useValue: mockFixedFilterService
|
||||
}
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(MyDSpacePageComponent, {
|
||||
|
@@ -24,7 +24,6 @@ import { SEARCH_CONFIG_SERVICE } from '../+my-dspace-page/my-dspace-page.compone
|
||||
import { RouteService } from '../shared/services/route.service';
|
||||
import { SearchConfigurationServiceStub } from '../shared/testing/search-configuration-service-stub';
|
||||
import { PaginatedSearchOptions } from '../shared/search/paginated-search-options.model';
|
||||
import { SearchFixedFilterService } from '../core/shared/search/search-fixed-filter.service';
|
||||
|
||||
let comp: SearchPageComponent;
|
||||
let fixture: ComponentFixture<SearchPageComponent>;
|
||||
@@ -88,11 +87,6 @@ const routeServiceStub = {
|
||||
return observableOf('')
|
||||
}
|
||||
};
|
||||
const mockFixedFilterService: SearchFixedFilterService = {
|
||||
getQueryByFilterName: (filter: string) => {
|
||||
return observableOf(undefined)
|
||||
}
|
||||
} as SearchFixedFilterService;
|
||||
|
||||
export function configureSearchComponentTestingModule(compType) {
|
||||
TestBed.configureTestingModule({
|
||||
@@ -125,10 +119,6 @@ export function configureSearchComponentTestingModule(compType) {
|
||||
provide: SearchFilterService,
|
||||
useValue: {}
|
||||
},
|
||||
{
|
||||
provide: SearchFixedFilterService,
|
||||
useValue: mockFixedFilterService
|
||||
},
|
||||
{
|
||||
provide: SearchConfigurationService,
|
||||
useValue: {
|
||||
|
@@ -8,19 +8,23 @@ import { RemoteData } from '../data/remote-data';
|
||||
import { ResourceType } from './resource-type';
|
||||
import { ListableObject } from '../../shared/object-collection/shared/listable-object.model';
|
||||
import { hasNoValue } from '../../shared/empty.util';
|
||||
import { excludeFromEquals } from '../utilities/equals.decorators';
|
||||
|
||||
/**
|
||||
* An abstract model class for a DSpaceObject.
|
||||
*/
|
||||
export class DSpaceObject extends ListableObject implements CacheableObject {
|
||||
|
||||
@excludeFromEquals
|
||||
private _name: string;
|
||||
|
||||
@excludeFromEquals
|
||||
self: string;
|
||||
|
||||
/**
|
||||
* The human-readable identifier of this DSpaceObject
|
||||
*/
|
||||
@excludeFromEquals
|
||||
id: string;
|
||||
|
||||
/**
|
||||
@@ -31,6 +35,7 @@ export class DSpaceObject extends ListableObject implements CacheableObject {
|
||||
/**
|
||||
* A string representing the kind of DSpaceObject, e.g. community, item, …
|
||||
*/
|
||||
@excludeFromEquals
|
||||
type: ResourceType;
|
||||
|
||||
/**
|
||||
@@ -50,6 +55,7 @@ export class DSpaceObject extends ListableObject implements CacheableObject {
|
||||
/**
|
||||
* All metadata of this DSpaceObject
|
||||
*/
|
||||
@excludeFromEquals
|
||||
metadata: MetadataMap;
|
||||
|
||||
/**
|
||||
@@ -62,11 +68,13 @@ export class DSpaceObject extends ListableObject implements CacheableObject {
|
||||
/**
|
||||
* An array of DSpaceObjects that are direct parents of this DSpaceObject
|
||||
*/
|
||||
@excludeFromEquals
|
||||
parents: Observable<RemoteData<DSpaceObject[]>>;
|
||||
|
||||
/**
|
||||
* The DSpaceObject that owns this DSpaceObject
|
||||
*/
|
||||
@excludeFromEquals
|
||||
owner: Observable<RemoteData<DSpaceObject>>;
|
||||
|
||||
/**
|
||||
|
@@ -8,12 +8,25 @@ class Dog extends EquatableObject<Dog> {
|
||||
@excludeFromEquals
|
||||
public ballsCaught: number;
|
||||
|
||||
@fieldsForEquals('name', 'age')
|
||||
public owner: {
|
||||
name: string;
|
||||
age: number;
|
||||
favouriteFood: string;
|
||||
public owner: Owner;
|
||||
|
||||
@fieldsForEquals('name')
|
||||
public favouriteToy: { name: string, colour: string };
|
||||
}
|
||||
|
||||
class Owner extends EquatableObject<Owner> {
|
||||
@excludeFromEquals
|
||||
favouriteFood: string;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
public age: number,
|
||||
favouriteFood: string
|
||||
) {
|
||||
super();
|
||||
this.favouriteFood = favouriteFood;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fdescribe('equatable', () => {
|
||||
@@ -24,12 +37,14 @@ fdescribe('equatable', () => {
|
||||
dogRoger = new Dog();
|
||||
dogRoger.name = 'Roger';
|
||||
dogRoger.ballsCaught = 6;
|
||||
dogRoger.owner = { name: 'Tommy', age: 16, favouriteFood: 'spaghetti' };
|
||||
dogRoger.owner = new Owner('Tommy', 16, 'spaghetti');
|
||||
dogRoger.favouriteToy = { name: 'Twinky', colour: 'red' };
|
||||
|
||||
dogMissy = new Dog();
|
||||
dogMissy.name = 'Missy';
|
||||
dogMissy.ballsCaught = 9;
|
||||
dogMissy.owner = { name: 'Jenny', age: 29, favouriteFood: 'pizza' };
|
||||
dogMissy.owner = new Owner('Jenny', 29, 'pizza');
|
||||
dogRoger.favouriteToy = { name: 'McSqueak', colour: 'grey' };
|
||||
});
|
||||
|
||||
it('should return false when the other object is undefined', () => {
|
||||
@@ -66,5 +81,33 @@ fdescribe('equatable', () => {
|
||||
const isEqual = dogRoger.equals(copyOfDogRoger);
|
||||
expect(isEqual).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true when the other object\'s nested object only differs in fields that are marked as excludeFromEquals, when the nested object is not marked decorated with @fieldsForEquals', () => {
|
||||
const copyOfDogRoger = cloneDeep(dogRoger);
|
||||
copyOfDogRoger.owner.favouriteFood = 'Sushi';
|
||||
const isEqual = dogRoger.equals(copyOfDogRoger);
|
||||
expect(isEqual).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when the other object\'s nested object differs in fields that are not marked as excludeFromEquals, when the nested object is not marked decorated with @fieldsForEquals', () => {
|
||||
const copyOfDogRoger = cloneDeep(dogRoger);
|
||||
copyOfDogRoger.owner.age = 36;
|
||||
const isEqual = dogRoger.equals(copyOfDogRoger);
|
||||
expect(isEqual).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true when the other object\'s nested object does not differ in fields that are listed inside the nested @fieldsForEquals decorator', () => {
|
||||
const copyOfDogRoger = cloneDeep(dogRoger);
|
||||
copyOfDogRoger.favouriteToy.colour = 'green';
|
||||
const isEqual = dogRoger.equals(copyOfDogRoger);
|
||||
expect(isEqual).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when the other object\'s nested object differs in fields that are listed inside the nested @fieldsForEquals decorator', () => {
|
||||
const copyOfDogRoger = cloneDeep(dogRoger);
|
||||
copyOfDogRoger.favouriteToy.name = 'Mister Bone';
|
||||
const isEqual = dogRoger.equals(copyOfDogRoger);
|
||||
expect(isEqual).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -33,7 +33,7 @@ export abstract class EquatableObject<T> {
|
||||
return true;
|
||||
}
|
||||
const excludedKeys = getExcludedFromEqualsFor(this.constructor);
|
||||
const keys = Object.keys(this).filter((key) => excludedKeys.findIndex((excludedKey) => key === excludedKey) < 0);
|
||||
const keys = Object.keys(this).filter((key) => !excludedKeys.includes(key));
|
||||
return equalsByFields(this, other, keys);
|
||||
}
|
||||
}
|
@@ -19,6 +19,51 @@
|
||||
<button class="btn btn-outline-secondary" type="submit">Go</button>
|
||||
</div>
|
||||
</form>
|
||||
<div *ngIf="repeatable" class="position-absolute">
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
<!-- In theory we don't need separate checkboxes for this,
|
||||
but I wasn't able to get this to work correctly without them.
|
||||
Checkboxes that are in the indeterminate state always switch to checked when clicked
|
||||
This seemed like the cleanest and clearest solution to solve this issue for now.
|
||||
-->
|
||||
<input *ngIf="!allSelected && !(someSelected$ | async)"
|
||||
type="checkbox"
|
||||
[indeterminate]="false"
|
||||
(change)="selectAll()">
|
||||
<input *ngIf="!allSelected && (someSelected$ | async)"
|
||||
type="checkbox"
|
||||
[indeterminate]="true"
|
||||
(change)="deselectAll()">
|
||||
<input *ngIf="allSelected" type="checkbox"
|
||||
[checked]="true"
|
||||
(change)="deselectAll()">
|
||||
</div>
|
||||
</div>
|
||||
<div ngbDropdown class="input-group-append">
|
||||
<button *ngIf="selectAllLoading" type="button"
|
||||
class="btn btn-outline-secondary rounded-right">
|
||||
<span class="spinner-border spinner-border-sm" role="status"
|
||||
aria-hidden="true"></span>
|
||||
<span class="sr-only">Loading...</span>
|
||||
</button>
|
||||
<button *ngIf="!selectAllLoading" id="resultdropdown" type="button"
|
||||
ngbDropdownToggle
|
||||
class="btn btn-outline-secondary dropdown-toggle-split"
|
||||
data-toggle="dropdown" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<div ngbDropdownMenu aria-labelledby="resultdropdown">
|
||||
<button class="dropdown-item" (click)="selectPage(resultsRD?.payload?.page)">Select page</button>
|
||||
<button class="dropdown-item" (click)="deselectPage(resultsRD?.payload?.page)">Deselect page</button>
|
||||
<button class="dropdown-item" (click)="selectAll()">Select all</button>
|
||||
<button class="dropdown-item" (click)="deselectAll()">Deselect all</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ds-search-results [searchResults]="resultsRD"
|
||||
[sortConfig]="this.searchConfig?.sort"
|
||||
[searchConfig]="this.searchConfig"
|
||||
@@ -29,10 +74,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<small>Selected {{(selection | async)?.length || 0}} items</small>
|
||||
<small>Selected {{(selection$ | async)?.length || 0}} items</small>
|
||||
<div>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="modal.dismiss()">Cancel
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="modal.dismiss()">Cancel</button>
|
||||
<button type="button" class="btn btn-danger" (click)="close()">Ok</button>
|
||||
</div>
|
||||
</div>
|
@@ -4,4 +4,8 @@
|
||||
|
||||
.modal-footer {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.position-absolute {
|
||||
right: $spacer;
|
||||
}
|
@@ -8,15 +8,16 @@ import { PaginatedSearchOptions } from '../../../../../search/paginated-search-o
|
||||
import { DSpaceObject } from '../../../../../../core/shared/dspace-object.model';
|
||||
import { PaginationComponentOptions } from '../../../../../pagination/pagination-component-options.model';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { hasValue } from '../../../../../empty.util';
|
||||
import { concat, filter, map, multicast, switchMap, take, takeWhile } from 'rxjs/operators';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { hasValue, isNotEmpty } from '../../../../../empty.util';
|
||||
import { concat, map, multicast, switchMap, take, takeWhile, tap } from 'rxjs/operators';
|
||||
import { Router } from '@angular/router';
|
||||
import { SEARCH_CONFIG_SERVICE } from '../../../../../../+my-dspace-page/my-dspace-page.component';
|
||||
import { SearchConfigurationService } from '../../../../../../core/shared/search/search-configuration.service';
|
||||
import { SelectableListService } from '../../../../../object-list/selectable-list/selectable-list.service';
|
||||
import { SelectableListState } from '../../../../../object-list/selectable-list/selectable-list.reducer';
|
||||
import { ListableObject } from '../../../../../object-collection/shared/listable-object.model';
|
||||
import { RouteService } from '../../../../../services/route.service';
|
||||
import { getSucceededRemoteData } from '../../../../../../core/shared/operators';
|
||||
|
||||
const RELATION_TYPE_FILTER_PREFIX = 'f.entityType=';
|
||||
|
||||
@@ -40,12 +41,16 @@ export class DsDynamicLookupRelationModalComponent implements OnInit {
|
||||
searchConfig: PaginatedSearchOptions;
|
||||
repeatable: boolean;
|
||||
searchQuery;
|
||||
allSelected: boolean;
|
||||
someSelected$: Observable<boolean>;
|
||||
selectAllLoading: boolean;
|
||||
initialPagination = Object.assign(new PaginationComponentOptions(), {
|
||||
id: 'submission-relation-list',
|
||||
pageSize: 10
|
||||
});
|
||||
selection: Observable<ListableObject[]>;
|
||||
selection$: Observable<ListableObject[]>;
|
||||
fixedFilter: string;
|
||||
|
||||
constructor(public modal: NgbActiveModal, private searchService: SearchService, private router: Router, private selectableListService: SelectableListService, private searchConfigService: SearchConfigurationService, private routeService: RouteService) {
|
||||
}
|
||||
|
||||
@@ -54,7 +59,8 @@ export class DsDynamicLookupRelationModalComponent implements OnInit {
|
||||
this.fixedFilter = RELATION_TYPE_FILTER_PREFIX + this.fieldName;
|
||||
this.routeService.setParameter('fixedFilterQuery', this.fixedFilter);
|
||||
|
||||
this.selection = this.selectableListService.getSelectableList(this.listId).pipe(map((listState: SelectableListState) => hasValue(listState) && hasValue(listState.selection) ? listState.selection : []));
|
||||
this.selection$ = this.selectableListService.getSelectableList(this.listId).pipe(map((listState: SelectableListState) => hasValue(listState) && hasValue(listState.selection) ? listState.selection : []));
|
||||
this.someSelected$ = this.selection$.pipe(map((selection) => isNotEmpty(selection)));
|
||||
this.resultsRD$ = this.searchConfigService.paginatedSearchOptions.pipe(
|
||||
map((options) => {
|
||||
return Object.assign(new PaginatedSearchOptions({}), options, { fixedFilter: RELATION_TYPE_FILTER_PREFIX + this.fieldName })
|
||||
@@ -93,4 +99,36 @@ export class DsDynamicLookupRelationModalComponent implements OnInit {
|
||||
queryParams: Object.assign({}, { page: 1, query: this.searchQuery }),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
selectPage(page: SearchResult<DSpaceObject>[]) {
|
||||
this.selectableListService.select(this.listId, page);
|
||||
}
|
||||
|
||||
deselectPage(page: SearchResult<DSpaceObject>[]) {
|
||||
this.allSelected = false;
|
||||
this.selectableListService.deselect(this.listId, page);
|
||||
}
|
||||
|
||||
selectAll() {
|
||||
this.allSelected = true;
|
||||
this.selectAllLoading = true;
|
||||
const fullPagination = Object.assign(new PaginationComponentOptions(), {
|
||||
query: this.searchQuery,
|
||||
currentPage: 1,
|
||||
pageSize: Number.POSITIVE_INFINITY
|
||||
});
|
||||
const fullSearchConfig = Object.assign(this.searchConfig, { pagination: fullPagination });
|
||||
const results = this.searchService.search(fullSearchConfig);
|
||||
results.pipe(
|
||||
getSucceededRemoteData(),
|
||||
map((resultsRD) => resultsRD.payload.page),
|
||||
tap(() => this.selectAllLoading = false),
|
||||
).subscribe((results) => this.selectableListService.select(this.listId, results));
|
||||
}
|
||||
|
||||
deselectAll() {
|
||||
this.allSelected = false;
|
||||
this.selectableListService.deselectAll(this.listId);
|
||||
}
|
||||
}
|
@@ -50,7 +50,6 @@ export class SearchFiltersComponent implements OnInit {
|
||||
private filterService: SearchFilterService,
|
||||
private router: Router,
|
||||
@Inject(SEARCH_CONFIG_SERVICE) private searchConfigService: SearchConfigurationService) {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||
import { MetadataMap } from '../../core/shared/metadata.models';
|
||||
import { ListableObject } from '../object-collection/shared/listable-object.model';
|
||||
import { excludeFromEquals, fieldsForEquals } from '../../core/utilities/equals.decorators';
|
||||
|
||||
/**
|
||||
* Represents a search result object of a certain (<T>) DSpaceObject
|
||||
@@ -9,14 +10,12 @@ export class SearchResult<T extends DSpaceObject> extends ListableObject {
|
||||
/**
|
||||
* The DSpaceObject that was found
|
||||
*/
|
||||
@fieldsForEquals('uuid')
|
||||
indexableObject: T;
|
||||
|
||||
/**
|
||||
* The metadata that was used to find this item, hithighlighted
|
||||
*/
|
||||
@excludeFromEquals
|
||||
hitHighlights: MetadataMap;
|
||||
|
||||
get id(): string {
|
||||
return this.indexableObject.id;
|
||||
}
|
||||
}
|
||||
|
@@ -27,15 +27,14 @@ import { SubmissionJsonPatchOperationsService } from '../../../core/submission/s
|
||||
import { SubmissionJsonPatchOperationsServiceStub } from '../../../shared/testing/submission-json-patch-operations-service-stub';
|
||||
import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder';
|
||||
import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner';
|
||||
import { Community } from '../../../core/shared/community.model';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
import { Collection } from '../../../core/shared/collection.model';
|
||||
import { createTestComponent } from '../../../shared/testing/utils';
|
||||
import { cold } from 'jasmine-marbles';
|
||||
import { SearchResult } from '../../../+search-page/search-result.model';
|
||||
import { SearchService } from '../../../+search-page/search-service/search.service';
|
||||
import { SearchResult } from '../../../shared/search/search-result.model';
|
||||
import { SearchService } from '../../../core/shared/search/search.service';
|
||||
|
||||
const mockCommunity1Collection1 = Object.assign(new Collection(), {
|
||||
name: 'Community 1-Collection 1',
|
||||
|
@@ -12,15 +12,7 @@ import {
|
||||
import { FormControl } from '@angular/forms';
|
||||
|
||||
import { BehaviorSubject, combineLatest, Observable, of as observableOf, Subscription } from 'rxjs';
|
||||
import {
|
||||
debounceTime,
|
||||
distinctUntilChanged,
|
||||
filter,
|
||||
find,
|
||||
map,
|
||||
mergeMap,
|
||||
startWith
|
||||
} from 'rxjs/operators';
|
||||
import { debounceTime, distinctUntilChanged, filter, map, startWith } from 'rxjs/operators';
|
||||
|
||||
import { Collection } from '../../../core/shared/collection.model';
|
||||
import { CommunityDataService } from '../../../core/data/community-data.service';
|
||||
@@ -32,12 +24,12 @@ import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { SubmissionService } from '../../submission.service';
|
||||
import { SubmissionObject } from '../../../core/submission/models/submission-object.model';
|
||||
import { SubmissionJsonPatchOperationsService } from '../../../core/submission/submission-json-patch-operations.service';
|
||||
import { SearchService } from '../../../+search-page/search-service/search.service';
|
||||
import { PaginatedSearchOptions } from '../../../+search-page/paginated-search-options.model';
|
||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||
import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model';
|
||||
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { SearchResult } from '../../../+search-page/search-result.model';
|
||||
import { SearchService } from '../../../core/shared/search/search.service';
|
||||
import { PaginatedSearchOptions } from '../../../shared/search/paginated-search-options.model';
|
||||
import { SearchResult } from '../../../shared/search/search-result.model';
|
||||
|
||||
/**
|
||||
* An interface to represent a collection entry
|
||||
|
Reference in New Issue
Block a user