98376: Added rating button to ratingreviewaction claimed task and created page

This commit is contained in:
Alexandre Vryghem
2023-01-10 18:59:06 +01:00
parent ef9373baec
commit 7cee2aac6f
16 changed files with 220 additions and 66 deletions

View File

@@ -105,6 +105,7 @@
"ng-mocks": "11.11.2",
"ng2-file-upload": "1.4.0",
"ng2-nouislider": "^1.8.3",
"ngx-bootstrap": "7.1.2",
"ngx-infinite-scroll": "^10.0.1",
"ngx-moment": "^5.0.0",
"ngx-pagination": "5.0.0",

View File

@@ -1,4 +1,4 @@
<button (click)="openAdvancedClaimedTaskTab()" class="ratingReviewerAction btn btn-primary"
ngbTooltip="{{ 'submission.workflow.generic.' + option + '-help' | translate }}">
<i class="fa fa-user"></i> {{ 'submission.workflow.generic.' + option | translate}}
<i class="fa fa-star-half-alt"></i> {{ 'submission.workflow.generic.' + option | translate}}
</button>

View File

@@ -1,7 +1,5 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {
AdvancedClaimedTaskActionRatingReviewerComponent
} from './advanced-claimed-task-action-rating-reviewer.component';
import { AdvancedClaimedTaskActionRatingComponent } from './advanced-claimed-task-action-rating.component';
import { By } from '@angular/platform-browser';
import { ClaimedTask } from '../../../../core/tasks/models/claimed-task-object.model';
import { ClaimedTaskDataServiceStub } from '../../../testing/claimed-task-data-service.stub';
@@ -17,23 +15,23 @@ import { Location } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
ADVANCED_WORKFLOW_ACTION_RATING_REVIEWER
} from '../../../../workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-rating-reviewer/advanced-workflow-action-rating-reviewer.component';
ADVANCED_WORKFLOW_ACTION_RATING
} from '../../../../workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-rating/advanced-workflow-action-rating.component';
import { of as observableOf } from 'rxjs';
import { WorkflowItem } from '../../../../core/submission/models/workflowitem.model';
const taskId = 'claimed-task-1';
const workflowId = 'workflow-1';
describe('AdvancedClaimedTaskActionRatingReviewerComponent', () => {
describe('AdvancedClaimedTaskActionRatingComponent', () => {
const object = Object.assign(new ClaimedTask(), {
id: taskId,
workflowitem: observableOf(Object.assign(new WorkflowItem(), {
id: workflowId,
})),
});
let component: AdvancedClaimedTaskActionRatingReviewerComponent;
let fixture: ComponentFixture<AdvancedClaimedTaskActionRatingReviewerComponent>;
let component: AdvancedClaimedTaskActionRatingComponent;
let fixture: ComponentFixture<AdvancedClaimedTaskActionRatingComponent>;
let claimedTaskDataService: ClaimedTaskDataServiceStub;
let notificationService: NotificationsServiceStub;
@@ -51,7 +49,7 @@ describe('AdvancedClaimedTaskActionRatingReviewerComponent', () => {
TranslateModule.forRoot(),
],
declarations: [
AdvancedClaimedTaskActionRatingReviewerComponent,
AdvancedClaimedTaskActionRatingComponent,
],
providers: [
{ provide: ClaimedTaskDataService, useValue: claimedTaskDataService },
@@ -66,7 +64,7 @@ describe('AdvancedClaimedTaskActionRatingReviewerComponent', () => {
});
beforeEach(() => {
fixture = TestBed.createComponent(AdvancedClaimedTaskActionRatingReviewerComponent);
fixture = TestBed.createComponent(AdvancedClaimedTaskActionRatingComponent);
component = fixture.componentInstance;
component.object = object;
fixture.detectChanges();
@@ -88,7 +86,7 @@ describe('AdvancedClaimedTaskActionRatingReviewerComponent', () => {
expect(router.navigate).toHaveBeenCalledWith([`/workflowitems/${workflowId}/advanced`], {
queryParams: {
workflow: ADVANCED_WORKFLOW_ACTION_RATING_REVIEWER,
workflow: ADVANCED_WORKFLOW_ACTION_RATING,
claimedTask: taskId,
},
});

View File

@@ -8,24 +8,25 @@ import {
AdvancedClaimedTaskActionsAbstractComponent
} from '../abstract/advanced-claimed-task-actions-abstract.component';
import {
ADVANCED_WORKFLOW_ACTION_RATING_REVIEWER
} from '../../../../workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-rating-reviewer/advanced-workflow-action-rating-reviewer.component';
export const WORKFLOW_ADVANCED_TASK_OPTION_RATING_REVIEWER = 'submit_rating_reviewer';
ADVANCED_WORKFLOW_ACTION_RATING,
WORKFLOW_ADVANCED_TASK_OPTION_RATING,
} from '../../../../workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-rating/advanced-workflow-action-rating.component';
import { rendersWorkflowTaskOption } from '../switcher/claimed-task-actions-decorator';
@rendersWorkflowTaskOption(WORKFLOW_ADVANCED_TASK_OPTION_RATING)
@Component({
selector: 'ds-advanced-claimed-task-action-rating-reviewer',
templateUrl: './advanced-claimed-task-action-rating-reviewer.component.html',
styleUrls: ['./advanced-claimed-task-action-rating-reviewer.component.scss']
templateUrl: './advanced-claimed-task-action-rating.component.html',
styleUrls: ['./advanced-claimed-task-action-rating.component.scss']
})
export class AdvancedClaimedTaskActionRatingReviewerComponent extends AdvancedClaimedTaskActionsAbstractComponent {
export class AdvancedClaimedTaskActionRatingComponent extends AdvancedClaimedTaskActionsAbstractComponent {
/**
* This component represents the advanced select option
*/
option = WORKFLOW_ADVANCED_TASK_OPTION_RATING_REVIEWER;
option = WORKFLOW_ADVANCED_TASK_OPTION_RATING;
workflowType = ADVANCED_WORKFLOW_ACTION_RATING_REVIEWER;
workflowType = ADVANCED_WORKFLOW_ACTION_RATING;
constructor(
protected injector: Injector,

View File

@@ -179,8 +179,8 @@ import { DsSelectComponent } from './ds-select/ds-select.component';
import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component';
import { AdvancedClaimedTaskActionSelectReviewerComponent } from './mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component';
import {
AdvancedClaimedTaskActionRatingReviewerComponent
} from './mydspace-actions/claimed-task/rating-reviewer/advanced-claimed-task-action-rating-reviewer.component';
AdvancedClaimedTaskActionRatingComponent
} from './mydspace-actions/claimed-task/rating/advanced-claimed-task-action-rating.component';
import { ClaimedTaskActionsDeclineTaskComponent } from './mydspace-actions/claimed-task/decline-task/claimed-task-actions-decline-task.component';
const MODULES = [
@@ -353,7 +353,7 @@ const COMPONENTS = [
SearchNavbarComponent,
ScopeSelectorModalComponent,
AdvancedClaimedTaskActionSelectReviewerComponent,
AdvancedClaimedTaskActionRatingReviewerComponent,
AdvancedClaimedTaskActionRatingComponent,
];
const ENTRY_COMPONENTS = [
@@ -412,7 +412,7 @@ const ENTRY_COMPONENTS = [
TextMenuItemComponent,
ScopeSelectorModalComponent,
AdvancedClaimedTaskActionSelectReviewerComponent,
AdvancedClaimedTaskActionRatingReviewerComponent,
AdvancedClaimedTaskActionRatingComponent,
];
const SHARED_ITEM_PAGE_COMPONENTS = [

View File

@@ -1,15 +0,0 @@
import { Component } from '@angular/core';
import {
rendersAdvancedWorkflowTaskOption
} from '../../../shared/mydspace-actions/claimed-task/switcher/claimed-task-actions-decorator';
export const ADVANCED_WORKFLOW_ACTION_RATING_REVIEWER = 'ratingrevieweraction';
@rendersAdvancedWorkflowTaskOption(ADVANCED_WORKFLOW_ACTION_RATING_REVIEWER)
@Component({
selector: 'ds-advanced-workflow-action-rating-reviewer',
templateUrl: './advanced-workflow-action-rating-reviewer.component.html',
styleUrls: ['./advanced-workflow-action-rating-reviewer.component.scss']
})
export class AdvancedWorkflowActionRatingReviewerComponent {
}

View File

@@ -0,0 +1,44 @@
<div *ngVar="getAdvancedInfo(workflowAction$ | async) as advancedInfo">
<p *ngIf="advancedInfo?.descriptionRequired">
{{ 'advanced-workflow-action.rating.description-requiredDescription' | translate }}
</p>
<p *ngIf="!advancedInfo?.descriptionRequired">
{{ 'advanced-workflow-action.rating.description' | translate }}
</p>
<form (ngSubmit)="performAction()" *ngIf="ratingForm" [formGroup]="ratingForm">
<div *ngVar="ratingForm.get('review').touched && !ratingForm.get('review').valid as invalid" class="form-group">
<label class="control-label">
<span>{{ 'advanced-workflow-action.rating.form.review.label' | translate }}</span>
<span *ngIf="advancedInfo?.descriptionRequired">*</span>
</label>
<textarea [ngClass]="invalid ? 'is-invalid' : ''" [required]="advancedInfo?.descriptionRequired"
class="form-control" formControlName="review">
</textarea>
<small *ngIf="invalid" class="invalid-feedback d-block">
{{ 'advanced-workflow-action.rating.form.review.error' | translate }}
</small>
</div>
<div class="form-group">
<label class="control-label">
{{ 'advanced-workflow-action.rating.form.rating.label' | translate }}*
</label>
<rating [max]="advancedInfo?.maxValue" class="d-block" formControlName="rating">
</rating>
</div>
</form>
<ds-modify-item-overview *ngIf="item$ | async"
[item]="item$ | async">
</ds-modify-item-overview>
<div class="d-flex flex-wrap justify-content-end">
<button (click)="previousPage()" class="btn btn-default">
{{'workflow-item.' + getType() + '.button.cancel' | translate}}
</button>
<button (click)="performAction()" class="btn btn-primary">
{{'workflow-item.' + getType() + '.button.confirm' | translate}}
</button>
</div>
</div>

View File

@@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AdvancedWorkflowActionRatingReviewerComponent } from './advanced-workflow-action-rating-reviewer.component';
import { ActivatedRoute, convertToParamMap } from '@angular/router';
import { AdvancedWorkflowActionRatingComponent } from './advanced-workflow-action-rating.component';
import { ActivatedRoute, convertToParamMap, Router } from '@angular/router';
import { of as observableOf } from 'rxjs';
import { ClaimedTaskDataService } from '../../../core/tasks/claimed-task-data.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
@@ -12,12 +12,17 @@ import { ClaimedTaskDataServiceStub } from '../../../shared/testing/claimed-task
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
import { WorkflowActionDataServiceStub } from '../../../shared/testing/workflow-action-data-service.stub';
import { WorkflowItemDataServiceStub } from '../../../shared/testing/workflow-item-data-service.stub';
import { RouterStub } from '../../../shared/testing/router.stub';
import { TranslateModule } from '@ngx-translate/core';
import { VarDirective } from '../../../shared/utils/var.directive';
import { RatingModule } from 'ngx-bootstrap/rating';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
const workflowId = '1';
describe('AdvancedWorkflowActionRatingReviewerComponent', () => {
let component: AdvancedWorkflowActionRatingReviewerComponent;
let fixture: ComponentFixture<AdvancedWorkflowActionRatingReviewerComponent>;
describe('AdvancedWorkflowActionRatingComponent', () => {
let component: AdvancedWorkflowActionRatingComponent;
let fixture: ComponentFixture<AdvancedWorkflowActionRatingComponent>;
let claimedTaskDataService: ClaimedTaskDataServiceStub;
let notificationService: NotificationsServiceStub;
@@ -31,8 +36,15 @@ describe('AdvancedWorkflowActionRatingReviewerComponent', () => {
workflowItemDataService = new WorkflowItemDataServiceStub();
await TestBed.configureTestingModule({
imports: [
FormsModule,
RatingModule,
ReactiveFormsModule,
TranslateModule.forRoot(),
],
declarations: [
AdvancedWorkflowActionRatingReviewerComponent,
AdvancedWorkflowActionRatingComponent,
VarDirective,
],
providers: [
{
@@ -51,6 +63,7 @@ describe('AdvancedWorkflowActionRatingReviewerComponent', () => {
{ provide: ClaimedTaskDataService, useValue: claimedTaskDataService },
{ provide: NotificationsService, useValue: notificationService },
{ provide: RouteService, useValue: routeServiceStub },
{ provide: Router, useValue: new RouterStub() },
{ provide: WorkflowActionDataService, useValue: workflowActionDataService },
{ provide: WorkflowItemDataService, useValue: workflowItemDataService },
],
@@ -58,11 +71,15 @@ describe('AdvancedWorkflowActionRatingReviewerComponent', () => {
});
beforeEach(() => {
fixture = TestBed.createComponent(AdvancedWorkflowActionRatingReviewerComponent);
fixture = TestBed.createComponent(AdvancedWorkflowActionRatingComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
afterEach(() => {
fixture.debugElement.nativeElement.remove();
});
it('should create', () => {
expect(component).toBeTruthy();
});

View File

@@ -0,0 +1,66 @@
import { Component, OnInit } from '@angular/core';
import {
rendersAdvancedWorkflowTaskOption
} from '../../../shared/mydspace-actions/claimed-task/switcher/claimed-task-actions-decorator';
import { AdvancedWorkflowActionComponent } from '../advanced-workflow-action/advanced-workflow-action.component';
import { FormGroup, FormControl } from '@angular/forms';
import { WorkflowAction } from '../../../core/tasks/models/workflow-action-object.model';
import {
RatingReviewerActionAdvancedInfo
} from '../../../core/tasks/models/rating-reviewer-action-advanced-info.model';
export const WORKFLOW_ADVANCED_TASK_OPTION_RATING = 'rating';
export const ADVANCED_WORKFLOW_ACTION_RATING = 'ratingreviewaction';
@rendersAdvancedWorkflowTaskOption(ADVANCED_WORKFLOW_ACTION_RATING)
@Component({
selector: 'ds-advanced-workflow-action-rating-reviewer',
templateUrl: './advanced-workflow-action-rating.component.html',
styleUrls: ['./advanced-workflow-action-rating.component.scss'],
preserveWhitespaces: false,
})
export class AdvancedWorkflowActionRatingComponent extends AdvancedWorkflowActionComponent implements OnInit {
ratingForm: FormGroup;
ngOnInit() {
super.ngOnInit();
this.ratingForm = new FormGroup({
review: new FormControl(''),
rating: new FormControl(0),
});
}
/**
* Only run **performAction()** when the form has been correctly filled in
*/
performAction(): void {
this.ratingForm.updateValueAndValidity();
if (this.ratingForm.valid) {
super.performAction();
} else {
this.ratingForm.markAllAsTouched();
}
}
createBody(): any {
const body = {
[WORKFLOW_ADVANCED_TASK_OPTION_RATING]: true,
score: this.ratingForm.get('rating').value,
};
if (this.ratingForm.get('review').value !== '') {
const description: string = this.ratingForm.get('review').value;
Object.assign(body, { description });
}
return body;
}
getType(): string {
return ADVANCED_WORKFLOW_ACTION_RATING;
}
getAdvancedInfo(workflowAction: WorkflowAction | null): RatingReviewerActionAdvancedInfo | null {
return workflowAction ? (workflowAction.advancedInfo[0] as RatingReviewerActionAdvancedInfo) : null;
}
}

View File

@@ -44,7 +44,7 @@ export abstract class AdvancedWorkflowActionComponent extends WorkflowItemAction
/**
* Performs the action and shows a notification based on the outcome of the action
*/
performAction() {
performAction(): void {
this.sendRequest(this.route.snapshot.queryParams.claimedTask).subscribe((successful: boolean) => {
if (successful) {
const title = this.translationService.get('workflow-item.' + this.type + '.notification.success.title');

View File

@@ -6,15 +6,23 @@ import { SubmissionModule } from '../submission/submission.module';
import { WorkflowItemDeleteComponent } from './workflow-item-delete/workflow-item-delete.component';
import { WorkflowItemSendBackComponent } from './workflow-item-send-back/workflow-item-send-back.component';
import { ThemedWorkflowItemDeleteComponent } from './workflow-item-delete/themed-workflow-item-delete.component';
import { ThemedWorkflowItemSendBackComponent } from './workflow-item-send-back/themed-workflow-item-send-back.component';
import {
ThemedWorkflowItemSendBackComponent
} from './workflow-item-send-back/themed-workflow-item-send-back.component';
import { StatisticsModule } from '../statistics/statistics.module';
import { ItemPageModule } from '../item-page/item-page.module';
import {
AdvancedWorkflowActionsLoaderComponent
} from './advanced-workflow-action/advanced-workflow-actions-loader/advanced-workflow-actions-loader.component';
import { AdvancedWorkflowActionRatingReviewerComponent } from './advanced-workflow-action/advanced-workflow-action-rating-reviewer/advanced-workflow-action-rating-reviewer.component';
import { AdvancedWorkflowActionSelectReviewerComponent } from './advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component';
import { AdvancedWorkflowActionPageComponent } from './advanced-workflow-action/advanced-workflow-action-page/advanced-workflow-action-page.component';
import {
AdvancedWorkflowActionRatingComponent
} from './advanced-workflow-action/advanced-workflow-action-rating/advanced-workflow-action-rating.component';
import {
AdvancedWorkflowActionSelectReviewerComponent
} from './advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component';
import {
AdvancedWorkflowActionPageComponent
} from './advanced-workflow-action/advanced-workflow-action-page/advanced-workflow-action-page.component';
import {
AdvancedClaimedTaskActionsDirective
} from './advanced-workflow-action/advanced-workflow-actions-loader/advanced-claimed-task-actions.directive';
@@ -22,6 +30,8 @@ import { AccessControlModule } from '../access-control/access-control.module';
import {
ReviewersListComponent
} from './advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component';
import { FormModule } from '../shared/form/form.module';
import { RatingModule } from 'ngx-bootstrap/rating';
@NgModule({
imports: [
@@ -31,7 +41,9 @@ import {
SubmissionModule,
StatisticsModule,
ItemPageModule,
AccessControlModule
AccessControlModule,
FormModule,
RatingModule,
],
declarations: [
WorkflowItemDeleteComponent,
@@ -39,7 +51,7 @@ import {
WorkflowItemSendBackComponent,
ThemedWorkflowItemSendBackComponent,
AdvancedWorkflowActionsLoaderComponent,
AdvancedWorkflowActionRatingReviewerComponent,
AdvancedWorkflowActionRatingComponent,
AdvancedWorkflowActionSelectReviewerComponent,
AdvancedWorkflowActionPageComponent,
AdvancedClaimedTaskActionsDirective,

View File

@@ -539,6 +539,17 @@
"admin.metadata-import.page.error.addFile": "Select file first!",
"advanced-workflow-action.rating.form.rating.label": "Rating",
"advanced-workflow-action.rating.form.review.label": "Review",
"advanced-workflow-action.rating.form.review.error": "You must enter a review to submit this rating",
"advanced-workflow-action.rating.description": "Please select a rating below",
"advanced-workflow-action.rating.description-requiredDescription": "Please select a rating below and also add a review",
"advanced-workflow-action.select-reviewer.description-single": "Please select a single reviewer below before submitting",
"advanced-workflow-action.select-reviewer.description-multiple": "Please select one or more reviewers below before submitting",
@@ -4061,9 +4072,9 @@
"submission.workflow.generic.submit_select_reviewer-help": "",
"submission.workflow.generic.submit_rating_reviewer": "Rating Reviewer",
"submission.workflow.generic.rating": "Rate",
"submission.workflow.generic.submit_rating_reviewer-help": "",
"submission.workflow.generic.rating-help": "",
"submission.workflow.tasks.claimed.approve": "Approve",
@@ -4241,8 +4252,21 @@
"workflow-item.selectrevieweraction.button.confirm": "Confirm",
"workflow-item.ratingrevieweraction.header": "Rating Reviewer",
"workflow-item.ratingreviewaction.notification.success.title": "Rating review",
"workflow-item.ratingreviewaction.notification.success.content": "The rating for this item workflow item has been successfully submitted",
"workflow-item.ratingreviewaction.notification.error.title": "Something went wrong",
"workflow-item.ratingreviewaction.notification.error.content": "Couldn't rate this item",
"workflow-item.ratingreviewaction.title": "Rate this item",
"workflow-item.ratingreviewaction.header": "Rate this item",
"workflow-item.ratingreviewaction.button.cancel": "Cancel",
"workflow-item.ratingreviewaction.button.confirm": "Confirm",
"idle-modal.header": "Session will expire soon",

View File

@@ -9357,6 +9357,13 @@ ng2-nouislider@^1.8.3:
resolved "https://registry.yarnpkg.com/ng2-nouislider/-/ng2-nouislider-1.8.3.tgz#c9c1ec77b6b5a909f87368ba799914208baa13a6"
integrity sha512-Vl8tHCcJ/ioJLAs2t6FBC35sZq1P/O5ZdqdFwYxOCOMVbILGWNg+2gWZIjFstvv9pqb/mVvVUYe6qGG/mA/RBQ==
ngx-bootstrap@7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/ngx-bootstrap/-/ngx-bootstrap-7.1.2.tgz#cf06a05cc22a74b882b45882a1f64f72ddece23d"
integrity sha512-VsZwlGVM+qYOAdvEzzH3wqCjvj3yHec4n82Tho0ve6mhN1GTRu9WPrPmvxp3cFjIu8VQbREUeKPfK0ooO8U5eg==
dependencies:
tslib "^2.0.0"
ngx-infinite-scroll@^10.0.1:
version "10.0.1"
resolved "https://registry.yarnpkg.com/ngx-infinite-scroll/-/ngx-infinite-scroll-10.0.1.tgz#6f51f2f8775a7c50d1dd8bad125d4e748abbe880"