MyEntries with new table and logic
This commit is contained in:
parent
e5d0e50102
commit
b8b4c31b45
@ -1,13 +1,14 @@
|
||||
import { API } from '../utils/globals';
|
||||
import KeyCloakService from '../services/KeyCloakService';
|
||||
|
||||
const getAllEntries = (
|
||||
const getEntries = (
|
||||
endpoint,
|
||||
challengeName,
|
||||
setDataStates,
|
||||
setLoadingState,
|
||||
setScoreSorted
|
||||
) => {
|
||||
fetch(`${API}/challenge-all-submissions/${challengeName}`, {
|
||||
fetch(`${API}/${endpoint}/${challengeName}`, {
|
||||
headers: { Authorization: `Bearer ${KeyCloakService.getToken()}` },
|
||||
})
|
||||
.then((response) => response.json())
|
||||
@ -61,4 +62,4 @@ const getAllEntries = (
|
||||
});
|
||||
};
|
||||
|
||||
export default getAllEntries;
|
||||
export default getEntries;
|
@ -3,9 +3,7 @@ import KeyCloakService from '../services/KeyCloakService';
|
||||
|
||||
const getMyEntries = (
|
||||
challengeName,
|
||||
setDataOriginalState,
|
||||
setDataStateForSearch,
|
||||
setDataState,
|
||||
setDataStates,
|
||||
setLoadingState,
|
||||
setScoreSorted
|
||||
) => {
|
||||
@ -14,7 +12,6 @@ const getMyEntries = (
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
setDataOriginalState(data);
|
||||
let item = {};
|
||||
let result = [];
|
||||
let initSetScoreSorted = [];
|
||||
@ -31,18 +28,17 @@ const getMyEntries = (
|
||||
};
|
||||
}
|
||||
for (let test of tests) {
|
||||
if (item.evaluations) {
|
||||
if (
|
||||
!Object.hasOwn(item.evaluations, `${test.metric}.${test.name}`)
|
||||
) {
|
||||
item = {
|
||||
...item,
|
||||
evaluations: {
|
||||
...item.evaluations,
|
||||
[`${test.metric}.${test.name}`]: '_',
|
||||
},
|
||||
};
|
||||
}
|
||||
if (!item.evaluations) {
|
||||
item.evaluations = {};
|
||||
}
|
||||
if (!Object.hasOwn(item.evaluations, `${test.metric}.${test.name}`)) {
|
||||
item = {
|
||||
...item,
|
||||
evaluations: {
|
||||
...item.evaluations,
|
||||
[`${test.metric}.${test.name}`]: -999999999,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
item = {
|
||||
@ -50,6 +46,7 @@ const getMyEntries = (
|
||||
id: submission.id,
|
||||
submitter: submission.submitter,
|
||||
when: submission.when,
|
||||
tags: submission.tags,
|
||||
};
|
||||
result.push(item);
|
||||
item = {};
|
||||
@ -58,10 +55,9 @@ const getMyEntries = (
|
||||
for (let _ of tests) {
|
||||
initSetScoreSorted.push(false);
|
||||
}
|
||||
setScoreSorted(initSetScoreSorted);
|
||||
setDataStateForSearch(result);
|
||||
setDataState(result);
|
||||
setLoadingState(false);
|
||||
for (let setDataState of setDataStates) setDataState(result);
|
||||
if (setScoreSorted) setScoreSorted(initSetScoreSorted);
|
||||
if (setLoadingState) setLoadingState(false);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { FlexColumn } from '../../utils/containers';
|
||||
import { H2 } from '../../utils/fonts';
|
||||
import Pager from '../../components/generic/Pager';
|
||||
import Search from '../../components/generic/Search';
|
||||
import getAllEntries from '../../api/getAllEntries';
|
||||
import getEntries from '../../api/getEntries';
|
||||
import Table from '../../components/generic/Table';
|
||||
import Loading from '../../components/generic/Loading';
|
||||
import { CALC_PAGES, ELEMENTS_PER_PAGE } from '../../utils/globals';
|
||||
@ -22,7 +22,8 @@ const NewTablePageTest = (props) => {
|
||||
|
||||
React.useMemo(() => {
|
||||
if (props.challengeName) {
|
||||
getAllEntries(
|
||||
getEntries(
|
||||
'challenge-all-submissions',
|
||||
props.challengeName,
|
||||
[setEntries, setEntriesAll],
|
||||
setLoading,
|
||||
|
@ -5,9 +5,19 @@ const searchQueryHandler = (event, entriesAll, setPageNr, setEntries) => {
|
||||
if (searchQuery === '') setEntries(entriesAll);
|
||||
else {
|
||||
for (let entry of entriesAll) {
|
||||
const { when } = entry;
|
||||
const otherKeys = Object.values(entry).join(' ');
|
||||
const str = `${when.slice(11, 16)} ${when.slice(0, 10)} ${otherKeys}`;
|
||||
let { when, tags } = entry;
|
||||
tags = Object.values(tags)
|
||||
.map((tag) => tag.name)
|
||||
.join(' ');
|
||||
const otherKeys = Object.values(entry)
|
||||
.join(' ')
|
||||
.replaceAll(-999999999, 'N/A')
|
||||
.replaceAll('[object Object]', '')
|
||||
.replaceAll(',', '');
|
||||
const str = `${when.slice(11, 16)} ${when.slice(
|
||||
0,
|
||||
10
|
||||
)} ${otherKeys} ${tags}`;
|
||||
if (str.toLowerCase().includes(searchQuery.toLowerCase()))
|
||||
submissionsToRender.push(entry);
|
||||
}
|
||||
|
@ -1,220 +1,132 @@
|
||||
import React from 'react';
|
||||
import { FlexColumn } from '../../utils/containers';
|
||||
import { H2 } from '../../utils/fonts';
|
||||
import getMyEntries from '../../api/getMyEntries';
|
||||
import Pager from '../../components/generic/Pager';
|
||||
import {
|
||||
CALC_PAGES,
|
||||
EVALUATIONS_FORMAT,
|
||||
IS_MOBILE,
|
||||
RENDER_WHEN,
|
||||
} from '../../utils/globals';
|
||||
import Media from 'react-media';
|
||||
import theme from '../../utils/theme';
|
||||
import { CALC_PAGES } from '../../utils/globals';
|
||||
import Loading from '../../components/generic/Loading';
|
||||
import Table from '../../components/generic/Table/Table';
|
||||
import myEntriesSearchQueryHandler from './myEntriesSearchQueryHandler';
|
||||
import Search from '../../components/generic/Search';
|
||||
import orderKeys from './orderKeys';
|
||||
import { ELEMENTS_PER_PAGE } from '../../utils/globals';
|
||||
import getEntries from '../../api/getEntries';
|
||||
import searchHandler from './searchHandler';
|
||||
|
||||
const MyEntries = (props) => {
|
||||
const [myEntriesFromAPI, setMyEntriesFromAPI] = React.useState({});
|
||||
const [myEntriesAll, setMyEntriesAll] = React.useState({});
|
||||
const [myEntries, setMyEntries] = React.useState({});
|
||||
// const [myEntriesFromAPI, setMyEntriesFromAPI] = React.useState({});
|
||||
const [myEntriesAll, setMyEntriesAll] = React.useState([]);
|
||||
const [myEntries, setMyEntries] = React.useState([]);
|
||||
const [loading, setLoading] = React.useState(true);
|
||||
const [pageNr, setPageNr] = React.useState(1);
|
||||
const [idSorted, setIdSorted] = React.useState([]);
|
||||
const [whenSorted, setWhenSorted] = React.useState(false);
|
||||
const [scoresSorted, setScoresSorted] = React.useState([]);
|
||||
|
||||
React.useEffect(() => {
|
||||
challengesRequest();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
const searchQueryHandler = (event) => {
|
||||
myEntriesSearchQueryHandler(event, myEntriesAll, setPageNr, setMyEntries);
|
||||
};
|
||||
|
||||
const getPossibleMetrics = () => {
|
||||
let metrics = [];
|
||||
for (let test of myEntriesFromAPI.tests) {
|
||||
let myEval = `${test.metric}.${test.name}`;
|
||||
if (myEval && !metrics.includes(myEval)) {
|
||||
metrics.push(myEval);
|
||||
}
|
||||
}
|
||||
return metrics;
|
||||
};
|
||||
|
||||
const getMyEntriesHeader = () => {
|
||||
let header = ['#'];
|
||||
if (IS_MOBILE()) header.push('when');
|
||||
for (let myEval of getPossibleMetrics()) {
|
||||
header.push(myEval);
|
||||
}
|
||||
if (!IS_MOBILE()) header.push('when');
|
||||
return header;
|
||||
};
|
||||
|
||||
const challengesRequest = () => {
|
||||
getMyEntries(
|
||||
React.useMemo(() => {
|
||||
getEntries(
|
||||
'challenge-my-submissions',
|
||||
props.challengeName,
|
||||
setMyEntriesFromAPI,
|
||||
setMyEntriesAll,
|
||||
setMyEntries,
|
||||
[setMyEntries, setMyEntriesAll],
|
||||
setLoading,
|
||||
setScoresSorted
|
||||
);
|
||||
};
|
||||
}, [props.challengeName]);
|
||||
|
||||
const sortByUpdate = (elem, i) => {
|
||||
let newEntries = 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:
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
let metricIndex = getPossibleMetrics().indexOf(elem);
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
let newScoresSorted = scoresSorted;
|
||||
if (scoresSorted[metricIndex]) {
|
||||
newEntries = newEntries.sort(
|
||||
(a, b) =>
|
||||
(b.evaluations ? b.evaluations[elem] : -1) -
|
||||
(a.evaluations ? a.evaluations[elem] : -1)
|
||||
);
|
||||
newScoresSorted[metricIndex] = false;
|
||||
setScoresSorted(newScoresSorted);
|
||||
} else {
|
||||
newEntries = newEntries.sort(
|
||||
(a, b) =>
|
||||
(a.evaluations ? a.evaluations[elem] : -1) -
|
||||
(b.evaluations ? b.evaluations[elem] : -1)
|
||||
);
|
||||
newScoresSorted[metricIndex] = true;
|
||||
setScoresSorted(newScoresSorted);
|
||||
}
|
||||
break;
|
||||
}
|
||||
setMyEntries(newEntries);
|
||||
};
|
||||
const sortByUpdate = React.useCallback(
|
||||
(elem) => {
|
||||
let newEntries = myEntries.slice();
|
||||
const possibleMetrics = orderKeys(myEntries[0]).filter(
|
||||
(key) => !['id', 'submitter', 'when'].includes(key)
|
||||
);
|
||||
let metricIndex = possibleMetrics.indexOf(elem);
|
||||
let newScoresSorted = scoresSorted.slice();
|
||||
switch (elem) {
|
||||
case 'id':
|
||||
if (idSorted) {
|
||||
setIdSorted(false);
|
||||
newEntries = newEntries.sort((a, b) =>
|
||||
a.id > b.id ? 1 : b.id > a.id ? -1 : 0
|
||||
);
|
||||
} else {
|
||||
setIdSorted(true);
|
||||
newEntries = newEntries.sort((a, b) =>
|
||||
a.id < b.id ? 1 : b.id < a.id ? -1 : 0
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'when':
|
||||
if (whenSorted) {
|
||||
setWhenSorted(false);
|
||||
newEntries = newEntries.sort((a, b) =>
|
||||
a.when < b.when ? 1 : b.when < a.when ? -1 : 0
|
||||
);
|
||||
} else {
|
||||
setWhenSorted(true);
|
||||
newEntries = newEntries.sort((a, b) =>
|
||||
a.when > b.when ? 1 : b.when > a.when ? -1 : 0
|
||||
);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (scoresSorted[metricIndex]) {
|
||||
newEntries = newEntries.sort(
|
||||
(a, b) => (b ? b[elem] : -1) - (a ? a[elem] : -1)
|
||||
);
|
||||
newScoresSorted[metricIndex] = false;
|
||||
setScoresSorted(newScoresSorted);
|
||||
} else {
|
||||
newEntries = newEntries.sort(
|
||||
(a, b) => (a ? a[elem] : -1) - (b ? b[elem] : -1)
|
||||
);
|
||||
newScoresSorted[metricIndex] = true;
|
||||
setScoresSorted(newScoresSorted);
|
||||
}
|
||||
break;
|
||||
}
|
||||
setMyEntries(newEntries);
|
||||
},
|
||||
[idSorted, myEntries, scoresSorted, whenSorted]
|
||||
);
|
||||
|
||||
const mobileRender = () => {
|
||||
return (
|
||||
<FlexColumn padding="24px 12px" width="70%" as="section" id="start">
|
||||
<H2 as="h2" margin="0 0 12px 0">
|
||||
My Entries
|
||||
</H2>
|
||||
{!loading ? (
|
||||
<>
|
||||
<Search searchQueryHandler={searchQueryHandler} />
|
||||
<Table
|
||||
challengeName={props.challengeName}
|
||||
headerElements={getMyEntriesHeader()}
|
||||
possibleMetrics={getPossibleMetrics()}
|
||||
tableType="myEntries"
|
||||
gridTemplateColumns={
|
||||
'1fr ' + '4fr '.repeat(getMyEntriesHeader().length - 1)
|
||||
}
|
||||
staticColumnElements={[
|
||||
{ name: 'id', format: null, order: 1, align: 'left' },
|
||||
{ name: 'when', format: RENDER_WHEN, order: 3, align: 'right' },
|
||||
]}
|
||||
iterableColumnElement={{
|
||||
name: 'evaluations',
|
||||
format: EVALUATIONS_FORMAT,
|
||||
order: 2,
|
||||
align: 'left',
|
||||
}}
|
||||
pageNr={pageNr}
|
||||
elements={myEntries}
|
||||
sortByUpdate={sortByUpdate}
|
||||
/>
|
||||
<Pager
|
||||
pageNr={pageNr}
|
||||
elements={myEntries}
|
||||
setPageNr={setPageNr}
|
||||
width="48px"
|
||||
borderRadius="64px"
|
||||
pages={CALC_PAGES(myEntries)}
|
||||
number={`${pageNr} / ${CALC_PAGES(myEntries)}`}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<Loading />
|
||||
)}
|
||||
</FlexColumn>
|
||||
);
|
||||
};
|
||||
|
||||
const desktopRender = () => {
|
||||
return (
|
||||
<FlexColumn padding="24px" as="section" width="100%" maxWidth="1600px">
|
||||
<FlexColumn padding="24px 12px" width="70%" as="section" id="start">
|
||||
<H2 as="h2" margin="0 0 32px 0">
|
||||
My Entries
|
||||
</H2>
|
||||
</FlexColumn>
|
||||
{myEntries && !loading ? (
|
||||
<>
|
||||
<Search searchQueryHandler={searchQueryHandler} />
|
||||
<Table
|
||||
challengeName={props.challengeName}
|
||||
headerElements={getMyEntriesHeader()}
|
||||
possibleMetrics={getPossibleMetrics()}
|
||||
gridTemplateColumns={
|
||||
'1fr ' + '3fr '.repeat(getMyEntriesHeader().length - 2) + ' 4fr'
|
||||
}
|
||||
staticColumnElements={[
|
||||
{ name: 'id', format: null, order: 1, align: 'left' },
|
||||
{ name: 'when', format: RENDER_WHEN, order: 3, align: 'right' },
|
||||
]}
|
||||
iterableColumnElement={{
|
||||
name: 'evaluations',
|
||||
format: EVALUATIONS_FORMAT,
|
||||
order: 2,
|
||||
align: 'left',
|
||||
}}
|
||||
pageNr={pageNr}
|
||||
elements={myEntries}
|
||||
sortByUpdate={sortByUpdate}
|
||||
myEntries
|
||||
/>
|
||||
<Pager
|
||||
pageNr={pageNr}
|
||||
elements={myEntries}
|
||||
setPageNr={setPageNr}
|
||||
width="72px"
|
||||
mobileRender
|
||||
borderRadius="64px"
|
||||
pages={CALC_PAGES(myEntries, 2)}
|
||||
number={`${pageNr} / ${CALC_PAGES(myEntries, 2)}`}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<Loading />
|
||||
)}
|
||||
</FlexColumn>
|
||||
);
|
||||
};
|
||||
const n = (pageNr - 1) * (ELEMENTS_PER_PAGE * 2);
|
||||
let elements = myEntries.slice(n, n + ELEMENTS_PER_PAGE * 2);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Media query={theme.mobile}>{mobileRender()}</Media>
|
||||
<Media query={theme.desktop}>{desktopRender()}</Media>
|
||||
</>
|
||||
<FlexColumn
|
||||
padding="24px"
|
||||
gap="32px"
|
||||
as="section"
|
||||
width="100%"
|
||||
maxWidth="1600px"
|
||||
>
|
||||
<H2 as="h2">My Entries</H2>
|
||||
{!loading ? (
|
||||
<>
|
||||
<Search
|
||||
searchQueryHandler={(event) =>
|
||||
searchHandler(event, myEntriesAll, setPageNr, setMyEntries)
|
||||
}
|
||||
/>
|
||||
{elements.length > 0 && myEntries[0] && (
|
||||
<Table
|
||||
items={elements}
|
||||
orderedKeys={orderKeys(myEntries[0])}
|
||||
sortByUpdate={sortByUpdate}
|
||||
/>
|
||||
)}
|
||||
<Pager
|
||||
pageNr={pageNr}
|
||||
elements={myEntries}
|
||||
setPageNr={setPageNr}
|
||||
width="72px"
|
||||
borderRadius="64px"
|
||||
pages={CALC_PAGES(myEntries, 2)}
|
||||
number={`${pageNr} / ${CALC_PAGES(myEntries, 2)}`}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<Loading />
|
||||
)}
|
||||
</FlexColumn>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
const myEntriesSearchQueryHandler = (
|
||||
event,
|
||||
entriesFromApi,
|
||||
setPageNr,
|
||||
setEntries
|
||||
) => {
|
||||
let searchQuery = event.target.value;
|
||||
let submissionsToRender = [];
|
||||
setPageNr(1);
|
||||
if (searchQuery === '') setEntries(entriesFromApi);
|
||||
else {
|
||||
for (let entry of entriesFromApi) {
|
||||
const { id, when } = entry;
|
||||
let evaluations = '';
|
||||
if (entry.evaluations) {
|
||||
for (let evaluation of Object.values(entry.evaluations)) {
|
||||
evaluations += ` ${evaluation}`;
|
||||
}
|
||||
}
|
||||
const str = `${id} ${when.slice(11, 16)} ${when.slice(
|
||||
0,
|
||||
10
|
||||
)} ${evaluations}`;
|
||||
console.log(entry);
|
||||
console.log(str);
|
||||
if (str.toLowerCase().includes(searchQuery.toLowerCase()))
|
||||
submissionsToRender.push(entry);
|
||||
}
|
||||
setEntries(submissionsToRender);
|
||||
}
|
||||
};
|
||||
|
||||
export default myEntriesSearchQueryHandler;
|
23
src/pages/MyEntries/orderKeys.js
Normal file
23
src/pages/MyEntries/orderKeys.js
Normal file
@ -0,0 +1,23 @@
|
||||
const orderKeys = (elem) => {
|
||||
if (elem) {
|
||||
let result = ['id'];
|
||||
const elemKeys = Object.keys(elem);
|
||||
const dev0keys = elemKeys
|
||||
.filter((key) => key.split('.')[1] === 'dev-0')
|
||||
.sort();
|
||||
const dev1keys = elemKeys
|
||||
.filter((key) => key.split('.')[1] === 'dev-1')
|
||||
.sort();
|
||||
const testAkeys = elemKeys
|
||||
.filter((key) => key.split('.')[1] === 'test-A')
|
||||
.sort();
|
||||
result = result.concat(dev0keys);
|
||||
result = result.concat(dev1keys);
|
||||
result = result.concat(testAkeys);
|
||||
result.push('when');
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export default orderKeys;
|
28
src/pages/MyEntries/searchHandler.js
Normal file
28
src/pages/MyEntries/searchHandler.js
Normal file
@ -0,0 +1,28 @@
|
||||
const searchQueryHandler = (event, entriesAll, setPageNr, setEntries) => {
|
||||
let searchQuery = event.target.value;
|
||||
let submissionsToRender = [];
|
||||
setPageNr(1);
|
||||
if (searchQuery === '') setEntries(entriesAll);
|
||||
else {
|
||||
for (let entry of entriesAll) {
|
||||
let { when, tags } = entry;
|
||||
tags = Object.values(tags)
|
||||
.map((tag) => tag.name)
|
||||
.join(' ');
|
||||
const otherKeys = Object.values(entry)
|
||||
.join(' ')
|
||||
.replaceAll(-999999999, 'N/A')
|
||||
.replaceAll('[object Object]', '')
|
||||
.replaceAll(',', '');
|
||||
const str = `${when.slice(11, 16)} ${when.slice(
|
||||
0,
|
||||
10
|
||||
)} ${otherKeys} ${tags}`;
|
||||
if (str.toLowerCase().includes(searchQuery.toLowerCase()))
|
||||
submissionsToRender.push(entry);
|
||||
}
|
||||
setEntries(submissionsToRender);
|
||||
}
|
||||
};
|
||||
|
||||
export default searchQueryHandler;
|
Loading…
Reference in New Issue
Block a user