sort columns in MyEntries

This commit is contained in:
mattyl006 2022-11-09 17:49:57 +01:00
parent f02c071fd7
commit a47fd25c1f
5 changed files with 139 additions and 82 deletions

View File

@ -1,15 +1,47 @@
import {API} from '../utils/globals'; import {API} from '../utils/globals';
import KeyCloakService from '../services/KeyCloakService'; import KeyCloakService from '../services/KeyCloakService';
const getMyEntries = (challengeName, setDataState, setLoadingState) => { const getMyEntries = (challengeName, setDataOriginalState, setDataState, setLoadingState) => {
fetch(`${API}/challenge-my-submissions/${challengeName}`, { fetch(`${API}/challenge-my-submissions/${challengeName}`, {
headers: {'Authorization': `Bearer ${KeyCloakService.getToken()}`} headers: {'Authorization': `Bearer ${KeyCloakService.getToken()}`}
}) })
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
setDataState(data); setDataOriginalState(data);
if (setLoadingState) let item = {};
console.log(data); let result = [];
let tests = data.tests;
for (let submission of data.submissions) {
for (let evaluation of submission.evaluations) {
item = {
...item,
evaluations: {
...item.evaluations,
[`${evaluation.test.metric}.${evaluation.test.name}`]: evaluation.score
}
};
}
for (let test of tests) {
if (!Object.hasOwn(item.evaluations, `${test.metric}.${test.name}`)) {
item = {
...item,
evaluations: {
...item.evaluations,
[`${test.metric}.${test.name}`]: '-1'
}
};
}
}
item = {
...item,
id: submission.id,
submitter: submission.submitter,
when: submission.when,
};
result.push(item);
item = {};
}
setDataState(result);
setLoadingState(false); setLoadingState(false);
}); });
}; };

View File

@ -29,9 +29,37 @@ const Table = (props) => {
); );
}; };
const metricsRender = (elem) => {
if (!props.iterableColumnElement)
return <></>;
if (Array.isArray(elem[props.iterableColumnElement.name]))
elem = elem[props.iterableColumnElement.name];
else {
let newElem = [];
for (let metric of props.possibleMetrics) {
if (elem[props.iterableColumnElement.name][metric] === '-1')
newElem.push('N/A');
else
newElem.push(elem[props.iterableColumnElement.name][metric]);
}
elem = newElem;
}
return (
elem.map((iterableElem, i) => {
return (
<Body key={`metric-result-${i}`} as='td'
order={props.iterableColumnElement.order}
textAlign={props.iterableColumnElement.align} minWidth='72px'>
{props.iterableColumnElement.format ?
props.iterableColumnElement.format(iterableElem) : iterableElem}
</Body>
);
})
);
};
const desktopRender = () => { const desktopRender = () => {
const n = (props.pageNr - 1) * (ELEMENTS_PER_PAGE * 2); const n = (props.pageNr - 1) * (ELEMENTS_PER_PAGE * 2);
console.log(props.elements);
let elementsToMap = props.elements.slice(n, n + (ELEMENTS_PER_PAGE * 2)); let elementsToMap = props.elements.slice(n, n + (ELEMENTS_PER_PAGE * 2));
return ( return (
<FlexColumn as='table' margin='32px 0 72px 0' width='100%'> <FlexColumn as='table' margin='32px 0 72px 0' width='100%'>
@ -41,7 +69,7 @@ const Table = (props) => {
gridTemplateColumns={props.gridTemplateColumns}> gridTemplateColumns={props.gridTemplateColumns}>
{props.headerElements.map((elem, i) => { {props.headerElements.map((elem, i) => {
return ( return (
<FlexRow key={`leaderboard-header-${i}`} alignmentX='flex-start' as='td' <FlexRow key={`table-header-${i}`} alignmentX='flex-start' as='td'
onClick={() => { onClick={() => {
props.sortByUpdate(elem); props.sortByUpdate(elem);
forceUpdate(); forceUpdate();
@ -77,24 +105,7 @@ const Table = (props) => {
</Body> </Body>
); );
})} })}
{props.iterableColumnElement ? elem[props.iterableColumnElement.name].map((iterableElem, i) => { {props.headerElements ? metricsRender(elem) : ''}
return (
<Body key={`metric-result-${i}`} as='td'
order={props.iterableColumnElement.order}
textAlign={props.iterableColumnElement.align} minWidth='72px'>
{props.iterableColumnElement.format ?
props.iterableColumnElement.format(iterableElem) : iterableElem}
</Body>
);
}) : ''}
{props.myEntries ? props.myEntries.tests.map((test, i) => {
return (
<Body key={`eval-result-${i}`} width='80px' as='td' textAlign='left'
minWidth='72px' order={2}>
{props.renderEvalResult(elem.evaluations, test)}
</Body>
);
}) : ''}
</Grid> </Grid>
); );
})} })}

View File

@ -7,7 +7,7 @@ import Table from '../../elements/Table';
import PropsTypes from 'prop-types'; import PropsTypes from 'prop-types';
import getChallengeLeaderboard from '../../../api/getChallengeLeaderboard'; import getChallengeLeaderboard from '../../../api/getChallengeLeaderboard';
import _tableSearchQueryHandler from './_tableSearchQueryHandler'; import _tableSearchQueryHandler from './_tableSearchQueryHandler';
import {CALC_PAGES, RENDER_WHEN} from '../../../utils/globals'; import {CALC_PAGES, EVALUATIONS_FORMAT, RENDER_WHEN} from '../../../utils/globals';
import Search from '../../elements/Search'; import Search from '../../elements/Search';
import Pager from '../../elements/Pager'; import Pager from '../../elements/Pager';
import Loading from '../../elements/Loading'; import Loading from '../../elements/Loading';
@ -85,7 +85,6 @@ const Leaderboard = (props) => {
const sortByUpdate = (elem) => { const sortByUpdate = (elem) => {
let metricIndex = 0; let metricIndex = 0;
let newEntries = entries; let newEntries = entries;
console.log(elem);
switch (elem) { switch (elem) {
case 'submitter': case 'submitter':
if (submitterSorted) { if (submitterSorted) {
@ -125,6 +124,7 @@ const Leaderboard = (props) => {
} }
break; break;
} }
console.log(newEntries);
setEntries(newEntries); setEntries(newEntries);
}; };
@ -146,10 +146,6 @@ const Leaderboard = (props) => {
); );
}; };
const evaluationsFormat = (evaluate) => {
return evaluate.score.slice(0, 7);
};
const desktopRender = () => { const desktopRender = () => {
return ( return (
<FlexColumn padding='24px' as='section' width='100%' maxWidth='1200px'> <FlexColumn padding='24px' as='section' width='100%' maxWidth='1200px'>
@ -172,7 +168,7 @@ const Leaderboard = (props) => {
metrics={getPossibleMetrics()} metrics={getPossibleMetrics()}
iterableColumnElement={{ iterableColumnElement={{
name: 'evaluations', name: 'evaluations',
format: evaluationsFormat, format: EVALUATIONS_FORMAT,
order: 3, order: 3,
align: 'left' align: 'left'
}} }}

View File

@ -3,7 +3,7 @@ import {FlexColumn} from '../../utils/containers';
import {H2} from '../../utils/fonts'; import {H2} from '../../utils/fonts';
import getMyEntries from '../../api/getMyEntries'; import getMyEntries from '../../api/getMyEntries';
import Pager from '../elements/Pager'; import Pager from '../elements/Pager';
import {CALC_PAGES, RENDER_WHEN} from '../../utils/globals'; import {CALC_PAGES, EVALUATIONS_FORMAT, RENDER_WHEN} from '../../utils/globals';
import Media from 'react-media'; import Media from 'react-media';
import theme from '../../utils/theme'; import theme from '../../utils/theme';
import _tableSearchQueryHandler from './Leaderboard/_tableSearchQueryHandler'; import _tableSearchQueryHandler from './Leaderboard/_tableSearchQueryHandler';
@ -15,9 +15,9 @@ const MyEntries = (props) => {
const [myEntries, setMyEntries] = React.useState({}); const [myEntries, setMyEntries] = React.useState({});
const [loading, setLoading] = React.useState(true); const [loading, setLoading] = React.useState(true);
const [pageNr, setPageNr] = React.useState(1); const [pageNr, setPageNr] = React.useState(1);
const [whenSorted, setWhenSorted] = React.useState(false);
const [scoreSorted, setScoreSorted] = React.useState(false);
/* eslint-disable */ /* eslint-disable */
const [metricChoose, setMetricChoose] = React.useState(0);
const [sortBy, setSortBy] = React.useState(5);
React.useEffect(() => { React.useEffect(() => {
challengesRequest(); challengesRequest();
@ -30,7 +30,7 @@ const MyEntries = (props) => {
const getPossibleMetrics = () => { const getPossibleMetrics = () => {
let metrics = []; let metrics = [];
for (let test of myEntriesFromAPI.tests) { for (let test of myEntriesFromAPI.tests) {
let myEval = `${test.metric} ${test.name}`; let myEval = `${test.metric}.${test.name}`;
if (myEval && !metrics.includes(myEval)) { if (myEval && !metrics.includes(myEval)) {
metrics.push(myEval); metrics.push(myEval);
} }
@ -62,63 +62,74 @@ const MyEntries = (props) => {
}; };
const challengesRequest = () => { const challengesRequest = () => {
getMyEntries(props.challengeName, setMyEntriesFromAPI, setLoading); getMyEntries(props.challengeName, setMyEntriesFromAPI, setMyEntries, setLoading);
getMyEntries(props.challengeName, setMyEntries, setLoading);
}; };
const mobileRender = () => { const mobileRender = () => {
} }
const renderEvalResult = (evaluations, test) => {
for (let myEval of evaluations) {
if (myEval.test.name === test.name && myEval.test.metric === test.metric) {
return myEval.score.slice(0, 7);
}
}
return 'xxx';
};
const sortByUpdate = (elem) => { const sortByUpdate = (elem) => {
let newEntries = myEntries; let newEntries = myEntries;
return myEntries; switch (elem) {
case '#':
break;
case 'when':
if (whenSorted) {
newEntries = newEntries.sort((a, b) => (a.when > b.when) ? 1 : ((b.when > a.when) ? -1 : 0));
setWhenSorted(false);
} else {
newEntries = newEntries.sort((a, b) => (a.when < b.when) ? 1 : ((b.when < a.when) ? -1 : 0));
setWhenSorted(true);
}
break;
default:
if (scoreSorted) {
newEntries = newEntries.sort((a, b) => b.evaluations[elem] - a.evaluations[elem]);
setScoreSorted(false);
} else {
newEntries = newEntries.sort((a, b) => a.evaluations[elem] - b.evaluations[elem]);
setScoreSorted(true);
}
break;
}
console.log(newEntries);
setMyEntries(newEntries);
}; };
const desktopRender = () => { const desktopRender = () => {
if (loading) { return (
return ( <FlexColumn padding='24px' as='section' width='100%' maxWidth='1400px'>
<Loading/> <H2 as='h2' margin='0 0 32px 0'>
); My entries
} else { </H2>
return ( {myEntries && !loading ?
<FlexColumn padding='24px' as='section' width='100%' maxWidth='1400px'> <>
<H2 as='h2' margin='0 0 32px 0'> <Table challengeName={props.challengeName} headerElements={getMyEntriesHeader()}
My entries possibleMetrics={getPossibleMetrics()}
</H2> gridTemplateColumns={'1fr ' + '4fr '.repeat(getMyEntriesHeader().length - 1)}
{myEntries.submissions ? staticColumnElements={
<> [
<Table challengeName={props.challengeName} loading={loading} {name: 'id', format: null, order: 1, align: 'left'},
headerElements={getMyEntriesHeader()} {name: 'when', format: RENDER_WHEN, order: 3, align: 'right'}
gridTemplateColumns={'1fr ' + '4fr '.repeat(getMyEntriesHeader().length - 1)} ]
staticColumnElements={ }
[ iterableColumnElement={{
{name: 'id', format: null, order: 1, align: 'left'}, name: 'evaluations',
{name: 'when', format: RENDER_WHEN, order: 3, align: 'right'} format: EVALUATIONS_FORMAT,
] order: 2,
} align: 'left'
metrics={getPossibleMetrics()} myEntries={myEntries} }}
renderEvalResult={renderEvalResult} pageNr={pageNr} elements={myEntries}
pageNr={pageNr} elements={myEntries.submissions} sortByUpdate={sortByUpdate}/>
sortByUpdate={sortByUpdate}/> <Pager pageNr={pageNr} width='72px' borderRadius='64px'
<Pager pageNr={pageNr} width='72px' borderRadius='64px' pages={CALC_PAGES(myEntries, 2)}
pages={CALC_PAGES(myEntries.submissions, 2)} nextPage={nextPage} previousPage={previousPage}
nextPage={nextPage} previousPage={previousPage} number={`${pageNr} / ${CALC_PAGES(myEntries, 2)}`}/>
number={`${pageNr} / ${CALC_PAGES(myEntries.submissions, 2)}`}/> </>
</> : <Loading/>}
: <Loading/>} </FlexColumn>
</FlexColumn> );
);
}
}; };
return ( return (

View File

@ -64,6 +64,12 @@ const RENDER_WHEN = (when) => {
return `${when.slice(0, 10)} ${when.slice(11, 16)}`; return `${when.slice(0, 10)} ${when.slice(11, 16)}`;
}; };
const EVALUATIONS_FORMAT = (evaluate) => {
if (Object.hasOwn(evaluate, 'score'))
return evaluate.score.slice(0, 7);
return evaluate.slice(0, 7);
};
const IS_MOBILE = () => { const IS_MOBILE = () => {
return document.body.clientWidth <= 768; return document.body.clientWidth <= 768;
}; };
@ -80,5 +86,6 @@ export {
CALC_PAGES, CALC_PAGES,
RENDER_DEADLINE_TIME, RENDER_DEADLINE_TIME,
IS_MOBILE, IS_MOBILE,
RENDER_WHEN RENDER_WHEN,
EVALUATIONS_FORMAT
}; };