mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-12 04:23:04 +00:00
108555: Refactored ItemSelectComponent to not call canSelect every time changes are detected
This commit is contained in:
@@ -17,17 +17,17 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let item of itemsRD?.payload?.page">
|
||||
<td><input [disabled]="!(canSelect(item) | async)" class="item-checkbox" [ngModel]="getSelected(item.id) | async" (change)="switch(item.id)" type="checkbox" name="{{item.id}}"></td>
|
||||
<tr *ngFor="let selectItem of selectItems$ | async">
|
||||
<td><input [disabled]="(selectItem.canSelect$ | async) === false" class="item-checkbox" [ngModel]="selectItem.selected$ | async" (change)="switch(selectItem.dso.id)" type="checkbox" name="{{selectItem.dso.id}}"></td>
|
||||
<td *ngIf="!hideCollection">
|
||||
<span *ngVar="(item.owningCollection | async)?.payload as collection">
|
||||
<span *ngVar="(selectItem.dso.owningCollection | async)?.payload as collection">
|
||||
<a *ngIf="collection" [routerLink]="['/collections', collection?.id]">
|
||||
{{ dsoNameService.getName(collection) }}
|
||||
</a>
|
||||
</span>
|
||||
</td>
|
||||
<td><span *ngIf="item.hasMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*'])">{{item.firstMetadataValue(['dc.contributor.author', 'dc.creator', 'dc.contributor.*'])}}</span></td>
|
||||
<td><a [routerLink]="[(itemPageRoutes$ | async)[item.id]]">{{ dsoNameService.getName(item) }}</a></td>
|
||||
<td><span *ngIf="selectItem.dso.hasMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*'])">{{selectItem.dso.firstMetadataValue(['dc.contributor.author', 'dc.creator', 'dc.contributor.*'])}}</span></td>
|
||||
<td><a [routerLink]="selectItem.route">{{ dsoNameService.getName(selectItem.dso) }}</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -184,15 +184,16 @@ describe('ItemSelectComponent', () => {
|
||||
beforeEach(() => {
|
||||
comp.featureId = FeatureID.CanManageMappings;
|
||||
spyOn(authorizationDataService, 'isAuthorized').and.returnValue(of(false));
|
||||
comp.ngOnInit();
|
||||
});
|
||||
|
||||
it('should disable the checkbox', waitForAsync(() => {
|
||||
it('should disable the checkbox', waitForAsync(async () => {
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
const checkbox = fixture.debugElement.query(By.css('input.item-checkbox')).nativeElement;
|
||||
expect(authorizationDataService.isAuthorized).toHaveBeenCalled();
|
||||
expect(checkbox.disabled).toBeTrue();
|
||||
});
|
||||
await fixture.whenStable();
|
||||
|
||||
const checkbox = fixture.debugElement.query(By.css('input.item-checkbox')).nativeElement;
|
||||
expect(authorizationDataService.isAuthorized).toHaveBeenCalled();
|
||||
expect(checkbox.disabled).toBeTrue();
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
@@ -1,14 +1,13 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { ObjectSelectService } from '../object-select.service';
|
||||
import { ObjectSelectComponent } from '../object-select/object-select.component';
|
||||
import { hasValueOperator, isNotEmpty } from '../../empty.util';
|
||||
import { Observable } from 'rxjs';
|
||||
import { getAllSucceededRemoteDataPayload } from '../../../core/shared/operators';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { getItemPageRoute } from '../../../item-page/item-page-routing-paths';
|
||||
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { DSpaceObjectSelect } from '../object-select.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-select',
|
||||
@@ -18,7 +17,7 @@ import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
||||
/**
|
||||
* A component used to select items from a specific list and returning the UUIDs of the selected items
|
||||
*/
|
||||
export class ItemSelectComponent extends ObjectSelectComponent<Item> {
|
||||
export class ItemSelectComponent extends ObjectSelectComponent<Item> implements OnInit {
|
||||
|
||||
/**
|
||||
* Whether or not to hide the collection column
|
||||
@@ -27,35 +26,25 @@ export class ItemSelectComponent extends ObjectSelectComponent<Item> {
|
||||
hideCollection = false;
|
||||
|
||||
/**
|
||||
* The routes to the items their pages
|
||||
* Key: Item ID
|
||||
* Value: Route to item page
|
||||
* Collection of all the data that is used to display the {@link Item} in the HTML.
|
||||
* By collecting this data here it doesn't need to be recalculated on evey change detection.
|
||||
*/
|
||||
itemPageRoutes$: Observable<{
|
||||
[itemId: string]: string
|
||||
}>;
|
||||
|
||||
constructor(
|
||||
protected objectSelectService: ObjectSelectService,
|
||||
protected authorizationService: AuthorizationDataService,
|
||||
public dsoNameService: DSONameService,
|
||||
) {
|
||||
super(objectSelectService, authorizationService);
|
||||
}
|
||||
selectItems$: Observable<DSpaceObjectSelect<Item>[]>;
|
||||
|
||||
ngOnInit(): void {
|
||||
super.ngOnInit();
|
||||
if (!isNotEmpty(this.confirmButton)) {
|
||||
this.confirmButton = 'item.select.confirm';
|
||||
}
|
||||
this.itemPageRoutes$ = this.dsoRD$.pipe(
|
||||
this.selectItems$ = this.dsoRD$.pipe(
|
||||
hasValueOperator(),
|
||||
getAllSucceededRemoteDataPayload(),
|
||||
map((items) => {
|
||||
const itemPageRoutes = {};
|
||||
items.page.forEach((item) => itemPageRoutes[item.uuid] = getItemPageRoute(item));
|
||||
return itemPageRoutes;
|
||||
})
|
||||
map((items: PaginatedList<Item>) => items.page.map((item: Item) => Object.assign(new DSpaceObjectSelect<Item>(), {
|
||||
dso: item,
|
||||
canSelect$: this.canSelect(item),
|
||||
selected$: this.getSelected(item.id),
|
||||
route: getItemPageRoute(item),
|
||||
} as DSpaceObjectSelect<Item>))),
|
||||
);
|
||||
}
|
||||
|
||||
|
29
src/app/shared/object-select/object-select.model.ts
Normal file
29
src/app/shared/object-select/object-select.model.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||
|
||||
/**
|
||||
* Class used to collect all the data that that is used by the {@link ObjectSelectComponent} in the HTML.
|
||||
*/
|
||||
export class DSpaceObjectSelect<T extends DSpaceObject> {
|
||||
|
||||
/**
|
||||
* The {@link DSpaceObject} to display
|
||||
*/
|
||||
dso: T;
|
||||
|
||||
/**
|
||||
* Whether the {@link DSpaceObject} can be selected
|
||||
*/
|
||||
canSelect$: Observable<boolean>;
|
||||
|
||||
/**
|
||||
* Whether the {@link DSpaceObject} is selected
|
||||
*/
|
||||
selected$: Observable<boolean>;
|
||||
|
||||
/**
|
||||
* The {@link DSpaceObject}'s route
|
||||
*/
|
||||
route: string;
|
||||
|
||||
}
|
@@ -9,6 +9,7 @@ import { SortOptions } from '../../../core/cache/models/sort-options.model';
|
||||
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
|
||||
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
||||
|
||||
/**
|
||||
* An abstract component used to select DSpaceObjects from a specific list and returning the UUIDs of the selected DSpaceObjects
|
||||
@@ -17,7 +18,7 @@ import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||
selector: 'ds-object-select-abstract',
|
||||
template: ''
|
||||
})
|
||||
export abstract class ObjectSelectComponent<TDomain> implements OnInit, OnDestroy {
|
||||
export abstract class ObjectSelectComponent<TDomain extends DSpaceObject> implements OnInit, OnDestroy {
|
||||
|
||||
/**
|
||||
* A unique key used for the object select service
|
||||
@@ -88,8 +89,11 @@ export abstract class ObjectSelectComponent<TDomain> implements OnInit, OnDestro
|
||||
*/
|
||||
selectedIds$: Observable<string[]>;
|
||||
|
||||
constructor(protected objectSelectService: ObjectSelectService,
|
||||
protected authorizationService: AuthorizationDataService) {
|
||||
constructor(
|
||||
protected objectSelectService: ObjectSelectService,
|
||||
protected authorizationService: AuthorizationDataService,
|
||||
public dsoNameService: DSONameService,
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
Reference in New Issue
Block a user