From f7c5c9e665d991bd2e1722e83cfc9f62ae3f0b04 Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Wed, 5 Jul 2023 14:21:57 -0400 Subject: [PATCH 01/15] Homepage draft --- src/App.css | 29 ++- src/components/CategoryItemBox.js | 58 +++--- src/components/CategoryItemIcon.js | 8 +- src/components/CategoryScroll.js | 68 ++++--- src/components/SotaChart.js | 169 +++++++++--------- src/components/SubscribeButton.js | 2 +- .../simple-react-footer/SimpleReactFooter.js | 8 +- src/views/Tasks.js | 61 +++++-- 8 files changed, 241 insertions(+), 162 deletions(-) diff --git a/src/App.css b/src/App.css index 023acd9c..9abe73e1 100644 --- a/src/App.css +++ b/src/App.css @@ -204,10 +204,19 @@ form > span > .row > label { padding: 12px; } +.task { + padding: 16px; +} + +.submission-cell { + padding: 8px; + width: 33%; +} + .submission { border-radius: 16px; - margin: 6px; padding: 8px; + margin: 6px; background-color: #FFFFFF; } @@ -215,6 +224,11 @@ form > span > .row > label { box-shadow: 0 0 16px rgba(33,33,33,.2); } +.category-item-box { + display: inline-block; + height: 128px; +} + .delete-button { position: relative; top: -8px; @@ -300,6 +314,12 @@ form > span > .row > label { text-align: left; } +.category-item-icon { + width: 22%; + display: inline-block; + padding-left: 24px; +} + .edit-button { width: 80px; height: 40px; @@ -372,6 +392,13 @@ form > span > .row > label { width: 100%; } +.sota-preview { + display: inline-block; + height: 300px; + width: 450px; + padding: 32px 0 16px 0; +} + iframe { display: block; border-style:none; diff --git a/src/components/CategoryItemBox.js b/src/components/CategoryItemBox.js index eea3fee2..1246ac02 100644 --- a/src/components/CategoryItemBox.js +++ b/src/components/CategoryItemBox.js @@ -60,33 +60,37 @@ const CategoryItemBox = (props) => { } return ( - - -
-
- - {props.type !== 'tag' && props.item.description && -
-
- {props.item.name} - {props.type === 'task' && qedcIds.includes(parseInt(props.item.id)) && - (QED-C)} -
-
{renderLatex(props.item.description)}
-
} - {(props.type === 'tag' || !props.item.description) && -
{props.item.name}
} - -
-
- -
- - - -
- - + +
+ + {props.type !== 'tag' && props.item.description && +
+
+ {props.item.name} + {props.type === 'task' && qedcIds.includes(parseInt(props.item.id)) && + (QED-C)} +
+
{renderLatex( + !props.item.description + ? '' + : ((!props.isPreview && (props.item.description.length > 128)) + ? (props.item.description.substring(0, 125) + '...') + : props.item.description))} +
+
} + {(props.type === 'tag' || !props.item.description) && +
{props.item.name}
} + +
+ + {!props.isPreview && + + + + + } +
+ ) } diff --git a/src/components/CategoryItemIcon.js b/src/components/CategoryItemIcon.js index 5912e74d..5e525cb9 100644 --- a/src/components/CategoryItemIcon.js +++ b/src/components/CategoryItemIcon.js @@ -3,10 +3,8 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import TooltipTrigger from './TooltipTrigger' const CategoryItemIcon = (props) => -
- -
{props.count}
-
-
+ +
{props.count}
+
export default CategoryItemIcon diff --git a/src/components/CategoryScroll.js b/src/components/CategoryScroll.js index 2ad76088..6d9ae1da 100644 --- a/src/components/CategoryScroll.js +++ b/src/components/CategoryScroll.js @@ -1,35 +1,55 @@ -import React, { Suspense } from 'react' +import React, { Suspense, useEffect, useState } from 'react' import FormFieldWideRow from './FormFieldWideRow' const CategoryItemBox = React.lazy(() => import('./CategoryItemBox')) -const CategoryScroll = (props) => -
-
- {props.heading && +const CategoryScroll = (props) => { + const [rows, setRows] = useState([]) + + useEffect(() => { + const rws = [] + for (let i = 0; i < props.items.length / 3; ++i) { + const row = [] + for (let j = 0; j < 3; ++j) { + if ((3 * i + j) >= props.items.length) { + break + } + row.push(props.items[3 * i + j]) + } + rws.push(row) + } + setRows(rws) + }, [props.items]) + + return ( +
+
+ {props.heading && + +

{props.heading}

+
} - {props.heading} - } - - {!props.items.length && + {!props.items.length && (props.isLoading ?

Fetching items from server...

:

There are no approved items, yet.

)} - {(props.items.length > 0) && - Loading...
}> -
-
-
- - - {props.items.map((item, index) => )} - -
+ {(props.items.length > 0) && + Loading...
}> +
+
+
+ + + {rows.map((row, rid) => {row.map((item, id) => )})} + +
+
-
- } - -
-
+ } + +
+
+ ) +} export default CategoryScroll diff --git a/src/components/SotaChart.js b/src/components/SotaChart.js index 024edc01..0ddc4eba 100644 --- a/src/components/SotaChart.js +++ b/src/components/SotaChart.js @@ -415,7 +415,7 @@ class SotaChart extends React.Component { return (type === 'scatter') } }, - datalabels: this.state.windowWidth < 820 + datalabels: (this.props.isPreview || (this.state.windowWidth < 820)) ? { display: false } : { font: { weight: '600', color: '#000000' }, @@ -425,6 +425,7 @@ class SotaChart extends React.Component { } }, legend: { + display: !this.props.isPreview, labels: { filter: function (item, chart) { // Logic to remove a particular legend item goes here @@ -630,32 +631,33 @@ class SotaChart extends React.Component { return (
- - ({ - id: name, - name - }))} - onChange={(field, value) => { - this.setState({ chartKey: value }) - this.loadChartFromState({ - subset: this.state.subset, - label: this.state.label, - metricNames: this.state.metricNames, - chartKey: value, - chartData: this.state.chartData, - isLowerBetterDict: this.state.isLowerBetterDict, - isLog: this.state.isLog, - log: this.state.log - }) - }} - tooltip='A metric performance measure of any "method" on this "task"' - /> - {this.state.isSubset && + {!this.props.isPreview && + + ({ + id: name, + name + }))} + onChange={(field, value) => { + this.setState({ chartKey: value }) + this.loadChartFromState({ + subset: this.state.subset, + label: this.state.label, + metricNames: this.state.metricNames, + chartKey: value, + chartData: this.state.chartData, + isLowerBetterDict: this.state.isLowerBetterDict, + isLog: this.state.isLog, + log: this.state.log + }) + }} + tooltip='A metric performance measure of any "method" on this "task"' + />} + {!this.props.isPreview && this.state.isSubset &&
} -
- -
- -
- -
- -
- -
- -
-
+ {!this.props.isPreview && +
+ +
+ +
+ +
+ +
+ +
+ +
+
} -
+
diff --git a/src/components/SubscribeButton.js b/src/components/SubscribeButton.js index fbfc157c..fef57bc1 100644 --- a/src/components/SubscribeButton.js +++ b/src/components/SubscribeButton.js @@ -5,7 +5,7 @@ const SubscribeButton = (props) => {!props.isSubscribed && - + } {props.isSubscribed && diff --git a/src/components/simple-react-footer/SimpleReactFooter.js b/src/components/simple-react-footer/SimpleReactFooter.js index f39531d6..adadcd7a 100644 --- a/src/components/simple-react-footer/SimpleReactFooter.js +++ b/src/components/simple-react-footer/SimpleReactFooter.js @@ -50,8 +50,8 @@ class SimpleReactFooter extends React.Component {
- Quantum computing benchmarks by community contributors made with
by Unitary Fund logo
-
+ Quantum computing benchmarks by community contributors made with
by Unitary Fund logo
+
Stay up to date on metriq.info! Subscribe now to our newsletter: 
- Follow us on social media
-
+ Follow us on social media
+
{(this.props.facebook !== undefined || this.props.linkedin !== undefined || this.props.instagram !== undefined || this.props.twitter !== undefined || this.props.pinterest !== undefined || this.props.youtube !== undefined) &&
{this.props.facebook !== undefined ? : ''} diff --git a/src/views/Tasks.js b/src/views/Tasks.js index 7d50d22d..8645059a 100644 --- a/src/views/Tasks.js +++ b/src/views/Tasks.js @@ -5,13 +5,19 @@ import ErrorHandler from '../components/ErrorHandler' import FormFieldValidator from '../components/FormFieldValidator' import FormFieldTypeaheadRow from '../components/FormFieldTypeaheadRow' import CategoryScroll from '../components/CategoryScroll' -import CategoryItemBox from '../components/CategoryItemBox' +import CategoryItemIcon from '../components/CategoryItemIcon' import FormFieldAlertRow from '../components/FormFieldAlertRow' import FormFieldWideRow from '../components/FormFieldWideRow' import ViewHeader from '../components/ViewHeader' import { sortAlphabetical } from '../components/SortFunctions' import SotaChart from '../components/SotaChart' -import { withRouter } from 'react-router-dom' +import { withRouter, Link } from 'react-router-dom' +import { library } from '@fortawesome/fontawesome-svg-core' +import { faHeart, faExternalLinkAlt, faChartLine } from '@fortawesome/free-solid-svg-icons' + +library.add(faHeart, faExternalLinkAlt, faChartLine) + +const qedcIds = [34, 2, 97, 142, 150, 172, 173, 174, 175, 176, 177, 178, 179] class Tasks extends React.Component { constructor (props) { @@ -79,7 +85,7 @@ class Tasks extends React.Component { return (
Tasks -
Tasks are workloads of interest performed on a quantum computer.
+

Tasks are workloads of interest performed on a quantum computer.

Search the task hierarchy to see charts of comparative performance across methods, see our submitter leader board and featured task charts, or click into the parent/child task hierarchy through top-level task categories.



-
Featured
+

Featured

{this.state.featured.map((item, index) => { return (
-
- - - - - +
+
+ + + + + + + + +
+ + +
+ {item.name} + {qedcIds.includes(parseInt(item.id)) && + (QED-C)} +
+ {item.description} +

+ {item.parentTask.name} + + + + +
From c4b9eeea8ee5a3f4e015611dfbe9fcb8fe7e3c20 Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Wed, 5 Jul 2023 15:12:31 -0400 Subject: [PATCH 02/15] Top submitters on homepage --- src/App.css | 5 +- src/MainRouter.js | 18 +-- src/components/SotaChart.js | 4 +- src/components/TopSubmitters.js | 135 ++++++++++++++++++++ src/views/Home.js | 213 -------------------------------- src/views/Submissions.js | 94 ++++++++++++++ src/views/Tasks.js | 97 ++++++++------- 7 files changed, 295 insertions(+), 271 deletions(-) create mode 100644 src/components/TopSubmitters.js delete mode 100644 src/views/Home.js create mode 100644 src/views/Submissions.js diff --git a/src/App.css b/src/App.css index 9abe73e1..bcb0c947 100644 --- a/src/App.css +++ b/src/App.css @@ -394,9 +394,8 @@ form > span > .row > label { .sota-preview { display: inline-block; - height: 300px; - width: 450px; - padding: 32px 0 16px 0; + height: 256px; + width: 256px; } iframe { diff --git a/src/MainRouter.js b/src/MainRouter.js index f6c7d352..aba74bff 100644 --- a/src/MainRouter.js +++ b/src/MainRouter.js @@ -2,7 +2,7 @@ import { BrowserRouter as Router, Redirect, Route, Switch } from 'react-router-d import axios from 'axios' import React, { useState } from 'react' import config from './config' -import Home from './views/Home' +import Submissions from './views/Submissions' import LogIn from './views/LogIn' import Register from './views/Register' import Delete from './views/Delete' @@ -66,25 +66,25 @@ const MainRouter = (props) => { exact path='/Submissions/' > - + - + - + - + { } + render={(p) => } /> } + render={(p) => } /> } + render={(p) => } /> } + render={(p) => } /> = 820 ? 40 : 8, - right: this.state.windowWidth >= 820 ? 100 : 16 + left: this.props.isPreview ? 0 : ((this.state.windowWidth >= 820) ? 40 : 8), + right: this.props.isPreview ? 0 : ((this.state.windowWidth >= 820) ? 100 : 16) } }, scales: { diff --git a/src/components/TopSubmitters.js b/src/components/TopSubmitters.js new file mode 100644 index 00000000..fb4b385e --- /dev/null +++ b/src/components/TopSubmitters.js @@ -0,0 +1,135 @@ +import React, { useEffect, useState } from 'react' +import axios from 'axios' +import { Tabs, Tab } from 'react-bootstrap' +import config from '../config' +import SortingTable from '../components/SortingTable' + +const TopSubmitters = (props) => { + const [data, setData] = useState({ weekly: [], monthly: [], allTime: [] }) + useEffect(() => { + axios.get(config.api.getUriPrefix() + '/user/topSubmitters') + .then(res => { + const tSubmitters = res.data.data + tSubmitters.weekly[0].rank = '🥇' + tSubmitters.weekly[1].rank = '🥈' + tSubmitters.weekly[2].rank = '🥉' + tSubmitters.monthly[0].rank = '🥇' + tSubmitters.monthly[1].rank = '🥈' + tSubmitters.monthly[2].rank = '🥉' + tSubmitters.allTime[0].rank = '🥇' + tSubmitters.allTime[1].rank = '🥈' + tSubmitters.allTime[2].rank = '🥉' + + const ts = { weekly: [], monthly: [], allTime: [] } + for (let i = 0; i < 3; ++i) { + if (tSubmitters.weekly[i].submissionsCount > 0) { + ts.weekly.push(tSubmitters.weekly[i]) + } + if (tSubmitters.monthly[i].submissionsCount > 0) { + ts.monthly.push(tSubmitters.monthly[i]) + } + if (tSubmitters.allTime[i].submissionsCount > 0) { + ts.allTime.push(tSubmitters.allTime[i]) + } + } + + setData(ts) + }) + }) + return ( + +
Top Submitters
+ + {(data.weekly.length > 0) && + +
+ this.props.history.push('/User/' + record.id + '/Submissions')} + tableLayout='auto' + rowClassName='link' + /> +
+
} + {(data.monthly.length > 0) && + +
+ this.props.history.push('/User/' + record.id + '/Submissions')} + tableLayout='auto' + rowClassName='link' + /> +
+
} + {(data.allTime.length > 0) && + +
+ this.props.history.push('/User/' + record.id + '/Submissions')} + tableLayout='auto' + rowClassName='link' + /> +
+
} +
+
+ ) +} + +export default TopSubmitters diff --git a/src/views/Home.js b/src/views/Home.js deleted file mode 100644 index d918794f..00000000 --- a/src/views/Home.js +++ /dev/null @@ -1,213 +0,0 @@ -import axios from 'axios' -import config from '../config' -import ErrorHandler from '../components/ErrorHandler' -import React, { useEffect, useState, Suspense } from 'react' -import { Tabs, Tab } from 'react-bootstrap' -import { useHistory, useParams } from 'react-router-dom' -import ViewHeader from '../components/ViewHeader' -import SubmissionScroll from '../components/SubmissionScroll' -import SubscribeButton from '../components/SubscribeButton' -const SortingTable = React.lazy(() => import('../components/SortingTable')) - -// See https://stackoverflow.com/questions/71663319/react-navigate-to-react-bootstrap-tab-with-history#answer-71668423 -const DEFAULT_INITIAL_TAB = 'Trending' - -const Home = (props) => { - const { tag } = useParams() - const history = useHistory() - const [activeTab, setActiveTab] = useState(DEFAULT_INITIAL_TAB) - const [isSubscribed, setIsSubscribed] = useState(false) - const [topSubmitters, setTopSubmitters] = useState({ weekly: [], monthly: [], allTime: [] }) - - useEffect(() => { - axios.get(config.api.getUriPrefix() + '/user/topSubmitters') - .then(res => { - const tSubmitters = res.data.data - tSubmitters.weekly[0].rank = '🥇' - tSubmitters.weekly[1].rank = '🥈' - tSubmitters.weekly[2].rank = '🥉' - tSubmitters.monthly[0].rank = '🥇' - tSubmitters.monthly[1].rank = '🥈' - tSubmitters.monthly[2].rank = '🥉' - tSubmitters.allTime[0].rank = '🥇' - tSubmitters.allTime[1].rank = '🥈' - tSubmitters.allTime[2].rank = '🥉' - - const ts = { weekly: [], monthly: [], allTime: [] } - for (let i = 0; i < 3; ++i) { - if (tSubmitters.weekly[i].submissionsCount > 0) { - ts.weekly.push(tSubmitters.weekly[i]) - } - if (tSubmitters.monthly[i].submissionsCount > 0) { - ts.monthly.push(tSubmitters.monthly[i]) - } - if (tSubmitters.allTime[i].submissionsCount > 0) { - ts.allTime.push(tSubmitters.allTime[i]) - } - } - - setTopSubmitters(ts) - }) - - if (!props.tabKey) { - window.scrollTo(0, 0) - history.replace(tag ? `/Tag/${tag}/${DEFAULT_INITIAL_TAB}` : `/Submissions/${DEFAULT_INITIAL_TAB}`) - } - setActiveTab(props.tabKey) - - if (!props.match) { - return - } - - axios.get(config.api.getUriPrefix() + '/tag/' + encodeURIComponent(props.match.params.tag)) - .then(res => { - setIsSubscribed(res.data.data.isSubscribed) - }) - .catch(err => { - window.alert('Error: ' + ErrorHandler(err) + '\nSorry! Check your connection and login status, and try again.') - }) - }, [props, history, tag]) - - const toggle = (tab) => { - if (props.tabKey !== tab) { - history.replace(tag ? `/Tag/${tag}/${tab}` : `/Submissions/${tab}`) - } - setActiveTab(tab) - } - - const handleLoginRedirect = () => { - props.history.push('/Login/' + encodeURIComponent('Tag/' + props.match.params.tag + '/' + props.tabKey)) - } - - const handleSubscribe = () => { - if (props.isLoggedIn) { - axios.post(config.api.getUriPrefix() + '/tag/' + encodeURIComponent(props.match.params.tag) + '/subscribe', {}) - .then(res => { - setIsSubscribed(res.data.data) - }) - .catch(err => { - window.alert('Error: ' + ErrorHandler(err) + '\nSorry! Check your connection and login status, and try again.') - }) - } else { - handleLoginRedirect() - } - } - - return ( -
-
Top Submitters
- Loading...
}> - - {(topSubmitters.weekly.length > 0) && - -
- this.props.history.push('/User/' + record.id + '/Submissions')} - tableLayout='auto' - rowClassName='link' - /> -
-
} - {(topSubmitters.monthly.length > 0) && - -
- this.props.history.push('/User/' + record.id + '/Submissions')} - tableLayout='auto' - rowClassName='link' - /> -
-
} - {(topSubmitters.allTime.length > 0) && - -
- this.props.history.push('/User/' + record.id + '/Submissions')} - tableLayout='auto' - rowClassName='link' - /> -
-
} -
- -
-
- - Top Submissions {props.match ? 'for "' + props.match.params.tag + '"' : ''} - {props.match && -  } - -
- - - - - - - - - - - -
- ) -} - -export default Home diff --git a/src/views/Submissions.js b/src/views/Submissions.js new file mode 100644 index 00000000..c3983119 --- /dev/null +++ b/src/views/Submissions.js @@ -0,0 +1,94 @@ +import axios from 'axios' +import config from '../config' +import ErrorHandler from '../components/ErrorHandler' +import React, { useEffect, useState, Suspense } from 'react' +import { Tabs, Tab } from 'react-bootstrap' +import { useHistory, useParams } from 'react-router-dom' +import ViewHeader from '../components/ViewHeader' +import SubmissionScroll from '../components/SubmissionScroll' +import SubscribeButton from '../components/SubscribeButton' +const TopSubmitters = React.lazy(() => import('../components/TopSubmitters')) + +// See https://stackoverflow.com/questions/71663319/react-navigate-to-react-bootstrap-tab-with-history#answer-71668423 +const DEFAULT_INITIAL_TAB = 'Trending' + +const Submissions = (props) => { + const { tag } = useParams() + const history = useHistory() + const [activeTab, setActiveTab] = useState(DEFAULT_INITIAL_TAB) + const [isSubscribed, setIsSubscribed] = useState(false) + + useEffect(() => { + if (!props.tabKey) { + window.scrollTo(0, 0) + history.replace(tag ? `/Tag/${tag}/${DEFAULT_INITIAL_TAB}` : `/Submissions/${DEFAULT_INITIAL_TAB}`) + } + setActiveTab(props.tabKey) + + if (!props.match) { + return + } + + axios.get(config.api.getUriPrefix() + '/tag/' + encodeURIComponent(props.match.params.tag)) + .then(res => { + setIsSubscribed(res.data.data.isSubscribed) + }) + .catch(err => { + window.alert('Error: ' + ErrorHandler(err) + '\nSorry! Check your connection and login status, and try again.') + }) + }, [props, history, tag]) + + const toggle = (tab) => { + if (props.tabKey !== tab) { + history.replace(tag ? `/Tag/${tag}/${tab}` : `/Submissions/${tab}`) + } + setActiveTab(tab) + } + + const handleLoginRedirect = () => { + props.history.push('/Login/' + encodeURIComponent('Tag/' + props.match.params.tag + '/' + props.tabKey)) + } + + const handleSubscribe = () => { + if (props.isLoggedIn) { + axios.post(config.api.getUriPrefix() + '/tag/' + encodeURIComponent(props.match.params.tag) + '/subscribe', {}) + .then(res => { + setIsSubscribed(res.data.data) + }) + .catch(err => { + window.alert('Error: ' + ErrorHandler(err) + '\nSorry! Check your connection and login status, and try again.') + }) + } else { + handleLoginRedirect() + } + } + + return ( +
+ Loading...
}> + + +
+
+ + Top Submissions {props.match ? 'for "' + props.match.params.tag + '"' : ''} + {props.match && +  } + +
+ + + + + + + + + + + +
+ ) +} + +export default Submissions diff --git a/src/views/Tasks.js b/src/views/Tasks.js index 8645059a..5b65d81f 100644 --- a/src/views/Tasks.js +++ b/src/views/Tasks.js @@ -14,6 +14,7 @@ import SotaChart from '../components/SotaChart' import { withRouter, Link } from 'react-router-dom' import { library } from '@fortawesome/fontawesome-svg-core' import { faHeart, faExternalLinkAlt, faChartLine } from '@fortawesome/free-solid-svg-icons' +import TopSubmitters from '../components/TopSubmitters' library.add(faHeart, faExternalLinkAlt, faChartLine) @@ -30,6 +31,7 @@ class Tasks extends React.Component { trending: [], popular: [], latest: [], + topSubmitters: [], filterId: null, requestFailedMessage: '' } @@ -101,51 +103,58 @@ class Tasks extends React.Component { />
-

Featured

- {this.state.featured.map((item, index) => { - return ( -
-
-
- - - - - - - - - - -
- - -
- {item.name} - {qedcIds.includes(parseInt(item.id)) && - (QED-C)} -
- {item.description} -

- {item.parentTask.name} - - - - -
+
+
+

Featured

+ {this.state.featured.map((item, index) => { + return ( +
+
+
+ + + + + + + + + + +
+ + +
+ {item.name} + {qedcIds.includes(parseInt(item.id)) && + (QED-C)} +
+ {item.description} +

+ {item.parentTask.name} + + + + +
+
+
-
-
- ) - })} + ) + })} +
+
+ +
+

From aaa46585b90f4d076bcc4b341792b76acd48ce26 Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Thu, 6 Jul 2023 15:45:15 -0400 Subject: [PATCH 03/15] Add follow button --- src/components/CategoryItemBox.js | 42 ++-------------- src/components/SubscribeButton.js | 62 +++++++++++++++++++---- src/components/TopSubmitters.js | 3 ++ src/views/Submissions.js | 20 +------- src/views/Tasks.js | 84 +++++++++++++++---------------- 5 files changed, 100 insertions(+), 111 deletions(-) diff --git a/src/components/CategoryItemBox.js b/src/components/CategoryItemBox.js index 1246ac02..c520c5ce 100644 --- a/src/components/CategoryItemBox.js +++ b/src/components/CategoryItemBox.js @@ -1,12 +1,9 @@ -import React, { useState } from 'react' -import axios from 'axios' +import React from 'react' import CategoryItemIcon from './CategoryItemIcon' import SubscribeButton from './SubscribeButton' -import { useHistory, Link } from 'react-router-dom' +import { Link } from 'react-router-dom' import { library } from '@fortawesome/fontawesome-svg-core' import { faHeart, faExternalLinkAlt, faChartLine } from '@fortawesome/free-solid-svg-icons' -import config from '../config' -import ErrorHandler from './ErrorHandler' import { renderLatex } from '../components/RenderLatex' library.add(faHeart, faExternalLinkAlt, faChartLine) @@ -26,39 +23,6 @@ const pickDetailUrl = (type, item) => { } const CategoryItemBox = (props) => { - const history = useHistory() - const [isSubscribed, setIsSubscribed] = useState(props.item.isSubscribed) - - const handleLoginRedirect = (type) => { - if (type === 'tag') { - history.push('/Login/Tags') - } else if (type === 'task') { - history.push('/Login/Tasks') - } else if (type === 'method') { - history.push('/Login/Methods') - } else if (type === 'platform') { - history.push('/Login/Platforms') - } - } - - const handleSubscribe = () => { - if (props.isLoggedIn) { - axios.post(config.api.getUriPrefix() + '/' + props.type + '/' + (props.type === 'tag' ? encodeURIComponent(props.item.name) : props.item.id) + '/subscribe', {}) - .then(res => { - if (props.type === 'tag') { - setIsSubscribed(res.data.data) - } else { - setIsSubscribed(!!res.data.data.isSubscribed) - } - }) - .catch(err => { - window.alert('Error: ' + ErrorHandler(err) + '\nSorry! Check your connection and login status, and try again.') - }) - } else { - handleLoginRedirect(props.type) - } - } - return (
@@ -82,7 +46,7 @@ const CategoryItemBox = (props) => {
{props.item.name}
}
- + {!props.isPreview && diff --git a/src/components/SubscribeButton.js b/src/components/SubscribeButton.js index fef57bc1..9e8b5094 100644 --- a/src/components/SubscribeButton.js +++ b/src/components/SubscribeButton.js @@ -1,16 +1,56 @@ +import React, { useState } from 'react' +import axios from 'axios' import { Button } from 'react-bootstrap' +import { useHistory } from 'react-router-dom' import TooltipTrigger from './TooltipTrigger' +import config from '../config' +import ErrorHandler from './ErrorHandler' -const SubscribeButton = (props) => - - {!props.isSubscribed && - - - } - {props.isSubscribed && - - - } - +const SubscribeButton = (props) => { + const history = useHistory() + const [isSubscribed, setIsSubscribed] = useState(props.item.isSubscribed) + + const handleLoginRedirect = (type) => { + if (type === 'tag') { + history.push('/Login/Tags') + } else if (type === 'task') { + history.push('/Login/Tasks') + } else if (type === 'method') { + history.push('/Login/Methods') + } else if (type === 'platform') { + history.push('/Login/Platforms') + } + } + const handleSubscribe = () => { + if (props.isLoggedIn) { + axios.post(config.api.getUriPrefix() + '/' + props.type + '/' + (props.type === 'tag' ? encodeURIComponent(props.item.name) : props.item.id) + '/subscribe', {}) + .then(res => { + if (props.type === 'tag') { + setIsSubscribed(res.data.data) + } else { + setIsSubscribed(!!res.data.data.isSubscribed) + } + }) + .catch(err => { + window.alert('Error: ' + ErrorHandler(err) + '\nSorry! Check your connection and login status, and try again.') + }) + } else { + handleLoginRedirect(props.type) + } + } + + return ( + + {!isSubscribed && + + + } + {isSubscribed && + + + } + + ) +} export default SubscribeButton diff --git a/src/components/TopSubmitters.js b/src/components/TopSubmitters.js index fb4b385e..892b467c 100644 --- a/src/components/TopSubmitters.js +++ b/src/components/TopSubmitters.js @@ -7,6 +7,9 @@ import SortingTable from '../components/SortingTable' const TopSubmitters = (props) => { const [data, setData] = useState({ weekly: [], monthly: [], allTime: [] }) useEffect(() => { + if (data.allTime.length) { + return + } axios.get(config.api.getUriPrefix() + '/user/topSubmitters') .then(res => { const tSubmitters = res.data.data diff --git a/src/views/Submissions.js b/src/views/Submissions.js index c3983119..f9fa461f 100644 --- a/src/views/Submissions.js +++ b/src/views/Submissions.js @@ -45,24 +45,6 @@ const Submissions = (props) => { setActiveTab(tab) } - const handleLoginRedirect = () => { - props.history.push('/Login/' + encodeURIComponent('Tag/' + props.match.params.tag + '/' + props.tabKey)) - } - - const handleSubscribe = () => { - if (props.isLoggedIn) { - axios.post(config.api.getUriPrefix() + '/tag/' + encodeURIComponent(props.match.params.tag) + '/subscribe', {}) - .then(res => { - setIsSubscribed(res.data.data) - }) - .catch(err => { - window.alert('Error: ' + ErrorHandler(err) + '\nSorry! Check your connection and login status, and try again.') - }) - } else { - handleLoginRedirect() - } - } - return (
Loading...
}> @@ -73,7 +55,7 @@ const Submissions = (props) => { Top Submissions {props.match ? 'for "' + props.match.params.tag + '"' : ''} {props.match && -  } +  }
diff --git a/src/views/Tasks.js b/src/views/Tasks.js index 5b65d81f..309abec8 100644 --- a/src/views/Tasks.js +++ b/src/views/Tasks.js @@ -6,6 +6,7 @@ import FormFieldValidator from '../components/FormFieldValidator' import FormFieldTypeaheadRow from '../components/FormFieldTypeaheadRow' import CategoryScroll from '../components/CategoryScroll' import CategoryItemIcon from '../components/CategoryItemIcon' +import SubscribeButton from '../components/SubscribeButton' import FormFieldAlertRow from '../components/FormFieldAlertRow' import FormFieldWideRow from '../components/FormFieldWideRow' import ViewHeader from '../components/ViewHeader' @@ -106,50 +107,49 @@ class Tasks extends React.Component {

Featured

- {this.state.featured.map((item, index) => { - return ( -
-
-
- - - - - - - - - - -
- - -
- {item.name} - {qedcIds.includes(parseInt(item.id)) && - (QED-C)} -
- {item.description} -

- {item.parentTask.name} - - - - -
-
+ {this.state.featured.map((item, index) => +
+
+
+ + + + + + + + + + +
+ + +
+ {item.name} + {qedcIds.includes(parseInt(item.id)) && + (QED-C)} + +
+ {item.description} +

+ {item.parentTask.name} + + + + +
- ) - })} +
+ )}
From 89bfe2a17f810d36abeff9e48d338bd41a711f63 Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Thu, 6 Jul 2023 16:41:53 -0400 Subject: [PATCH 04/15] Debug detail views --- src/App.css | 5 +++ src/views/Method.js | 17 +--------- src/views/Platform.js | 17 +--------- src/views/Task.js | 17 +--------- src/views/Tasks.js | 77 +++++++++++++++++++++++++++++++++++-------- 5 files changed, 71 insertions(+), 62 deletions(-) diff --git a/src/App.css b/src/App.css index bcb0c947..9530ec08 100644 --- a/src/App.css +++ b/src/App.css @@ -320,6 +320,11 @@ form > span > .row > label { padding-left: 24px; } +.platforms-more-button { + background-color: #68D0F4; + margin-left: 24px; +} + .edit-button { width: 80px; height: 40px; diff --git a/src/views/Method.js b/src/views/Method.js index cf9ce767..2b226380 100644 --- a/src/views/Method.js +++ b/src/views/Method.js @@ -38,7 +38,6 @@ class Method extends React.Component { } this.fetchData = this.fetchData.bind(this) - this.handleSubscribe = this.handleSubscribe.bind(this) this.handleShowEditModal = this.handleShowEditModal.bind(this) this.handleHideEditModal = this.handleHideEditModal.bind(this) this.handleEditModalDone = this.handleEditModalDone.bind(this) @@ -50,20 +49,6 @@ class Method extends React.Component { this.props.history.push('/Login/' + encodeURIComponent('Method/' + this.props.match.params.id)) } - handleSubscribe () { - if (this.props.isLoggedIn) { - axios.post(config.api.getUriPrefix() + '/method/' + this.props.match.params.id + '/subscribe', {}) - .then(res => { - this.setState({ item: res.data.data }) - }) - .catch(err => { - window.alert('Error: ' + ErrorHandler(err) + '\nSorry! Check your connection and login status, and try again.') - }) - } else { - this.handleLoginRedirect() - } - } - handleShowEditModal () { let mode = 'Edit' if (!this.props.isLoggedIn) { @@ -187,7 +172,7 @@ class Method extends React.Component { - +
diff --git a/src/views/Platform.js b/src/views/Platform.js index d9397d22..b300b730 100644 --- a/src/views/Platform.js +++ b/src/views/Platform.js @@ -73,7 +73,6 @@ class Platform extends React.Component { } this.fetchData = this.fetchData.bind(this) - this.handleSubscribe = this.handleSubscribe.bind(this) this.handleAccordionToggle = this.handleAccordionToggle.bind(this) this.handleShowEditModal = this.handleShowEditModal.bind(this) this.handleHideEditModal = this.handleHideEditModal.bind(this) @@ -98,20 +97,6 @@ class Platform extends React.Component { this.props.history.push('/Login/' + encodeURIComponent('Platform/' + this.props.match.params.id)) } - handleSubscribe () { - if (this.props.isLoggedIn) { - axios.post(config.api.getUriPrefix() + '/platform/' + this.props.match.params.id + '/subscribe', {}) - .then(res => { - this.setState({ item: res.data.data }) - }) - .catch(err => { - window.alert('Error: ' + ErrorHandler(err) + '\nSorry! Check your connection and login status, and try again.') - }) - } else { - this.handleLoginRedirect() - } - } - handleAccordionToggle () { this.setState({ showAccordion: !this.state.showAccordion, isValidated: false }) } @@ -440,7 +425,7 @@ class Platform extends React.Component { - +
diff --git a/src/views/Task.js b/src/views/Task.js index 52c7ebe7..e144e8b2 100644 --- a/src/views/Task.js +++ b/src/views/Task.js @@ -43,7 +43,6 @@ class Task extends React.Component { } this.fetchData = this.fetchData.bind(this) - this.handleSubscribe = this.handleSubscribe.bind(this) this.handleShowEditModal = this.handleShowEditModal.bind(this) this.handleHideEditModal = this.handleHideEditModal.bind(this) this.handleEditModalDone = this.handleEditModalDone.bind(this) @@ -58,20 +57,6 @@ class Task extends React.Component { this.props.history.push('/Login/' + encodeURIComponent('Task/' + this.props.match.params.id)) } - handleSubscribe () { - if (this.props.isLoggedIn) { - axios.post(config.api.getUriPrefix() + '/task/' + this.props.match.params.id + '/subscribe', {}) - .then(res => { - this.setState({ item: res.data.data }) - }) - .catch(err => { - window.alert('Error: ' + ErrorHandler(err) + '\nSorry! Check your connection and login status, and try again.') - }) - } else { - this.handleLoginRedirect() - } - } - handleShowEditModal () { let mode = 'Edit' if (!this.props.isLoggedIn) { @@ -243,7 +228,7 @@ class Task extends React.Component { - +
diff --git a/src/views/Tasks.js b/src/views/Tasks.js index 309abec8..544a092e 100644 --- a/src/views/Tasks.js +++ b/src/views/Tasks.js @@ -1,11 +1,13 @@ import axios from 'axios' import React from 'react' +import { Button } from 'react-bootstrap' import config from './../config' import ErrorHandler from '../components/ErrorHandler' import FormFieldValidator from '../components/FormFieldValidator' import FormFieldTypeaheadRow from '../components/FormFieldTypeaheadRow' import CategoryScroll from '../components/CategoryScroll' import CategoryItemIcon from '../components/CategoryItemIcon' +import CategoryItemBox from '../components/CategoryItemBox' import SubscribeButton from '../components/SubscribeButton' import FormFieldAlertRow from '../components/FormFieldAlertRow' import FormFieldWideRow from '../components/FormFieldWideRow' @@ -28,6 +30,7 @@ class Tasks extends React.Component { isLoading: true, alphabetical: [], allNames: [], + platforms: [], featured: [], trending: [], popular: [], @@ -74,6 +77,24 @@ class Tasks extends React.Component { .catch(err => { this.setState({ requestFailedMessage: ErrorHandler(err) }) }) + axios.get(config.api.getUriPrefix() + '/platform/names') + .then(res => { + const rws = [] + for (let i = 0; i < 2; ++i) { + const row = [] + for (let j = 0; j < 3; ++j) { + row.push(res.data.data[3 * i + j]) + } + rws.push(row) + } + this.setState({ + requestFailedMessage: '', + platforms: rws + }) + }) + .catch(err => { + this.setState({ requestFailedMessage: ErrorHandler(err) }) + }) axios.get(config.api.getUriPrefix() + '/task/submissionCount/34') .then(res => { @@ -114,24 +135,26 @@ class Tasks extends React.Component { @@ -140,9 +163,11 @@ class Tasks extends React.Component { {item.parentTask.name}
- + + +
- {item.name} + {item.name} {qedcIds.includes(parseInt(item.id)) && (QED-C)}
- {item.description} + {item.description}

- - - + + + + +
@@ -160,6 +185,30 @@ class Tasks extends React.Component { +
+ {(this.state.platforms.length > 0) && + + +

Platforms

+
+ +
+
+
+ + + {this.state.platforms.map((row, rid) => {row.map((item, id) => )})} + +
+
+
+
+
+
+ + + +
} From 0f760e8c43ed2aad0582ff0e925475290f508ca6 Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Fri, 7 Jul 2023 14:31:52 -0400 Subject: [PATCH 05/15] Reduce header/footer font size --- src/App.css | 13 ++++++------- .../simple-react-footer/SimpleReactFooter.css | 1 + 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/App.css b/src/App.css index 9530ec08..ac3daf7a 100644 --- a/src/App.css +++ b/src/App.css @@ -47,6 +47,12 @@ textarea { font-family: 'Arial', sans-serif; color:white; font-weight: bold; + font-size: 0.875rem +} + +.metriq-navbar-button { + font-size: small; + margin-bottom: 4px; } .metriq-navbar.navbar { @@ -84,10 +90,6 @@ textarea { margin-top: 8px; } -.metriq-follow-button { - font-size: small; -} - .navbar-nav { border-radius: 16px; border: none; @@ -258,7 +260,6 @@ form > span > .row > label { } .submission-subheading { - font-size: 80%; padding: 0 8px 8px 8px } @@ -284,7 +285,6 @@ form > span > .row > label { .submission-description { white-space: pre-line; text-align: left; - font-size: 90%; padding: 0 8px 8px 8px } @@ -329,7 +329,6 @@ form > span > .row > label { width: 80px; height: 40px; margin: 4px; - font-size: 0.5em; display: inline-block; } diff --git a/src/components/simple-react-footer/SimpleReactFooter.css b/src/components/simple-react-footer/SimpleReactFooter.css index a22d12e4..7c703918 100644 --- a/src/components/simple-react-footer/SimpleReactFooter.css +++ b/src/components/simple-react-footer/SimpleReactFooter.css @@ -9,6 +9,7 @@ .footer-div { width: 100%; + font-size: 0.875rem } .social-media { From 5e9a22ffff17cfab1243fbfe662195f0017d7c34 Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Mon, 10 Jul 2023 13:29:10 -0400 Subject: [PATCH 06/15] Remove Bootstrap container; left align --- src/App.css | 8 +++++--- src/App.js | 2 +- src/components/CategoryScroll.js | 4 ++-- src/views/Methods.js | 2 +- src/views/Platforms.js | 2 +- src/views/Tags.js | 2 +- src/views/Tasks.js | 8 ++++---- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/App.css b/src/App.css index 27b898bf..6ac89710 100644 --- a/src/App.css +++ b/src/App.css @@ -7,7 +7,7 @@ .centered-tabs > nav { display: flex; flex-direction: row; - justify-content: center; + /* justify-content: center; */ } textarea { @@ -110,7 +110,7 @@ textarea { .nav-tabs { display: flex; flex-direction: row; - justify-content: center; + /* justify-content: center;*/ } .metriq-navbar-spacer { @@ -158,6 +158,8 @@ textarea { #metriq-main-content { min-height: 700px; padding-top: 20px; + padding-left: 32px; + padding-right: 32px; } @keyframes App-logo-spin { @@ -376,7 +378,7 @@ form > span > .row > label { color: white; } -.container .submission a { +.category-scroll .submission a { color: #000000; text-decoration: none; } diff --git a/src/App.js b/src/App.js index ab6e647a..d77c9ecd 100644 --- a/src/App.js +++ b/src/App.js @@ -4,7 +4,7 @@ import SimpleReactFooter from './components/simple-react-footer/SimpleReactFoote const App = () =>
- + { }, [props.items]) return ( -
+

{props.heading && -

{props.heading}

+

{props.heading}

} {!props.items.length && diff --git a/src/views/Methods.js b/src/views/Methods.js index 0fd0a9f0..fc9b6422 100644 --- a/src/views/Methods.js +++ b/src/views/Methods.js @@ -77,7 +77,7 @@ class Methods extends React.Component { render () { return ( -
+
Methods Methods are the algorithms used in a submission.
diff --git a/src/views/Platforms.js b/src/views/Platforms.js index c79a714b..93bfe5c0 100644 --- a/src/views/Platforms.js +++ b/src/views/Platforms.js @@ -77,7 +77,7 @@ class Platforms extends React.Component { render () { return ( -
+
Platforms Platforms are the hardware devices used for a submission.
diff --git a/src/views/Tags.js b/src/views/Tags.js index 18fe3170..106bc245 100644 --- a/src/views/Tags.js +++ b/src/views/Tags.js @@ -48,7 +48,7 @@ class Tags extends React.Component { render () { return ( -
+
Tags Tags are keywords assigned to a submission that enable retrieval by search.
diff --git a/src/views/Tasks.js b/src/views/Tasks.js index 544a092e..16e817d1 100644 --- a/src/views/Tasks.js +++ b/src/views/Tasks.js @@ -107,7 +107,7 @@ class Tasks extends React.Component { render () { return ( -
+
Tasks

Tasks are workloads of interest performed on a quantum computer.

Search the task hierarchy to see charts of comparative performance across methods, see our submitter leader board and featured task charts, or click into the parent/child task hierarchy through top-level task categories.

@@ -127,7 +127,7 @@ class Tasks extends React.Component {
-

Featured

+

Featured

{this.state.featured.map((item, index) =>
@@ -189,13 +189,13 @@ class Tasks extends React.Component { {(this.state.platforms.length > 0) && -

Platforms

+

Platforms

- +
{this.state.platforms.map((row, rid) => {row.map((item, id) => )})} From 4516951a84b4ab015b897f9a4a08a2bc4dc8e944 Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Wed, 12 Jul 2023 10:45:06 -0400 Subject: [PATCH 07/15] 3 featured tasks --- src/components/SotaChart.js | 10 +++++++--- src/views/Tasks.js | 21 +++++++++++++++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/components/SotaChart.js b/src/components/SotaChart.js index 8980c358..e29cd099 100644 --- a/src/components/SotaChart.js +++ b/src/components/SotaChart.js @@ -81,6 +81,7 @@ class SotaChart extends React.Component { chartData: this.state.chartData, isLowerBetterDict: this.state.isLowerBetterDict, isLog: type, + logBase, log }) } @@ -95,6 +96,7 @@ class SotaChart extends React.Component { chartData: this.state.chartData, isLowerBetterDict: this.state.isLowerBetterDict, isLog: this.state.isLog, + logBase: this.state.logBase, log: this.state.log }) } @@ -109,6 +111,7 @@ class SotaChart extends React.Component { chartData: this.state.chartData, isLowerBetterDict: this.state.isLowerBetterDict, isLog: this.state.isLog, + logBase: this.state.logBase, log: this.state.log }) } @@ -318,7 +321,7 @@ class SotaChart extends React.Component { y: { title: { display: true, - text: ((state.isLog && canLog) ? ((state.isLog > 1) ? 'Log Log ' : 'Log ') : '') + (state.chartKey ? state.chartKey : 'Metric value') + text: ((state.isLog && canLog) ? (((state.isLog > 1) ? 'Log Log ' : 'Log ') + state.logBase.toString() + ' ') : '') + (state.chartKey ? state.chartKey : 'Metric value') }, type: (state.isLog && !canLog) ? 'logarithmic' : 'linear', suggestedMin: lowest, @@ -386,7 +389,7 @@ class SotaChart extends React.Component { y: { title: { display: true, - text: ((state.isLog && canLog) ? ((state.isLog > 1) ? 'Log Log ' : 'Log ') : '') + (state.chartKey ? state.chartKey : 'Metric value') + text: ((state.isLog && canLog) ? (((state.isLog > 1) ? 'Log Log ' : 'Log ') + state.logBase.toString() + ' ') : '') + (state.chartKey ? state.chartKey : 'Metric value') }, type: (state.isLog && !canLog) ? 'logarithmic' : 'linear' } @@ -551,7 +554,7 @@ class SotaChart extends React.Component { } } this.setState({ metricNames, chartKey, chartData, isLowerBetterDict, key: Math.random() }) - this.loadChartFromState({ subset: this.state.subset, label: this.state.label, metricNames, chartKey, chartData, isLowerBetterDict, isLog: this.state.isLog, log: this.state.log }) + this.loadChartFromState({ subset: this.state.subset, label: this.state.label, metricNames, chartKey, chartData, isLowerBetterDict, isLog: this.state.isLog, logBase: this.state.logBase, log: this.state.log }) } componentDidMount () { @@ -652,6 +655,7 @@ class SotaChart extends React.Component { chartData: this.state.chartData, isLowerBetterDict: this.state.isLowerBetterDict, isLog: this.state.isLog, + logBase: this.state.logBase, log: this.state.log }) }} diff --git a/src/views/Tasks.js b/src/views/Tasks.js index 16e817d1..b16a21f5 100644 --- a/src/views/Tasks.js +++ b/src/views/Tasks.js @@ -98,7 +98,24 @@ class Tasks extends React.Component { axios.get(config.api.getUriPrefix() + '/task/submissionCount/34') .then(res => { - this.setState({ featured: [res.data.data] }) + let featured = [res.data.data] + + axios.get(config.api.getUriPrefix() + '/task/submissionCount/50') + .then(res => { + featured.push(res.data.data) + + axios.get(config.api.getUriPrefix() + '/task/submissionCount/164') + .then(res => { + featured.push(res.data.data) + this.setState({ featured }) + }) + .catch(err => { + this.setState({ requestFailedMessage: ErrorHandler(err) }) + }) + }) + .catch(err => { + this.setState({ requestFailedMessage: ErrorHandler(err) }) + }) }) .catch(err => { this.setState({ requestFailedMessage: ErrorHandler(err) }) @@ -143,7 +160,7 @@ class Tasks extends React.Component { taskId={item.id} key={index} isLog - logBase={(index === 0) ? '2' : ((index === 1) ? 'e' : '10')} + logBase={(index === 0) ? '2' : '10'} /> From 32c91ee03a99349b137ac730f2a61bbb1b8a8cb2 Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Thu, 13 Jul 2023 11:57:51 -0400 Subject: [PATCH 08/15] Fix responsive layout --- src/App.css | 3 +- src/components/CategoryItemBox.js | 4 +- src/components/CategoryScroll.js | 10 +-- src/components/SubmissionBoxSmall.js | 26 +++++++ src/components/SubmissionScroll.js | 41 +++++++---- src/components/ViewHeader.js | 2 +- src/views/Submissions.js | 2 +- src/views/Tasks.js | 106 ++++++++++++++------------- 8 files changed, 115 insertions(+), 79 deletions(-) create mode 100644 src/components/SubmissionBoxSmall.js diff --git a/src/App.css b/src/App.css index 6ac89710..c798a0fd 100644 --- a/src/App.css +++ b/src/App.css @@ -221,7 +221,6 @@ form > span > .row > label { .submission-cell { padding: 8px; - width: 33%; } .submission { @@ -378,7 +377,7 @@ form > span > .row > label { color: white; } -.category-scroll .submission a { +.submission a { color: #000000; text-decoration: none; } diff --git a/src/components/CategoryItemBox.js b/src/components/CategoryItemBox.js index c520c5ce..293adbcd 100644 --- a/src/components/CategoryItemBox.js +++ b/src/components/CategoryItemBox.js @@ -24,7 +24,7 @@ const pickDetailUrl = (type, item) => { const CategoryItemBox = (props) => { return ( - + ) } diff --git a/src/components/CategoryScroll.js b/src/components/CategoryScroll.js index 116ff998..c2947dd9 100644 --- a/src/components/CategoryScroll.js +++ b/src/components/CategoryScroll.js @@ -21,7 +21,7 @@ const CategoryScroll = (props) => { }, [props.items]) return ( -
+

{props.heading && @@ -36,12 +36,8 @@ const CategoryScroll = (props) => { Loading...
}>
-
-
+
{props.type !== 'tag' && props.item.description && @@ -54,7 +54,7 @@ const CategoryItemBox = (props) => { }
-
- - {rows.map((row, rid) => {row.map((item, id) => )})} - -
+
+ {rows.map((row, rid) =>
{row.map((item, id) => )}
)}
diff --git a/src/components/SubmissionBoxSmall.js b/src/components/SubmissionBoxSmall.js new file mode 100644 index 00000000..d2ff3532 --- /dev/null +++ b/src/components/SubmissionBoxSmall.js @@ -0,0 +1,26 @@ +import React from 'react' +import { Link } from 'react-router-dom' +import { library } from '@fortawesome/fontawesome-svg-core' +import { faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons' +import logo from './../images/metriq_logo_secondary_blue.png' + +library.add(faExternalLinkAlt) + +const SubmissionBoxSmall = (props) => +
+ +
+
+ Submission thumbnail +
+
+
{props.item.name} {props.isEditView && ' - '} {props.isEditView && {props.isDraft ? 'Unpublished draft' : props.isUnderReview ? 'Under Review' : 'Approved'}}
+
+ Submitted by {props.item.username} +
+
+
+ +
+ +export default SubmissionBoxSmall diff --git a/src/components/SubmissionScroll.js b/src/components/SubmissionScroll.js index 57aa9ce8..c5511b17 100644 --- a/src/components/SubmissionScroll.js +++ b/src/components/SubmissionScroll.js @@ -6,6 +6,7 @@ import FormFieldValidator from './FormFieldValidator' import FormFieldAlertRow from './FormFieldAlertRow' import FormFieldWideRow from './FormFieldWideRow' import FormFieldTypeaheadRow from './FormFieldTypeaheadRow' +import SubmissionBoxSmall from './SubmissionBoxSmall' const InfiniteScroll = React.lazy(() => import('react-infinite-scroll-component')) const SubmissionBox = React.lazy(() => import('./SubmissionBox')) @@ -48,7 +49,7 @@ class SubmissionScroll extends React.Component { nextPage: 1, items, filterOptions, - filteredItems: items + filteredItems: this.props.isSmall ? items.slice(0, 3) : items }) }) .catch(err => { @@ -111,28 +112,38 @@ class SubmissionScroll extends React.Component { render () { return ( -
- this.onFilter(value)} - alignLabelRight - /> +
+ {!this.props.isSmall && + this.onFilter(value)} + alignLabelRight + />} {this.state.items.length && ( Loading...
}> Loading...} - endMessage={

You have seen all submissions.

} + endMessage={this.props.isSmall ? :

You have seen all submissions.

} > - {this.state.filteredItems.map((item, index) => + {this.props.isSmall && this.state.filteredItems.map((item, index) => + )} + {!this.props.isSmall && this.state.filteredItems.map((item, index) =>

{props.children}

+const ViewHeader = (props) =>

{props.children}

export default ViewHeader diff --git a/src/views/Submissions.js b/src/views/Submissions.js index f9fa461f..215a3350 100644 --- a/src/views/Submissions.js +++ b/src/views/Submissions.js @@ -46,7 +46,7 @@ const Submissions = (props) => { } return ( -
+
Loading...
}> diff --git a/src/views/Tasks.js b/src/views/Tasks.js index b16a21f5..1add529c 100644 --- a/src/views/Tasks.js +++ b/src/views/Tasks.js @@ -1,6 +1,6 @@ import axios from 'axios' import React from 'react' -import { Button } from 'react-bootstrap' +import { Button, Tab, Tabs } from 'react-bootstrap' import config from './../config' import ErrorHandler from '../components/ErrorHandler' import FormFieldValidator from '../components/FormFieldValidator' @@ -18,6 +18,7 @@ import { withRouter, Link } from 'react-router-dom' import { library } from '@fortawesome/fontawesome-svg-core' import { faHeart, faExternalLinkAlt, faChartLine } from '@fortawesome/free-solid-svg-icons' import TopSubmitters from '../components/TopSubmitters' +import SubmissionScroll from '../components/SubmissionScroll' library.add(faHeart, faExternalLinkAlt, faChartLine) @@ -36,6 +37,7 @@ class Tasks extends React.Component { popular: [], latest: [], topSubmitters: [], + activeTab: 'Trending', filterId: null, requestFailedMessage: '' } @@ -98,7 +100,7 @@ class Tasks extends React.Component { axios.get(config.api.getUriPrefix() + '/task/submissionCount/34') .then(res => { - let featured = [res.data.data] + const featured = [res.data.data] axios.get(config.api.getUriPrefix() + '/task/submissionCount/50') .then(res => { @@ -143,64 +145,70 @@ class Tasks extends React.Component {
-
+

Featured

{this.state.featured.map((item, index) =>
+
+
+ + + +
+
+
+ {item.name} + {qedcIds.includes(parseInt(item.id)) && + (QED-C)} + +
+ {item.description} +
+
-
- - - - - - - - - - -
- - - - -
- {item.name} - {qedcIds.includes(parseInt(item.id)) && - (QED-C)} - -
- {item.description} -

- {item.parentTask.name} - - - - - - -
+
+ {item.parentTask.name} +
+
+ + + + +
)}
-
+
+
+
Top Submissions
+ this.setState({ activeTab })}> + + + + + + + + + +

- +
{(this.state.platforms.length > 0) && @@ -211,12 +219,8 @@ class Tasks extends React.Component {
-
- - - {this.state.platforms.map((row, rid) => {row.map((item, id) => )})} - -
+
+ {this.state.platforms.map((row, rid) =>
{row.map((item, id) => )}
)}
From b9a17b652239797fd5e950d96bd0cfbaa11cffd3 Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Fri, 14 Jul 2023 14:13:23 -0400 Subject: [PATCH 09/15] Colors and shadows --- src/App.css | 10 +++- src/components/CategoryScroll.js | 8 ++-- src/components/ViewHeader.js | 2 +- src/components/ViewSubHeader.js | 2 +- src/views/Tasks.js | 81 ++++++++++++++++---------------- 5 files changed, 54 insertions(+), 49 deletions(-) diff --git a/src/App.css b/src/App.css index c798a0fd..f626ca13 100644 --- a/src/App.css +++ b/src/App.css @@ -1,7 +1,6 @@ .App { text-align: center; font-family: Arial, Helvetica, sans-serif; - background-color: #F6F6F6; } .centered-tabs > nav { @@ -74,6 +73,7 @@ textarea { .metriq-header { margin-top: 16px; font-family: 'Arial', sans-serif; + color: #04165D } .metriq-navbar h2 { @@ -215,8 +215,13 @@ form > span > .row > label { padding: 12px; } +.view-header { + color: #04165D +} + .task { padding: 16px; + box-shadow: 0 3px 12px rgba(33,33,33,.2); } .submission-cell { @@ -228,10 +233,11 @@ form > span > .row > label { padding: 8px; margin: 6px; background-color: #FFFFFF; + box-shadow: 0 3px 12px rgba(33,33,33,.2); } .submission:hover { - box-shadow: 0 0 16px rgba(33,33,33,.2); + box-shadow: 0 3px 16px rgba(33,33,33,.2); } .category-item-box { diff --git a/src/components/CategoryScroll.js b/src/components/CategoryScroll.js index c2947dd9..c0b2f8f4 100644 --- a/src/components/CategoryScroll.js +++ b/src/components/CategoryScroll.js @@ -34,11 +34,9 @@ const CategoryScroll = (props) => { :

There are no approved items, yet.

)} {(props.items.length > 0) && Loading...
}> -
-
-
- {rows.map((row, rid) =>
{row.map((item, id) => )}
)} -
+
+
+ {rows.map((row, rid) =>
{row.map((item, id) => )}
)}
} diff --git a/src/components/ViewHeader.js b/src/components/ViewHeader.js index dfdfb628..5ed8a05c 100644 --- a/src/components/ViewHeader.js +++ b/src/components/ViewHeader.js @@ -1,2 +1,2 @@ -const ViewHeader = (props) =>

{props.children}

+const ViewHeader = (props) =>

{props.children}

export default ViewHeader diff --git a/src/components/ViewSubHeader.js b/src/components/ViewSubHeader.js index e317ff8a..d18e8438 100644 --- a/src/components/ViewSubHeader.js +++ b/src/components/ViewSubHeader.js @@ -1,2 +1,2 @@ -const ViewSubHeader = (props) =>

{props.children}

+const ViewSubHeader = (props) =>

{props.children}

export default ViewSubHeader diff --git a/src/views/Tasks.js b/src/views/Tasks.js index 1add529c..02f10524 100644 --- a/src/views/Tasks.js +++ b/src/views/Tasks.js @@ -148,44 +148,47 @@ class Tasks extends React.Component {

Featured

{this.state.featured.map((item, index) => -
-
-
- - - + +
+
+
+ + + +
+
+
+ {item.name} + {qedcIds.includes(parseInt(item.id)) && + (QED-C)} + +
+ {item.description} +
-
-
- {item.name} - {qedcIds.includes(parseInt(item.id)) && - (QED-C)} - -
- {item.description} +
+
+ {item.parentTask.name} +
+
+ + + + + +
-
-
- {item.parentTask.name} -
-
- - - - - -
-
-
+
+
)}
@@ -217,11 +220,9 @@ class Tasks extends React.Component {

Platforms

-
-
-
- {this.state.platforms.map((row, rid) =>
{row.map((item, id) => )}
)} -
+
+
+ {this.state.platforms.map((row, rid) =>
{row.map((item, id) => )}
)}
From 28eecfef8816a0e770b7ca4729100de50a0263cd Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Fri, 14 Jul 2023 14:39:29 -0400 Subject: [PATCH 10/15] Bootstrap grid --- src/App.css | 1 + src/components/CategoryItemBox.js | 2 +- src/components/CategoryScroll.js | 2 +- src/views/Tasks.js | 14 +++++++------- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/App.css b/src/App.css index f626ca13..f00be45a 100644 --- a/src/App.css +++ b/src/App.css @@ -226,6 +226,7 @@ form > span > .row > label { .submission-cell { padding: 8px; + min-width: 256px; } .submission { diff --git a/src/components/CategoryItemBox.js b/src/components/CategoryItemBox.js index 293adbcd..ec35cf59 100644 --- a/src/components/CategoryItemBox.js +++ b/src/components/CategoryItemBox.js @@ -24,7 +24,7 @@ const pickDetailUrl = (type, item) => { const CategoryItemBox = (props) => { return ( -
+
{props.type !== 'tag' && props.item.description && diff --git a/src/components/CategoryScroll.js b/src/components/CategoryScroll.js index c0b2f8f4..14f71312 100644 --- a/src/components/CategoryScroll.js +++ b/src/components/CategoryScroll.js @@ -35,7 +35,7 @@ const CategoryScroll = (props) => { {(props.items.length > 0) && Loading...
}>
-
+
{rows.map((row, rid) =>
{row.map((item, id) => )}
)}
diff --git a/src/views/Tasks.js b/src/views/Tasks.js index 02f10524..08e6a3e4 100644 --- a/src/views/Tasks.js +++ b/src/views/Tasks.js @@ -151,7 +151,7 @@ class Tasks extends React.Component {
-
+
-
+
{item.name} {qedcIds.includes(parseInt(item.id)) && @@ -175,11 +175,11 @@ class Tasks extends React.Component {
-
+
{item.parentTask.name}
-
- +
+ @@ -211,7 +211,7 @@ class Tasks extends React.Component {
- +
{(this.state.platforms.length > 0) && @@ -221,7 +221,7 @@ class Tasks extends React.Component {
-
+
{this.state.platforms.map((row, rid) =>
{row.map((item, id) => )}
)}
From fd0e1f38be2d91ded20783e8a3cbde378ebd06e3 Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Wed, 19 Jul 2023 14:40:33 -0400 Subject: [PATCH 11/15] Fix top submitters and top submissions --- src/App.css | 16 +++ src/components/SubmissionBoxSmall.js | 17 ++- src/components/TopSubmitters.js | 206 +++++++++++++++------------ src/views/Tasks.js | 2 +- 4 files changed, 144 insertions(+), 97 deletions(-) diff --git a/src/App.css b/src/App.css index f00be45a..f856e712 100644 --- a/src/App.css +++ b/src/App.css @@ -288,6 +288,22 @@ form > span > .row > label { padding: 8px; } +.submission-image-small { + display: inline-block; + vertical-align: -40px; + width: 60px; + height: auto; + max-width: 120px; + max-height: 120px; + padding-top: 16px; + padding-bottom: 16px; +} + +.submission-heading-small { + padding-top: 16px; + padding-bottom: 16px; +} + .submission-detail-image { display: inline-block; vertical-align: -128px; diff --git a/src/components/SubmissionBoxSmall.js b/src/components/SubmissionBoxSmall.js index d2ff3532..b6528d9b 100644 --- a/src/components/SubmissionBoxSmall.js +++ b/src/components/SubmissionBoxSmall.js @@ -7,17 +7,20 @@ import logo from './../images/metriq_logo_secondary_blue.png' library.add(faExternalLinkAlt) const SubmissionBoxSmall = (props) => +
-
- Submission thumbnail +
+ Submission thumbnail +
+
+
{(props.item.name.length > 80) ? (props.item.name.substring(0, 77) + '...') : props.item.name}
-
-
{props.item.name} {props.isEditView && ' - '} {props.isEditView && {props.isDraft ? 'Unpublished draft' : props.isUnderReview ? 'Under Review' : 'Approved'}}
-
- Submitted by {props.item.username} -
+
+
+
+ Submitted by {props.item.username}
diff --git a/src/components/TopSubmitters.js b/src/components/TopSubmitters.js index 892b467c..12662e92 100644 --- a/src/components/TopSubmitters.js +++ b/src/components/TopSubmitters.js @@ -42,95 +42,123 @@ const TopSubmitters = (props) => { return (
Top Submitters
- - {(data.weekly.length > 0) && - -
- this.props.history.push('/User/' + record.id + '/Submissions')} - tableLayout='auto' - rowClassName='link' - /> -
-
} - {(data.monthly.length > 0) && - -
- this.props.history.push('/User/' + record.id + '/Submissions')} - tableLayout='auto' - rowClassName='link' - /> -
-
} - {(data.allTime.length > 0) && - -
- this.props.history.push('/User/' + record.id + '/Submissions')} - tableLayout='auto' - rowClassName='link' - /> -
-
} -
+ {props.isOnlyAllTime && +
+ this.props.history.push('/User/' + record.id + '/Submissions')} + tableLayout='auto' + rowClassName='link' + /> +
} + {!props.isOnlyAllTime && + + {(data.weekly.length > 0) && + +
+ this.props.history.push('/User/' + record.id + '/Submissions')} + tableLayout='auto' + rowClassName='link' + /> +
+
} + {(data.monthly.length > 0) && + +
+ this.props.history.push('/User/' + record.id + '/Submissions')} + tableLayout='auto' + rowClassName='link' + /> +
+
} + {(data.allTime.length > 0) && + +
+ this.props.history.push('/User/' + record.id + '/Submissions')} + tableLayout='auto' + rowClassName='link' + /> +
+
} +
}
) } diff --git a/src/views/Tasks.js b/src/views/Tasks.js index 08e6a3e4..ba280ed1 100644 --- a/src/views/Tasks.js +++ b/src/views/Tasks.js @@ -192,7 +192,7 @@ class Tasks extends React.Component { )}
- +
Top Submissions
this.setState({ activeTab })}> From d01b4716c4538c2c975003fb6743d5af6183bd6c Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Wed, 19 Jul 2023 15:13:59 -0400 Subject: [PATCH 12/15] Fix cards and text --- src/App.css | 5 + src/components/SubmissionScroll.js | 34 ++--- src/components/TopSubmitters.js | 200 ++++++++++++++--------------- src/views/Tasks.js | 45 ++++--- 4 files changed, 148 insertions(+), 136 deletions(-) diff --git a/src/App.css b/src/App.css index f856e712..7ff4c1cf 100644 --- a/src/App.css +++ b/src/App.css @@ -304,6 +304,11 @@ form > span > .row > label { padding-bottom: 16px; } +.top-submitters-card { + padding: 8px 16px 8px 16px; + box-shadow: 0 3px 12px rgba(33,33,33,.2); +} + .submission-detail-image { display: inline-block; vertical-align: -128px; diff --git a/src/components/SubmissionScroll.js b/src/components/SubmissionScroll.js index c5511b17..2487b578 100644 --- a/src/components/SubmissionScroll.js +++ b/src/components/SubmissionScroll.js @@ -125,7 +125,17 @@ class SubmissionScroll extends React.Component { alignLabelRight />} - {this.state.items.length && ( + {this.props.isSmall && this.state.items.length && + this.state.filteredItems.map((item, index) => + )} + {!this.props.isSmall && this.state.items.length && ( Loading...
}> Loading...} endMessage={this.props.isSmall ? :

You have seen all submissions.

} > - {this.props.isSmall && this.state.filteredItems.map((item, index) => - )} - {!this.props.isSmall && this.state.filteredItems.map((item, index) => + {this.state.filteredItems.map((item, index) => You have no submissions, yet.

:

There are no approved submissions, yet.

)} -
- - - + {!this.props.isSmall && + +
+ + + +
}
) } diff --git a/src/components/TopSubmitters.js b/src/components/TopSubmitters.js index 12662e92..e9b93ab2 100644 --- a/src/components/TopSubmitters.js +++ b/src/components/TopSubmitters.js @@ -43,120 +43,112 @@ const TopSubmitters = (props) => {
Top Submitters
{props.isOnlyAllTime && -
- this.props.history.push('/User/' + record.id + '/Submissions')} - tableLayout='auto' - rowClassName='link' - /> -
} + this.props.history.push('/User/' + record.id + '/Submissions')} + tableLayout='auto' + rowClassName='link' + />} {!props.isOnlyAllTime && {(data.weekly.length > 0) && -
- this.props.history.push('/User/' + record.id + '/Submissions')} - tableLayout='auto' - rowClassName='link' - /> -
+ this.props.history.push('/User/' + record.id + '/Submissions')} + tableLayout='auto' + rowClassName='link' + />
} {(data.monthly.length > 0) && -
- this.props.history.push('/User/' + record.id + '/Submissions')} - tableLayout='auto' - rowClassName='link' - /> -
+ this.props.history.push('/User/' + record.id + '/Submissions')} + tableLayout='auto' + rowClassName='link' + />
} {(data.allTime.length > 0) && -
- this.props.history.push('/User/' + record.id + '/Submissions')} - tableLayout='auto' - rowClassName='link' - /> -
+ this.props.history.push('/User/' + record.id + '/Submissions')} + tableLayout='auto' + rowClassName='link' + />
}
}
diff --git a/src/views/Tasks.js b/src/views/Tasks.js index ba280ed1..1ae3d092 100644 --- a/src/views/Tasks.js +++ b/src/views/Tasks.js @@ -12,7 +12,7 @@ import SubscribeButton from '../components/SubscribeButton' import FormFieldAlertRow from '../components/FormFieldAlertRow' import FormFieldWideRow from '../components/FormFieldWideRow' import ViewHeader from '../components/ViewHeader' -import { sortAlphabetical } from '../components/SortFunctions' +import { sortCommon, sortAlphabetical } from '../components/SortFunctions' import SotaChart from '../components/SotaChart' import { withRouter, Link } from 'react-router-dom' import { library } from '@fortawesome/fontawesome-svg-core' @@ -79,13 +79,16 @@ class Tasks extends React.Component { .catch(err => { this.setState({ requestFailedMessage: ErrorHandler(err) }) }) - axios.get(config.api.getUriPrefix() + '/platform/names') + + axios.get(config.api.getUriPrefix() + '/platform/submissionCount') .then(res => { + const common = [...res.data.data] + common.sort(sortCommon) const rws = [] for (let i = 0; i < 2; ++i) { const row = [] for (let j = 0; j < 3; ++j) { - row.push(res.data.data[3 * i + j]) + row.push(common[3 * i + j]) } rws.push(row) } @@ -145,8 +148,12 @@ class Tasks extends React.Component {
-
+

Featured

+
+
+
+
{this.state.featured.map((item, index) =>
@@ -192,20 +199,24 @@ class Tasks extends React.Component { )}
- +
+ +

-
Top Submissions
- this.setState({ activeTab })}> - - - - - - - - - - +
+
Top Submissions
+ this.setState({ activeTab })}> + + + + + + + + + + +
From 0fc2de26d5da166eeb7a135cfae7a679a6406494 Mon Sep 17 00:00:00 2001 From: Dan Strano Date: Wed, 19 Jul 2023 15:46:09 -0400 Subject: [PATCH 13/15] Search bar accent --- src/App.css | 9 +++++++++ src/components/FormFieldTypeaheadRow.js | 4 ++-- src/views/Tasks.js | 5 +++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/App.css b/src/App.css index 7ff4c1cf..3d703ed5 100644 --- a/src/App.css +++ b/src/App.css @@ -25,6 +25,14 @@ textarea { padding-top: 10px; } +.search-accent { + outline: solid !important; + outline-width: 4px !important; + outline-color: #68D0F4 !important; + border-radius: 4px; + padding: 0; +} + .main-search-bar { display: inline-block; padding-top: 8px; @@ -244,6 +252,7 @@ form > span > .row > label { .category-item-box { display: inline-block; height: 128px; + padding: 12px; } .delete-button { diff --git a/src/components/FormFieldTypeaheadRow.js b/src/components/FormFieldTypeaheadRow.js index cfffd6b7..57a80b75 100644 --- a/src/components/FormFieldTypeaheadRow.js +++ b/src/components/FormFieldTypeaheadRow.js @@ -61,7 +61,7 @@ const FormFieldTypeaheadRow = (props) => { } - {props.label && !props.tooltip && + {(props.isRow || (props.label && !props.tooltip)) &&