Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,12 @@
[routerLink]="[itemPageRoute]">
<i class="fa fa-info-circle"></i> {{"submission.workflow.generic.view" | translate}}
</button>

<button class="btn btn-outline-primary mt-1 mb-3 ml-1"
*ngIf="canCreateVersion$ | async"
[dsBtnDisabled]="disableNewVersion$ | async"
[ngbTooltip]="(newVersionTooltip$ | async) | translate"
[attr.aria-label]="(newVersionTooltip$ | async) | translate"
(click)="openCreateVersionModal()">
<i class="fas fa-code-branch"></i> {{ 'item.page.version.create' | translate }}
</button>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChangeDetectionStrategy, Injector, NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Router } from '@angular/router';

import { of as observableOf } from 'rxjs';
Expand All @@ -16,6 +17,8 @@ import { RequestService } from '../../../core/data/request.service';
import { getMockSearchService } from '../../mocks/search-service.mock';
import { getMockRequestService } from '../../mocks/request.service.mock';
import { SearchService } from '../../../core/shared/search/search.service';
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
import { DsoVersioningModalService } from '../../dso-page/dso-versioning-modal-service/dso-versioning-modal.service';

let component: ItemActionsComponent;
let fixture: ComponentFixture<ItemActionsComponent>;
Expand All @@ -24,7 +27,25 @@ let mockObject: Item;

const mockDataService = {};

const authorizationService = jasmine.createSpyObj('authorizationService', {
isAuthorized: observableOf(true),
});

const dsoVersioningModalService = jasmine.createSpyObj('dsoVersioningModalService', {
isNewVersionButtonDisabled: observableOf(false),
getVersioningTooltipMessage: observableOf('item.page.version.create'),
openCreateVersionModal: undefined,
});

mockObject = Object.assign(new Item(), {
_links: {
self: {
href: 'https://rest.test/server/api/core/items/item-id'
},
version: {
href: 'https://rest.test/server/api/core/versions/1'
}
},
bundles: observableOf({}),
metadata: {
'dc.title': [
Expand Down Expand Up @@ -76,7 +97,9 @@ describe('ItemActionsComponent', () => {
{ provide: ItemDataService, useValue: mockDataService },
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
{ provide: SearchService, useValue: searchService },
{ provide: RequestService, useValue: requestServce }
{ provide: RequestService, useValue: requestServce },
{ provide: AuthorizationDataService, useValue: authorizationService },
{ provide: DsoVersioningModalService, useValue: dsoVersioningModalService }
],
schemas: [NO_ERRORS_SCHEMA]
}).overrideComponent(ItemActionsComponent, {
Expand All @@ -85,6 +108,14 @@ describe('ItemActionsComponent', () => {
}));

beforeEach(() => {
authorizationService.isAuthorized.calls.reset();
authorizationService.isAuthorized.and.returnValue(observableOf(true));
dsoVersioningModalService.isNewVersionButtonDisabled.calls.reset();
dsoVersioningModalService.isNewVersionButtonDisabled.and.returnValue(observableOf(false));
dsoVersioningModalService.getVersioningTooltipMessage.calls.reset();
dsoVersioningModalService.getVersioningTooltipMessage.and.returnValue(observableOf('item.page.version.create'));
dsoVersioningModalService.openCreateVersionModal.calls.reset();

fixture = TestBed.createComponent(ItemActionsComponent);
component = fixture.componentInstance;
component.object = mockObject;
Expand All @@ -103,4 +134,70 @@ describe('ItemActionsComponent', () => {
expect(component.object).toEqual(mockObject);
});

it('should show the New version button when version creation is authorized', () => {
fixture.detectChanges();

const newVersionButton = fixture.debugElement.query(By.css('button.btn-outline-primary'));

expect(newVersionButton).toBeTruthy();
});

it('should hide the New version button when version creation is not authorized', () => {
authorizationService.isAuthorized.and.returnValue(observableOf(false));

fixture = TestBed.createComponent(ItemActionsComponent);
component = fixture.componentInstance;
component.object = mockObject;
fixture.detectChanges();

const newVersionButton = fixture.debugElement.query(By.css('button.btn-outline-primary'));

expect(newVersionButton).toBeNull();
});

it('should mark the New version button as disabled when version creation is disabled', () => {
dsoVersioningModalService.isNewVersionButtonDisabled.and.returnValue(observableOf(true));

fixture = TestBed.createComponent(ItemActionsComponent);
component = fixture.componentInstance;
component.object = mockObject;
fixture.detectChanges();

let isDisabled: boolean;
component.disableNewVersion$.subscribe((value) => {
isDisabled = value;
});

expect(isDisabled).toBeTrue();
});

it('should use getVersioningTooltipMessage to derive tooltip key', () => {
dsoVersioningModalService.isNewVersionButtonDisabled.and.returnValue(observableOf(true));
dsoVersioningModalService.getVersioningTooltipMessage.and.returnValue(observableOf('item.page.version.hasDraft'));

fixture = TestBed.createComponent(ItemActionsComponent);
component = fixture.componentInstance;
component.object = mockObject;
fixture.detectChanges();

let tooltipKey: string;
component.newVersionTooltip$.subscribe((value) => {
tooltipKey = value;
});

expect(tooltipKey).toBe('item.page.version.hasDraft');
expect(dsoVersioningModalService.getVersioningTooltipMessage)
.toHaveBeenCalledWith(mockObject, 'item.page.version.hasDraft', 'item.page.version.create');
});

it('should open the create version modal when the New version button is clicked', () => {
fixture.detectChanges();

const newVersionButton = fixture.debugElement.query(By.css('button.btn-outline-primary'));

newVersionButton.triggerEventHandler('click');
Comment thread
milanmajchrak marked this conversation as resolved.

expect(dsoVersioningModalService.openCreateVersionModal).toHaveBeenCalledWith(mockObject);
});

});
58 changes: 57 additions & 1 deletion src/app/shared/mydspace-actions/item/item-actions.component.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { Component, Injector, Input, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Observable, of as observableOf } from 'rxjs';
import { shareReplay } from 'rxjs/operators';
import { MyDSpaceActionsComponent } from '../mydspace-actions';
import { ItemDataService } from '../../../core/data/item-data.service';
import { Item } from '../../../core/shared/item.model';
import { NotificationsService } from '../../notifications/notifications.service';
import { RequestService } from '../../../core/data/request.service';
import { SearchService } from '../../../core/shared/search/search.service';
import { getItemPageRoute } from '../../../item-page/item-page-routing-paths';
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
import { DsoVersioningModalService } from '../../dso-page/dso-versioning-modal-service/dso-versioning-modal.service';
import { hasValue } from '../../empty.util';

/**
* This component represents mydspace actions related to Item object.
Expand All @@ -30,6 +36,21 @@ export class ItemActionsComponent extends MyDSpaceActionsComponent<Item, ItemDat
*/
itemPageRoute: string;

/**
* Whether the current user can create a new version for this item.
*/
canCreateVersion$: Observable<boolean>;

/**
* Whether the New version button should be disabled.
*/
disableNewVersion$: Observable<boolean>;

/**
* Tooltip key for the New version button.
*/
newVersionTooltip$: Observable<string>;

/**
* Initialize instance variables
*
Expand All @@ -45,12 +66,15 @@ export class ItemActionsComponent extends MyDSpaceActionsComponent<Item, ItemDat
protected notificationsService: NotificationsService,
protected translate: TranslateService,
protected searchService: SearchService,
protected requestService: RequestService) {
protected requestService: RequestService,
protected authorizationService: AuthorizationDataService,
protected dsoVersioningModalService: DsoVersioningModalService) {
super(Item.type, injector, router, notificationsService, translate, searchService, requestService);
}

ngOnInit(): void {
this.initPageRoute();
this.initVersioningControls();
}

/**
Expand All @@ -61,6 +85,7 @@ export class ItemActionsComponent extends MyDSpaceActionsComponent<Item, ItemDat
initObjects(object: Item) {
this.object = object;
this.initPageRoute();
this.initVersioningControls();
}

/**
Expand All @@ -70,4 +95,35 @@ export class ItemActionsComponent extends MyDSpaceActionsComponent<Item, ItemDat
this.itemPageRoute = getItemPageRoute(this.object);
}

/**
* Initialize authorization and button state for version creation.
*/
initVersioningControls(): void {
this.canCreateVersion$ = observableOf(false);
this.disableNewVersion$ = observableOf(false);
this.newVersionTooltip$ = observableOf('item.page.version.create');

if (!hasValue(this.object?.self) || !hasValue(this.object?._links?.version?.href)) {
return;
}

this.canCreateVersion$ = this.authorizationService.isAuthorized(
FeatureID.CanCreateVersion,
this.object.self,
Comment thread
milanmajchrak marked this conversation as resolved.
);
this.disableNewVersion$ = this.dsoVersioningModalService.isNewVersionButtonDisabled(this.object).pipe(shareReplay(1));
this.newVersionTooltip$ = this.dsoVersioningModalService.getVersioningTooltipMessage(
this.object,
'item.page.version.hasDraft',
'item.page.version.create',
);
Comment thread
milanmajchrak marked this conversation as resolved.
}

/**
* Open the existing Create version modal for the current item.
*/
openCreateVersionModal(): void {
this.dsoVersioningModalService.openCreateVersionModal(this.object);
}

}
Loading