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