diff --git a/tcms/settings/common.py b/tcms/settings/common.py index fe212b2ccb..fd1abe53f6 100644 --- a/tcms/settings/common.py +++ b/tcms/settings/common.py @@ -326,6 +326,12 @@ (_("TestCase health"), reverse_lazy("test-case-health")), ], ), + ( + _("Management"), + [ + (_("Performance"), reverse_lazy("management-performance")), + ], + ), ( "More coming soon", "http://kiwitcms.org/blog/kiwi-tcms-team/2019/03/03/legacy-reports-become-telemetry/", diff --git a/tcms/telemetry/static/telemetry/js/management/performance.js b/tcms/telemetry/static/telemetry/js/management/performance.js new file mode 100644 index 0000000000..9a815d6561 --- /dev/null +++ b/tcms/telemetry/static/telemetry/js/management/performance.js @@ -0,0 +1,142 @@ +// TODO: account for more users +const colors = [ + 'blue', + 'red', + 'gold', + 'orange', + 'green', + 'cyan', + 'purple', + 'black', + 'lightBlue', + 'lightGreen' +] + +$(document).ready(() => { + $('.selectpicker').selectpicker() + $('[data-toggle="tooltip"]').tooltip() + + loadInitialProduct(reloadCharts) + + $('#id_after').on('dp.change', reloadCharts) + $('#id_before').on('dp.change', reloadCharts) + document.getElementById('id_test_plan').onchange = reloadCharts + document.getElementById('id_product').onchange = () => { + updateTestPlanSelectFromProduct(reloadCharts) + } +}) + +function reloadCharts () { + const query = {} + + const testPlanIds = $('#id_test_plan').val() + const productIds = $('#id_product').val() + + if (testPlanIds.length) { + query.plan__in = testPlanIds + } else if (productIds.length) { + query.category__product_id__in = productIds + } + + const dateBefore = $('#id_before') + if (dateBefore.val()) { + query.create_date__lte = dateBefore.data('DateTimePicker').date().format('YYYY-MM-DD 23:59:59') + } + + const dateAfter = $('#id_after') + if (dateAfter.val()) { + query.create_date__gte = dateAfter.data('DateTimePicker').date().format('YYYY-MM-DD 00:00:00') + } + + jsonRPC('Management.performance', query, result => { + console.log(result) + + // the actual result is in the same format, only it can be much bigger + // and the chart may break + const r = { + 1: { + 1: 1, + 3: 2 + }, + 2: { + 1: 1, + 4: 2 + }, + 3: { + 1: 1, + 3: 1, + 5: 1 + }, + 4: { + 3: 1, + 2: 1 + }, + 5: { + 1: 5, + 3: 2, + 4: 1 + } + } + + drawChart(r) + }, true) +} + +function drawChart (data) { + // the X axis of the chart - run IDs + const groupedCategories = [] + // map of user ID -> table column. we use map here for faster lookup by user ID. + const groupedColumnsDataMap = {} + const userIds = new Set() + + // collect all the testers so that we know how much columns we will have + Object.entries(data).forEach(([_testRunId, asigneeCount]) => { + Object.entries(asigneeCount).forEach(([userId, _executionCount]) => userIds.add(userId)) + }) + + userIds.forEach(userId => (groupedColumnsDataMap[userId] = [`User ${userId}`])) + + Object.entries(data).forEach(([testRunId, _asigneeCount]) => { + groupedCategories.push(testRunId) + + const asigneesCount = data[testRunId] + + // for each user in the groupedColumnsDataMap check if that user + // is assigned any executions for this run. + Object.entries(groupedColumnsDataMap).forEach(([userId, data]) => { + const count = asigneesCount[userId] + if (count) { + data.push(count) + } else { + // TODO: find a way to hide the 0 valued-columns + data.push(0) + } + }) + }) + + // C3 does not need a map, but an array of values + // get rid of the keys, because we do not need them anymore + const groupedColumnsData = Object.values(groupedColumnsDataMap) + + const chartConfig = $().c3ChartDefaults().getDefaultGroupedBarConfig() + chartConfig.bindto = '#performance-chart' + chartConfig.axis = { + x: { + categories: groupedCategories, + type: 'category' + }, + y: { + tick: { + format: showOnlyRoundNumbers + } + } + } + chartConfig.data = { + type: 'bar', + columns: groupedColumnsData + } + chartConfig.color = { + pattern: colors + } + c3.generate(chartConfig) +} diff --git a/tcms/telemetry/static/telemetry/js/testing/breakdown.js b/tcms/telemetry/static/telemetry/js/testing/breakdown.js index 181cef71d6..9a357a4e65 100644 --- a/tcms/telemetry/static/telemetry/js/testing/breakdown.js +++ b/tcms/telemetry/static/telemetry/js/testing/breakdown.js @@ -114,6 +114,9 @@ function drawChart(data, type, selector) { chartData.push(dataEntry); }); + console.log('data', data) + console.log('groups', groups) + console.log('chartData', chartData) let chartConfig = $().c3ChartDefaults().getDefaultStackedBarConfig(); chartConfig.bindto = selector; chartConfig.axis = { diff --git a/tcms/telemetry/templates/telemetry/management/performance.html b/tcms/telemetry/templates/telemetry/management/performance.html new file mode 100644 index 0000000000..074b4cd47a --- /dev/null +++ b/tcms/telemetry/templates/telemetry/management/performance.html @@ -0,0 +1,28 @@ +{% extends "base.html" %} +{% load i18n %} +{% load static %} + +{% block title %}{% trans "Performance" %}{% endblock %} + +{% block contents %} + +