From a748d5724c8acff6e3bb3fe6c20aa5968b65d58a Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Sun, 27 Mar 2022 14:33:44 +0200 Subject: [PATCH] tournament monitors --- app/Models/User.php | 17 ++++++++++++ app/Policies/ParticipantPolicy.php | 6 ++--- app/Policies/RoundPolicy.php | 4 +-- app/Policies/TournamentPolicy.php | 4 +-- resources/js/components/rounds/SeedButton.js | 2 +- resources/js/components/tournament/Detail.js | 12 +++++++++ resources/js/helpers/Participant.js | 8 ++++++ resources/js/helpers/Tournament.js | 28 ++++++++++++++++++++ resources/js/helpers/permissions.js | 21 +++++++++++---- resources/js/i18n/de.js | 2 ++ resources/js/i18n/en.js | 2 ++ 11 files changed, 93 insertions(+), 13 deletions(-) diff --git a/app/Models/User.php b/app/Models/User.php index eea1426..e5bb4f1 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -12,6 +12,10 @@ class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; + public function isAdmin() { + return $this->role === 'admin'; + } + public function isParticipant(Tournament $tournament) { foreach ($tournament->participants as $participant) { if ($participant->user_id == $this->id) { @@ -39,6 +43,19 @@ class User extends Authenticatable return false; } + public function isTournamentCrew(Tournament $tournament) { + return $this->isTournamentAdmin($tournament) || $this->isTournamentMonitor($tournament); + } + + public function isTournamentMonitor(Tournament $tournament) { + foreach ($tournament->participants as $participant) { + if ($participant->user_id == $this->id) { + return in_array('monitor', $participant->roles); + } + } + return false; + } + public function participation() { return $this->hasMany(Participant::class); diff --git a/app/Policies/ParticipantPolicy.php b/app/Policies/ParticipantPolicy.php index f5b5246..8622d12 100644 --- a/app/Policies/ParticipantPolicy.php +++ b/app/Policies/ParticipantPolicy.php @@ -18,7 +18,7 @@ class ParticipantPolicy */ public function viewAny(User $user) { - return $user->role === 'admin'; + return $user->isAdmin(); } /** @@ -30,7 +30,7 @@ class ParticipantPolicy */ public function view(User $user, Participant $participant) { - return $user->role === 'admin'; + return $user->isAdmin(); } /** @@ -53,7 +53,7 @@ class ParticipantPolicy */ public function update(User $user, Participant $participant) { - return $user->role === 'admin'; + return $user->isAdmin(); } /** diff --git a/app/Policies/RoundPolicy.php b/app/Policies/RoundPolicy.php index 230b225..c1a1a48 100644 --- a/app/Policies/RoundPolicy.php +++ b/app/Policies/RoundPolicy.php @@ -101,7 +101,7 @@ class RoundPolicy */ public function setSeed(User $user, Round $round) { - return $user->role === 'admin' || ($user->isParticipant($round->tournament) && !$round->locked); + return $user->isAdmin() || (!$round->locked && ($user->isRunner($round->tournament) || $user->isTournamentAdmin($round->tournament))); } /** @@ -113,7 +113,7 @@ class RoundPolicy */ public function lock(User $user, Round $round) { - return $user->role === 'admin' || $user->isTournamentAdmin($round->tournament); + return $user->isAdmin() || $user->isTournamentAdmin($round->tournament); } /** diff --git a/app/Policies/TournamentPolicy.php b/app/Policies/TournamentPolicy.php index fa27298..72b5dcb 100644 --- a/app/Policies/TournamentPolicy.php +++ b/app/Policies/TournamentPolicy.php @@ -101,7 +101,7 @@ class TournamentPolicy */ public function addRound(User $user, Tournament $tournament) { - return $user->role === 'admin' || (!$tournament->locked && $user->isParticipant($tournament)); + return $user->isAdmin() || (!$tournament->locked && ($user->isRunner($tournament) || $user->isTournamentAdmin($tournament))); } /** @@ -113,7 +113,7 @@ class TournamentPolicy */ public function viewProtocol(User $user, Tournament $tournament) { - return $user->role === 'admin' || $user->isTournamentAdmin($tournament); + return $user->isAdmin() || $user->isTournamentCrew($tournament); } } diff --git a/resources/js/components/rounds/SeedButton.js b/resources/js/components/rounds/SeedButton.js index 1d68b6a..d9d3433 100644 --- a/resources/js/components/rounds/SeedButton.js +++ b/resources/js/components/rounds/SeedButton.js @@ -18,7 +18,7 @@ const SeedButton = ({ round, tournament, user }) => { ); } - if (maySetSeed(user, tournament)) { + if (maySetSeed(user, tournament, round)) { return <> setShowDialog(false)} diff --git a/resources/js/components/tournament/Detail.js b/resources/js/components/tournament/Detail.js index 1afcc29..cfea60d 100644 --- a/resources/js/components/tournament/Detail.js +++ b/resources/js/components/tournament/Detail.js @@ -14,8 +14,10 @@ import { } from '../../helpers/permissions'; import { getTournamentAdmins, + getTournamentMonitors, hasRunners, hasTournamentAdmins, + hasTournamentMonitors, } from '../../helpers/Tournament'; import { withUser } from '../../helpers/UserContext'; import i18n from '../../i18n'; @@ -66,6 +68,16 @@ const Detail = ({ )} : null} + {hasTournamentMonitors(tournament) ? + <> +
+

{i18n.t('tournaments.monitors')}

+
+ {getTournamentMonitors(tournament).map(p => +

+ )} + + : null}
diff --git a/resources/js/helpers/Participant.js b/resources/js/helpers/Participant.js index 8545e03..4b4b6ef 100644 --- a/resources/js/helpers/Participant.js +++ b/resources/js/helpers/Participant.js @@ -41,6 +41,12 @@ export const isRunner = participant => export const isTournamentAdmin = participant => participant && participant.roles && participant.roles.includes('admin'); +export const isTournamentCrew = participant => + isTournamentAdmin(participant) || isTournamentMonitor(participant); + +export const isTournamentMonitor = participant => + participant && participant.roles && participant.roles.includes('monitor'); + export const patchUser = (participant, user) => { if (!participant || !user) return participant; if (participant.user_id != user.id) return participant; @@ -65,6 +71,8 @@ export default { findResult, isRunner, isTournamentAdmin, + isTournamentCrew, + isTournamentMonitor, patchUser, sortByResult, }; diff --git a/resources/js/helpers/Tournament.js b/resources/js/helpers/Tournament.js index ec141d1..7dbcb9b 100644 --- a/resources/js/helpers/Tournament.js +++ b/resources/js/helpers/Tournament.js @@ -29,6 +29,20 @@ export const getTournamentAdmins = tournament => { .sort(Participant.compareUsername); }; +export const getTournamentCrew = tournament => { + if (!tournament || !tournament.participants || !tournament.participants.length) return []; + return tournament.participants + .filter(Participant.isTournamentCrew) + .sort(Participant.compareUsername); +}; + +export const getTournamentMonitors = tournament => { + if (!tournament || !tournament.participants || !tournament.participants.length) return []; + return tournament.participants + .filter(Participant.isTournamentMonitor) + .sort(Participant.compareUsername); +}; + export const hasRunners = tournament => { return getRunners(tournament).length > 0; }; @@ -37,6 +51,14 @@ export const hasTournamentAdmins = tournament => { return getTournamentAdmins(tournament).length > 0; }; +export const hasTournamentCrew = tournament => { + return getTournamentCrew(tournament).length > 0; +}; + +export const hasTournamentMonitors = tournament => { + return getTournamentMonitors(tournament).length > 0; +}; + export const patchParticipant = (tournament, participant) => { if (!tournament) return tournament; if (!tournament.participants || !tournament.participants.length) { @@ -103,6 +125,12 @@ export default { findParticipant, getRunners, getTournamentAdmins, + getTournamentCrew, + getTournamentMonitors, + hasRunners, + hasTournamentAdmins, + hasTournamentCrew, + hasTournamentMonitors, patchResult, patchRound, patchUser, diff --git a/resources/js/helpers/permissions.js b/resources/js/helpers/permissions.js index 3df65d6..f86b585 100644 --- a/resources/js/helpers/permissions.js +++ b/resources/js/helpers/permissions.js @@ -23,24 +23,35 @@ export const isTournamentAdmin = (user, tournament) => { return p && p.roles && p.roles.includes('admin'); }; +export const isTournamentCrew = (user, tournament) => + isTournamentAdmin(user, tournament) || isTournamentMonitor(user, tournament); + +export const isTournamentMonitor = (user, tournament) => { + const p = isParticipant(user, tournament); + return p && p.roles && p.roles.includes('monitor'); +}; + export const hasFinished = (user, round) => user && round && round.results && round.results.find(r => r.user_id == user.id && r.has_finished); export const mayAddRounds = (user, tournament) => - isAdmin(user) || (!tournament.locked && isParticipant(user, tournament)); + isAdmin(user) || (!tournament.locked && + (isRunner(user, tournament) || isTournamentAdmin(user, tournament))); export const mayLockRound = (user, tournament) => isAdmin(user) || (!tournament.locked && isTournamentAdmin(user, tournament)); -export const maySetSeed = (user, tournament) => - isAdmin(user) || isParticipant(user, tournament); +export const maySetSeed = (user, tournament, round) => + isAdmin(user) || (!round.locked && + (isRunner(user, tournament) || isTournamentAdmin(user, tournament))); export const mayViewProtocol = (user, tournament) => - isAdmin(user) || isTournamentAdmin(user, tournament); + isAdmin(user) || isTournamentCrew(user, tournament); export const maySeeResults = (user, tournament, round) => - isAdmin(user) || hasFinished(user, round) || Round.isComplete(tournament, round); + isAdmin(user) || hasFinished(user, round) || + isTournamentMonitor(user, tournament) || Round.isComplete(tournament, round); // Users diff --git a/resources/js/i18n/de.js b/resources/js/i18n/de.js index 9416ead..17cb41f 100644 --- a/resources/js/i18n/de.js +++ b/resources/js/i18n/de.js @@ -114,6 +114,7 @@ export default { placementSubjectToChange: 'Das Turnier wurde noch nicht abgeschlossen, die Platzierung kann sich noch ändern.', roleNames: { admin: 'Administrator', + monitor: 'Monitor', runner: 'Runner', }, roles: 'Teilnahme als', @@ -177,6 +178,7 @@ export default { }, tournaments: { admins: 'Organisation', + monitors: 'Monitore', noRecord: 'Turnier wird nicht gewertet', scoreboard: 'Scoreboard', }, diff --git a/resources/js/i18n/en.js b/resources/js/i18n/en.js index 6aa5cc8..f0c6871 100644 --- a/resources/js/i18n/en.js +++ b/resources/js/i18n/en.js @@ -114,6 +114,7 @@ export default { placementSubjectToChange: 'Tournament incomplete, placement subject to change.', roleNames: { admin: 'Administrator', + monitor: 'Monitor', runner: 'Runner', }, roles: 'Participated as', @@ -177,6 +178,7 @@ export default { }, tournaments: { admins: 'Admins', + monitors: 'Monitors', noRecord: 'Tournament set to not be recorded', scoreboard: 'Scoreboard', }, -- 2.39.2