From 5126e0fd77e6de74fc5c466ff245887db4dda646 Mon Sep 17 00:00:00 2001
From: Luca <30503695+tameTNT@users.noreply.github.com>
Date: Tue, 10 Sep 2024 16:56:57 +0100
Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20Remove=20concept=20of?=
=?UTF-8?q?=20unranked=20projects=20and=20move=20to=20batch=20submission?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Towards addressing issue #1.
Under the new system (not yet developed) unranked teams will not exist
and rankings will be submitted in batches.
---
client/src/components/judge/ProjectEntry.tsx | 2 +-
client/src/pages/admin/settings.tsx | 43 +++++++++++++++++++-
client/src/pages/judge/index.tsx | 28 +++++++++++--
client/src/types.d.ts | 1 +
server/models/options.go | 24 ++++++-----
server/ranking/borda.go | 12 +++---
server/ranking/borda_test.go | 8 ++--
server/router/admin.go | 13 +++---
8 files changed, 97 insertions(+), 34 deletions(-)
diff --git a/client/src/components/judge/ProjectEntry.tsx b/client/src/components/judge/ProjectEntry.tsx
index 7645b3b..1950528 100644
--- a/client/src/components/judge/ProjectEntry.tsx
+++ b/client/src/components/judge/ProjectEntry.tsx
@@ -18,7 +18,7 @@ const ProjectEntry = ({ project }: ProjectEntryProps) => {
if (project.id === -1) {
return (
-
Unsorted Projects below here...
+ Unranked projects below here...
);
}
diff --git a/client/src/pages/admin/settings.tsx b/client/src/pages/admin/settings.tsx
index a0532c9..72df2f0 100644
--- a/client/src/pages/admin/settings.tsx
+++ b/client/src/pages/admin/settings.tsx
@@ -23,6 +23,7 @@ const AdminSettings = () => {
const [dropPopup, setDropPopup] = useState(false);
const [judgingTimer, setJudgingTimer] = useState('');
const [categories, setCategories] = useState('');
+ const [rankingBatchSize, setRankingBatchSize] = useState(8);
const [loading, setLoading] = useState(true);
async function getOptions() {
@@ -45,6 +46,10 @@ const AdminSettings = () => {
const cats = res.data?.categories.join(', ');
setCategories(cats ?? '');
+ // Set ranking batch size
+ const rbs = res.data?.ranking_batch_size;
+ setRankingBatchSize(rbs ?? 8)
+
setLoading(false);
}
@@ -111,6 +116,19 @@ const AdminSettings = () => {
getOptions();
};
+ const updateRankingBatchSize = async () => {
+ const res = await postRequest('/admin/categories', 'admin', {
+ ranking_batch_size: rankingBatchSize,
+ });
+ if (res.status !== 200 || res.data?.ok !== 1) {
+ errorAlert(res);
+ return;
+ }
+
+ alert('Ranking Batch Size updated!');
+ getOptions();
+ }
+
const resetClock = async () => {
const res = await postRequest('/admin/clock/reset', 'admin', null);
if (res.status !== 200 || res.data?.ok !== 1) {
@@ -234,11 +252,34 @@ const AdminSettings = () => {
Update Categories
+ Set Ranking Batch Size
+
+ Set how many projects judges rank at a time (must be at least 2 obviously).
+ Judges can rank and reorder projects freely before submitting a batch of the specified size.
+
+ {
+ setRankingBatchSize(parseInt(e.target.value));
+ }}
+ />
+
+ Update Ranking Batch Size
+
+
Reassign Project Numbers
diff --git a/client/src/pages/judge/index.tsx b/client/src/pages/judge/index.tsx
index e40f952..590a938 100644
--- a/client/src/pages/judge/index.tsx
+++ b/client/src/pages/judge/index.tsx
@@ -30,6 +30,7 @@ const Judge = () => {
const navigate = useNavigate();
const [judge, setJudge] = useState(null);
const [projects, setProjects] = useState([]);
+ const [allRanked, setAllRanked] = useState(false)
const [loaded, setLoaded] = useState(false);
const [projCount, setProjCount] = useState(0);
const [activeId, setActiveId] = useState(null);
@@ -125,6 +126,8 @@ const Judge = () => {
const combinedProjects = [...rankedProjects, dummy, ...unrankedProjects];
setProjects(combinedProjects);
+ setAllRanked(rankedProjects.length === 3); // lucatodo: use rank batch size variable;
+ // lucatodo: rankedProjects won't be variable we want to find length of. new variable probable: batchProjects?
setLoaded(true);
}, [judge]);
@@ -169,6 +172,7 @@ const Judge = () => {
const saveSort = async (newProjects: SortableJudgedProject[]) => {
// Split index
const splitIndex = newProjects.findIndex((p) => p.id === -1);
+ setAllRanked(newProjects.length>0 && splitIndex === newProjects.length-1); // lucatodo: use rank batch size variable equality, not >0
// Get the ranked projects
const rankedProjects = newProjects.slice(0, splitIndex);
@@ -189,6 +193,7 @@ const Judge = () => {
Welcome, {judge?.name}!
+ {/* lucatodo: disable button if all projects in batch seen */}
Next Project
@@ -199,10 +204,12 @@ const Judge = () => {
-
-
+
+
Rank Projects
+ {/* lucatodo: only update scores on submission? query this (only relevant if prioritisation implemented, issue #5 */}
+ NB: Relative project order is tracked on the admin panel even before your submit a batch.
{
>
{projects.map((item) => (
-
+
))}
{activeId ? (
- p.id === activeId)} />
+ p.id === activeId)}/>
) : null}
+
+
+ {/* lucatodo: update X with variable limit */}
+ {/* lucatodo: text updates if judging is ended manually to allow 'early' submission (see issue #4) */}
+ Please rank all your projects.
+ You can only submit rankings in batches of X projects.
+
+
+ {/* lucatodo: add button functionality (inc. alert to confirm submission) */}
+ Submit Rankings
+ And move onto next batch
+
+
>
);
diff --git a/client/src/types.d.ts b/client/src/types.d.ts
index 78a87c2..ce372f2 100644
--- a/client/src/types.d.ts
+++ b/client/src/types.d.ts
@@ -112,6 +112,7 @@ interface Options {
clock: ClockState;
judging_timer: number;
categories: string[];
+ ranking_batch_size: number;
}
interface FetchResponse {
diff --git a/server/models/options.go b/server/models/options.go
index 679ab0d..e09217b 100644
--- a/server/models/options.go
+++ b/server/models/options.go
@@ -3,20 +3,22 @@ package models
import "go.mongodb.org/mongo-driver/bson/primitive"
type Options struct {
- Id primitive.ObjectID `bson:"_id,omitempty" json:"id"`
- Ref int64 `bson:"ref" json:"ref"`
- CurrTableNum int64 `bson:"curr_table_num" json:"curr_table_num"`
- Clock ClockState `bson:"clock" json:"clock"`
- JudgingTimer int64 `bson:"judging_timer" json:"judging_timer"`
- Categories []string `bson:"categories" json:"categories"`
+ Id primitive.ObjectID `bson:"_id,omitempty" json:"id"`
+ Ref int64 `bson:"ref" json:"ref"`
+ CurrTableNum int64 `bson:"curr_table_num" json:"curr_table_num"`
+ Clock ClockState `bson:"clock" json:"clock"`
+ JudgingTimer int64 `bson:"judging_timer" json:"judging_timer"`
+ Categories []string `bson:"categories" json:"categories"`
+ RankingBatchSize int64 `bson:"ranking_batch_size" json:"ranking_batch_size"`
}
func NewOptions() *Options {
return &Options{
- Ref: 0,
- CurrTableNum: 0,
- JudgingTimer: 300,
- Clock: *NewClockState(),
- Categories: []string{"Creativity/Innovation", "Technical Competence/Execution", "Research/Design", "Presentation"},
+ Ref: 0,
+ CurrTableNum: 0,
+ JudgingTimer: 300,
+ Clock: *NewClockState(),
+ Categories: []string{"Creativity/Innovation", "Technical Competence/Execution", "Research/Design", "Presentation"},
+ RankingBatchSize: 8,
}
}
diff --git a/server/ranking/borda.go b/server/ranking/borda.go
index 2953066..6d904db 100644
--- a/server/ranking/borda.go
+++ b/server/ranking/borda.go
@@ -8,7 +8,7 @@ import (
type JudgeRanking struct {
Rankings []primitive.ObjectID `json:"rankings"`
- Unranked []primitive.ObjectID `json:"unranked"`
+ //Unranked []primitive.ObjectID `json:"unranked"`
}
type RankedObject struct {
@@ -34,11 +34,11 @@ func rankingToPairwise(judgeRanking JudgeRanking) []Comparison {
}
// Loop through each project in the ranking and compare it to all the unranked projects
- for _, winner := range judgeRanking.Rankings {
- for _, loser := range judgeRanking.Unranked {
- pairwise = append(pairwise, Comparison{winner, loser})
- }
- }
+ //for _, winner := range judgeRanking.Rankings {
+ // for _, loser := range judgeRanking.Unranked {
+ // pairwise = append(pairwise, Comparison{winner, loser})
+ // }
+ //}
return pairwise
}
diff --git a/server/ranking/borda_test.go b/server/ranking/borda_test.go
index 3264389..d3f6e63 100644
--- a/server/ranking/borda_test.go
+++ b/server/ranking/borda_test.go
@@ -19,19 +19,19 @@ func TestCalcRanking(t *testing.T) {
jrs := []ranking.JudgeRanking{
{
Rankings: []primitive.ObjectID{obj1, obj5, obj3},
- Unranked: []primitive.ObjectID{obj4, obj2},
+ //Unranked: []primitive.ObjectID{obj4, obj2},
},
{
Rankings: []primitive.ObjectID{obj5, obj4, obj2},
- Unranked: []primitive.ObjectID{obj3, obj1},
+ //Unranked: []primitive.ObjectID{obj3, obj1},
},
{
Rankings: []primitive.ObjectID{obj1, obj5, obj2},
- Unranked: []primitive.ObjectID{obj3, obj4},
+ //Unranked: []primitive.ObjectID{obj3, obj4},
},
{
Rankings: []primitive.ObjectID{obj2, obj1, obj5},
- Unranked: []primitive.ObjectID{obj5, obj3},
+ //Unranked: []primitive.ObjectID{obj5, obj3},
},
}
diff --git a/server/router/admin.go b/server/router/admin.go
index 3cb7fa0..134d6e6 100644
--- a/server/router/admin.go
+++ b/server/router/admin.go
@@ -393,16 +393,15 @@ func GetScores(ctx *gin.Context) {
// Create an array of {Rankings: [], Unranked: []}
judgeRankings := make([]ranking.JudgeRanking, 0)
for _, judge := range judges {
- unranked := make([]primitive.ObjectID, 0)
- for _, proj := range judge.SeenProjects {
- if !contains(judge.Rankings, proj.ProjectId) {
- unranked = append(unranked, proj.ProjectId)
- }
- }
+ //for _, proj := range judge.SeenProjects {
+ // if !contains(judge.Rankings, proj.ProjectId) {
+ // unranked = append(unranked, proj.ProjectId)
+ // }
+ //}
judgeRankings = append(judgeRankings, ranking.JudgeRanking{
Rankings: judge.Rankings,
- Unranked: unranked,
+ //Unranked: unranked,
})
}