Skip to content

Commit

Permalink
pkp#8887 Add review assignment views
Browse files Browse the repository at this point in the history
  • Loading branch information
Vitaliy-1 authored and ipula committed Dec 4, 2023
1 parent a3657b4 commit b76beee
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 41 deletions.
66 changes: 44 additions & 22 deletions api/v1/_submissions/PKPBackendSubmissionsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,6 @@ public function getGroupRoutes(): void

if (Config::getVar('features', 'enable_new_submission_listing')) {

Route::get('needsEditor', $this->needsEditor(...))
->name('_submission.needsEditor')
->middleware([
self::roleAuthorizer([
Role::ROLE_ID_MANAGER,
]),
]);

Route::get('assigned', $this->assigned(...))
->name('_submission.assigned')
->middleware([
Expand All @@ -116,7 +108,7 @@ public function getGroupRoutes(): void
]),
]);

Route::get('reviews', $this->assigned(...))
Route::get('reviews', $this->reviews(...))
->name('_submission.reviews')
->middleware([
self::roleAuthorizer([
Expand All @@ -127,7 +119,7 @@ public function getGroupRoutes(): void
])
]);

Route::get('viewsCount', $this->assigned(...))
Route::get('viewsCount', $this->getViewsCount(...))
->name('_submission.getViewsCount')
->middleware([
self::roleAuthorizer([
Expand All @@ -137,7 +129,7 @@ public function getGroupRoutes(): void
])
]);

Route::get('reviewAssignments', $this->assigned(...))
Route::get('reviewerAssignments', $this->getReviewAssignments(...))
->name('_submission.getReviewAssignments')
->middleware([
Role::ROLE_ID_REVIEWER,
Expand Down Expand Up @@ -271,16 +263,19 @@ public function assigned(Request $illuminateRequest): JsonResponse
/**
* Get submission undergoing the review
*/
public function reviews(SlimRequest $slimRequest, APIResponse $response, array $args)
public function reviews(Request $illuminateRequest): JsonResponse
{
$request = Application::get()->getRequest();
$context = $request->getContext();
if (!$context) {
return $response->withStatus(404)->withJsonError('api.404.resourceNotFound');
return response()->json([
'error' => __('api.404.resourceNotFound'),
], Response::HTTP_NOT_FOUND);
}
$currentUser = $request->getUser();
$queryParams = $illuminateRequest->query();

$collector = $this->getSubmissionCollector($slimRequest->getQueryParams());
$collector = $this->getSubmissionCollector($queryParams);
$collector
->filterByContextIds([$context->getId()])
->filterByStatus([PKPSubmission::STATUS_QUEUED])
Expand All @@ -292,7 +287,6 @@ public function reviews(SlimRequest $slimRequest, APIResponse $response, array $
$collector->assignedTo([$currentUser->getId()]);
}

$queryParams = $slimRequest->getQueryParams();
foreach ($queryParams as $param => $val) {
switch ($param) {
case 'needsReviewers':
Expand Down Expand Up @@ -327,40 +321,68 @@ public function reviews(SlimRequest $slimRequest, APIResponse $response, array $
$genreDao = DAORegistry::getDAO('GenreDAO');
$genres = $genreDao->getByContextId($context->getId())->toArray();

return $response->withJson([
return response()->json([
'itemsMax' => $collector->limit(null)->offset(null)->getCount(),
'items' => Repo::submission()->getSchemaMap()->mapManyToSubmissionsList($submissions, $userGroups, $genres)->values(),
], 200);
], Response::HTTP_OK);
}

/**
* Get a number of the submissions for each view
*/
public function getViewsCount(SlimRequest $slimRequest, APIResponse $response, array $args): APIResponse
public function getViewsCount(Request $illuminateRequest): JsonResponse
{
$request = Application::get()->getRequest();
$context = $request->getContext();
if (!$context) {
return $response->withStatus(404)->withJsonError('api.404.resourceNotFound');
return response()->json([
'error' => __('api.404.resourceNotFound'),
], Response::HTTP_NOT_FOUND);
}
$currentUser = $request->getUser();

$dashboardViews = Repo::submission()->getDashboardViews($context, $currentUser);

return $response->withJson($dashboardViews->map(fn(DashboardView $view) => $view->getCount()), 200);
return response()->json(
$dashboardViews->map(fn(DashboardView $view) => $view->getCount()),
Response::HTTP_OK
);
}

/**
* Get all reviewer's assignments
*/
public function getReviewAssignments(SlimRequest $slimRequest, APIResponse $response, array $args)
public function getReviewAssignments(Request $illuminateRequest): JsonResponse
{
$request = Application::get()->getRequest();
$context = $request->getContext();
if (!$context) {
return $response->withStatus(404)->withJsonError('api.404.resourceNotFound');
return response()->json([
'error' => __('api.404.resourceNotFound'),
], Response::HTTP_NOT_FOUND);
}
$currentUser = $request->getUser();
$collector = Repo::reviewAssignment()->getCollector()
->filterByReviewRoundIds([$currentUser->getId()])
->filterByContextIds([$context->getId()]);

foreach ($illuminateRequest->query() as $param => $val) {
switch ($param) {
case 'pending':
$collector->filterByIsIncomplete(true);
break;
case 'archived':
$collector->filterByIsArchived(true);
break;
}
}

$reviewAssignments = $collector->getMany();

return response()->json([
'itemsMax' => $collector->limit(null)->offset(null)->getCount(),
'items' => Repo::reviewAssignment()->getSchemaMap()->mapMany($reviewAssignments)->values(),
], Response::HTTP_OK);
}

/**
Expand Down
19 changes: 2 additions & 17 deletions classes/submission/Collector.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
*/
abstract class Collector implements CollectorInterface
{
use ViewsCount;

public const ORDERBY_DATE_PUBLISHED = 'datePublished';
public const ORDERBY_DATE_SUBMITTED = 'dateSubmitted';
public const ORDERBY_ID = 'id';
Expand Down Expand Up @@ -640,23 +642,6 @@ public function getQueryBuilder(): Builder
return $q;
}

/**
* Builds a single query to retrieve submissions count for all dashboard views
* @param Collection [
* Dashboard view unique ID => Submission Collector with filters applied
* ]
*/
public static function getViewsCountBuilder(Collection $keyCollectorPair): Builder
{
$q = DB::query();
$keyCollectorPair->each(function(AppCollector $collector, string $key) use ($q) {
// Get query builder from a collector instance, override a select statement to retrieve submissions count instead of submissions data
$subQuery = $collector->getQueryBuilder()->select([])->selectRaw('COUNT(s.submission_id)');
$q->selectSub($subQuery, $key);
});
return $q;
}

/**
* Build queries to retrieve review stage related
*/
Expand Down
6 changes: 4 additions & 2 deletions classes/submission/DashboardView.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use PKP\security\Role;
use PKP\submission\Collector as SubmissionCollector;
use PKP\submission\reviewAssignment\Collector as ReviewAssignmentCollector;

class DashboardView
{
Expand All @@ -40,7 +42,7 @@ class DashboardView
const TYPE_INCOMPLETE_SUBMISSIONS = 'incomplete-submissions';
const TYPE_REVIEWER_ASSIGNMENTS_ALL = 'reviewer-assignments-all';
const TYPE_REVIEWER_ASSIGNMENTS_PENDING = 'reviewer-assignments-pending';
const TYPE_REVIEWER_ASSIGNMENTS_FINISHED = 'reviewer-assignments-finished';
const TYPE_REVIEWER_ASSIGNMENTS_ARCHIVED = 'reviewer-assignments-archived';

// The number of submissions in the view
protected int $count;
Expand All @@ -49,7 +51,7 @@ public function __construct(
protected string $type, // View type, used also as the unique ID of the view's front-end part
protected string $name, // View name as a localized string
protected array $roles, // User roles having access to the view
protected Collector $submissionCollector, // Collector with correspondent filters applied
protected SubmissionCollector|ReviewAssignmentCollector $submissionCollector, // Collector with correspondent filters applied
protected ?string $op = null, // Dashboard handler operation to retrieve filtered submissions
protected ?array $queryParams = null // Optional query parameters
)
Expand Down
34 changes: 34 additions & 0 deletions classes/submission/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,40 @@ public function getDashboardViews(Context $context, User $user): Collection
'assigned',
['isIncomplete' => true]
);
case DashboardView::TYPE_REVIEWER_ASSIGNMENTS_ALL:
return new DashboardView(
$key,
__('submission.dashboard.view.reviewAssignments.all'),
[Role::ROLE_ID_REVIEWER],
Repo::reviewAssignment()->getCollector()
->filterByReviewerIds([$user->getId()])
->filterByContextIds([$context->getId()]),
'reviewerAssignments'
);
case DashboardView::TYPE_REVIEWER_ASSIGNMENTS_PENDING:
return new DashboardView(
$key,
__('submission.dashboard.view.reviewAssignments.pending'),
[Role::ROLE_ID_REVIEWER],
Repo::reviewAssignment()->getCollector()
->filterByReviewerIds([$user->getId()])
->filterByContextIds([$context->getId()])
->filterByIsIncomplete(true),
'reviewerAssignments',
['pending' => true]
);
case DashboardView::TYPE_REVIEWER_ASSIGNMENTS_ARCHIVED:
return new DashboardView(
$key,
__('submission.dashboard.view.reviewAssignments.archived'),
[Role::ROLE_ID_REVIEWER],
Repo::reviewAssignment()->getCollector()
->filterByReviewerIds([$user->getId()])
->filterByContextIds([$context->getId()])
->filterByIsArchived(true),
'reviewerAssignments',
['archived' => true]
);
}
});

Expand Down
41 changes: 41 additions & 0 deletions classes/submission/ViewsCount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
/**
* @file classes/submission/ViewsCount.php
*
* Copyright (c) 2014-2023 Simon Fraser University
* Copyright (c) 2000-2023 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class ViewsCount
*
* @brief trait to use with a collector to build a query for counting submissions/reviewAssignments in a view
*/

namespace PKP\submission;

use APP\submission\Collector as AppCollector;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

trait ViewsCount
{
/**
* Builds a single query to retrieve submissions count for all dashboard views
* @param Collection [
* Dashboard view unique ID => Submission Collector with filters applied
* ]
*/
public static function getViewsCountBuilder(Collection $keyCollectorPair): Builder
{
$q = DB::query();
$keyCollectorPair->each(function(AppCollector $collector, string $key) use ($q) {
// Get query builder from a collector instance, override a select statement to retrieve submissions count instead of submissions data
$subQuery = $collector->getQueryBuilder()->select([])->selectRaw(
'COUNT('. $this->dao->table . '.' . $this->dao->primaryKeyColumn . ')'
);
$q->selectSub($subQuery, $key);
});
return $q;
}
}
20 changes: 20 additions & 0 deletions classes/submission/reviewAssignment/Collector.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@
use Illuminate\Support\LazyCollection;
use PKP\core\Core;
use PKP\core\interfaces\CollectorInterface;
use PKP\submission\ViewsCount;

/**
* @template T of ReviewAssignment
*/
class Collector implements CollectorInterface
{
use ViewsCount;

public DAO $dao;
public ?array $contextIds = null;
public ?array $submissionIds = null;
public bool $isIncomplete = false;
public bool $isArchived = false;
public bool $isOverdue = false;
public ?array $reviewRoundIds = null;
public ?array $reviewerIds = null;
Expand Down Expand Up @@ -98,6 +102,15 @@ public function filterByIsIncomplete(?bool $isIncomplete): self
return $this;
}

/**
* Filter by completed or declined assignments
*/
public function filterByIsArchived(?bool $isArchived): self
{
$this->isArchived = $isArchived;
return $this;
}

/**
* Filter by overdue assignments
*/
Expand Down Expand Up @@ -218,6 +231,13 @@ public function getQueryBuilder(): Builder
);
});

$q->when($this->isArchived, fn(Builder $q) =>
$q->where(fn(Builder $q) => $q
->whereNotNull('ra.date_completed')
->orWhere('declined', 1)
)
);

$q->when($this->isOverdue, fn(Builder $q) => $q
->where(fn(Builder $q) => $q
->whereNull('ra.date_completed')
Expand Down

0 comments on commit b76beee

Please sign in to comment.