diff options
Diffstat (limited to 'services/app/assets')
| -rw-r--r-- | services/app/assets/chart.js | 72 | ||||
| -rw-r--r-- | services/app/assets/index.js | 13 | ||||
| -rw-r--r-- | services/app/assets/loading.js | 54 |
3 files changed, 139 insertions, 0 deletions
diff --git a/services/app/assets/chart.js b/services/app/assets/chart.js new file mode 100644 index 0000000..dab6cbf --- /dev/null +++ b/services/app/assets/chart.js @@ -0,0 +1,72 @@ +import { + Chart, + Colors, + LineController, + LineElement, + LinearScale, + PointElement, + TimeScale, + Tooltip, +} from 'chart.js' +import 'chartjs-adapter-date-fns'; + +Chart.register( + Colors, + LineController, + LineElement, + LinearScale, + PointElement, + TimeScale, + Tooltip, +); + +document.addEventListener('DOMContentLoaded', async () => { + const chartCanvas = document.getElementById('chart'); + const quizId = chartCanvas.dataset.quizId; + + const apiUrl = `${process.env.ALBATROSS_BASE_PATH}/api/quizzes/${quizId}/chart`; + const apiResult = await fetch(apiUrl).then(res => res.json()); + if (apiResult.error) { + return; + } + const stats = apiResult.stats; + + new Chart( + chartCanvas, + { + type: 'line', + data: { + datasets: stats.map(s => ({ + label: `${s.user.name}${s.user.is_admin ? ' (staff)' : ''}`, + data: s.scores.map(row => ({ x: row.submitted_at * 1000, y: row.code_size })), + })) + }, + options: { + scales: { + x: { + type: 'time', + time: { + parsing: false, + display: false, + unit: 'day', + tooltipFormat: 'yyyy-MM-dd HH:mm:ss', + displayFormats: { + day: 'yyyy-MM-dd', + }, + }, + title: { + display: true, + text: '提出日時', + }, + }, + y: { + title: { + display: true, + text: 'コードサイズ (byte)', + }, + }, + }, + }, + }, + ); +}); diff --git a/services/app/assets/index.js b/services/app/assets/index.js new file mode 100644 index 0000000..74a0682 --- /dev/null +++ b/services/app/assets/index.js @@ -0,0 +1,13 @@ +import hljs from 'highlight.js/lib/core'; +import php from 'highlight.js/lib/languages/php'; +import plaintext from 'highlight.js/lib/languages/plaintext'; +import 'highlight.js/styles/github.css'; +import 'bootstrap/dist/css/bootstrap.css'; + +document.addEventListener('DOMContentLoaded', () => { + hljs.registerLanguage('php', php); + hljs.registerLanguage('plaintext', plaintext); + hljs.highlightAll(); +}); + +console.log(`#Albatross!`); diff --git a/services/app/assets/loading.js b/services/app/assets/loading.js new file mode 100644 index 0000000..570a7e9 --- /dev/null +++ b/services/app/assets/loading.js @@ -0,0 +1,54 @@ +document.addEventListener('DOMContentLoaded', () => { + const aggregatedStatusElem = document.getElementsByClassName('js-aggregated-execution-status')[0]; + const aggregatedStatusLoadingIndicatorElem = document.getElementsByClassName('js-aggregated-execution-status-loading-indicator')[0]; + const answerId = aggregatedStatusElem.dataset.answerId; + + const getElemsMap = cls => new Map( + Array.from(document.getElementsByClassName(cls) ?? []) + .map(e => [parseInt(e.dataset.testcaseExecutionId), e]) + ); + const statusElemsMap = getElemsMap('js-testcase-execution-status'); + const statusLoadingIndicatorElemsMap = getElemsMap('js-testcase-execution-status-loading-indicator'); + const stdoutElemsMap = getElemsMap('js-testcase-execution-stdout'); + const stderrElemsMap = getElemsMap('js-testcase-execution-stderr'); + + if (!aggregatedStatusLoadingIndicatorElem) { + return; + } + + const apiUrl = `${process.env.ALBATROSS_BASE_PATH}/api/answers/${answerId}/statuses`; + + let timerId; + timerId = setInterval(() => { + fetch(apiUrl) + .then(response => response.json()) + .then(({ aggregated_status, testcase_executions }) => { + for (const ex of testcase_executions) { + const statusElem = statusElemsMap.get(ex.id); + const loadingIndicatorElem = statusLoadingIndicatorElemsMap.get(ex.id); + const stdoutElem = stdoutElemsMap.get(ex.id); + const stderrElem = stderrElemsMap.get(ex.id); + + const { status, stdout, stderr } = ex; + if (status.label === statusElem.textContent) { + continue; + } + statusElem.textContent = status.label; + stdoutElem.textContent = stdout; + stderrElem.textContent = stderr; + if (loadingIndicatorElem && !status.show_loading_indicator) { + loadingIndicatorElem.remove(); + } + } + + if (aggregated_status.label === aggregatedStatusElem.textContent) { + return; + } + aggregatedStatusElem.textContent = aggregated_status.label; + if (!aggregated_status.show_loading_indicator) { + aggregatedStatusLoadingIndicatorElem.remove(); + clearInterval(timerId); + } + }); + }, 5 * 1000); +}); |
