From b6b42b1afabdd42894b2842f965247445a20e55b Mon Sep 17 00:00:00 2001 From: cenfun Date: Sun, 10 Nov 2024 13:37:23 +0800 Subject: [PATCH] fixed UI --- CHANGELOG.md | 6 + lib/common.js | 7 +- lib/default/summary.js | 26 +-- lib/generate-data.js | 2 +- lib/utils/pie.js | 4 +- packages/app/src/components/detail/detail.vue | 52 ++++-- packages/app/src/components/icon-label.vue | 9 + packages/app/src/components/report/report.vue | 31 ++-- packages/app/src/components/report/trend.vue | 161 ++++++++++++------ packages/app/src/images/icons/attachment.svg | 5 +- packages/app/src/images/icons/error.svg | 9 +- packages/app/src/images/icons/log.svg | 6 +- packages/app/src/images/icons/retry.svg | 8 +- packages/app/src/images/icons/time.svg | 9 +- packages/app/src/modules/formatters.js | 2 + 15 files changed, 233 insertions(+), 104 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e11c544f..abbc7d58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## Changelog +* 2.9.10 + - fixed UI highlight + - fixed UI icons + - fixed trends chart + - fixed case type ordering + * 2.9.9 - fixed trend file issue (#160) diff --git a/lib/common.js b/lib/common.js index 16209fd3..7076f391 100644 --- a/lib/common.js +++ b/lib/common.js @@ -230,8 +230,13 @@ const getTrends = async (input) => { return []; } + // filter with one year ago + const date = new Date(); + const oneYearAgo = date.setFullYear(date.getFullYear() - 1); + // copy previous trends - const trends = [].concat(data.trends || []); + const trends = [].concat(data.trends || []).filter((it) => it.date > oneYearAgo); + trends.push(Util.getCurrentTrendInfo(data)); return trends; diff --git a/lib/default/summary.js b/lib/default/summary.js index a7f0e68d..33da5595 100644 --- a/lib/default/summary.js +++ b/lib/default/summary.js @@ -4,10 +4,10 @@ module.exports = () => ({ value: 0, nav: true }, - passed: { - name: 'Passed', + failed: { + name: 'Failed', value: 0, - color: 'green', + color: '#d00', nav: true }, flaky: { @@ -22,10 +22,10 @@ module.exports = () => ({ color: 'gray', nav: true }, - failed: { - name: 'Failed', + passed: { + name: 'Passed', value: 0, - color: '#d00', + color: 'green', nav: true }, @@ -60,21 +60,27 @@ module.exports = () => ({ value: 0 }, - retries: { - name: 'Retries', + errors: { + name: 'Errors', + icon: 'error', value: 0 }, - errors: { - name: 'Errors', + retries: { + name: 'Retries', + icon: 'retry', value: 0 }, + logs: { name: 'Logs', + icon: 'log', value: 0 }, + attachments: { name: 'Attachments', + icon: 'attachment', value: 0 } }); diff --git a/lib/generate-data.js b/lib/generate-data.js index db773e8b..c87a7ed7 100644 --- a/lib/generate-data.js +++ b/lib/generate-data.js @@ -97,7 +97,7 @@ const generateData = async (results) => { // suite and case types data.suiteTypes = ['project', 'file', 'describe', 'shard']; - data.caseTypes = ['passed', 'flaky', 'skipped', 'failed']; + data.caseTypes = ['failed', 'flaky', 'skipped', 'passed']; data.traceViewerUrl = options.traceViewerUrl; data.mermaid = generateMermaid(options); data.groupOptions = options.groupOptions; diff --git a/lib/utils/pie.js b/lib/utils/pie.js index d20c8d9d..be8dae9f 100644 --- a/lib/utils/pie.js +++ b/lib/utils/pie.js @@ -116,8 +116,8 @@ const generatePieChart = (pieDataList) => { // legends const legendWidth = 200; - const legendHeight = Math.floor((o.height - margin * 2) / list.length); - const legends = [``]; + const legendHeight = Math.floor((o.height - margin * 3) / list.length); + const legends = [``]; list.forEach((item, i) => { const midY = legendHeight * 0.5; legends.push(``); diff --git a/packages/app/src/components/detail/detail.vue b/packages/app/src/components/detail/detail.vue index eb98ccd1..bb465761 100644 --- a/packages/app/src/components/detail/detail.vue +++ b/packages/app/src/components/detail/detail.vue @@ -71,6 +71,21 @@ const updateColumnWidth = function(grid) { }; +const addHighlight = (rowItem) => { + removeHighlight(); + if (data.grid && rowItem) { + data.grid.setRowState(rowItem, 'highlight', true); + data.highlightRow = rowItem; + } +}; + +const removeHighlight = () => { + if (data.grid && data.highlightRow) { + data.grid.setRowState(data.highlightRow, 'highlight', false); + data.highlightRow = null; + } +}; + const getGrid = () => { if (data.grid) { return data.grid; @@ -90,20 +105,9 @@ const getGrid = () => { }); grid.bind('onClick', (e, d) => { - grid.selectAll(false); - }); - - grid.bind('onDblClick', (e, d) => { - const { rowItem } = d; - if (rowItem && !rowItem.hasDetails) { - grid.setRowSelected(d.rowItem); - } + removeHighlight(); }); - // grid.bind('onRowExpanded onRowCollapsed', (e, d) => { - // console.log(d); - // }); - grid.setOption({ headerVisible: false, @@ -387,8 +391,7 @@ const updatePosition = (position) => { grid.scrollRowIntoView(rowItem); } setTimeout(() => { - grid.selectAll(false); - grid.setRowSelected(rowItem); + addHighlight(rowItem); }, 100); } @@ -450,9 +453,7 @@ onMounted(() => { }); const onFocus = (e) => { - if (data.grid) { - data.grid.selectAll(false); - } + removeHighlight(); }; @@ -541,6 +542,23 @@ const onFocus = (e) => { .mcr-overview-grid { position: relative; overflow: hidden; + + .tg-turbogrid { + .tg-highlight { + &::after { + position: absolute; + top: 0; + left: 0; + content: ""; + display: block; + width: 100%; + height: 100%; + box-sizing: border-box; + border: 2px solid #80bdff; + pointer-events: none; + } + } + } } .markdown-body { diff --git a/packages/app/src/components/icon-label.vue b/packages/app/src/components/icon-label.vue index f3b47251..0810f779 100644 --- a/packages/app/src/components/icon-label.vue +++ b/packages/app/src/components/icon-label.vue @@ -20,6 +20,10 @@ const props = defineProps({ type: String, default: '' }, + color: { + type: String, + default: '' + }, gap: { type: String, default: '' @@ -53,6 +57,9 @@ const styleMap = computed(() => { if (props.size) { st['--mcr-icon-size'] = props.size; } + if (props.color) { + st['--mcr-icon-color'] = props.color; + } if (props.gap) { st['--mcr-icon-gap'] = props.gap; } @@ -116,6 +123,7 @@ watch(() => props.icon, () => { .mcr-icon-label { --mcr-icon-size: 16px; --mcr-icon-gap: 3px; + --mcr-icon-color: inherit; position: relative; gap: var(--mcr-icon-gap); @@ -125,6 +133,7 @@ watch(() => props.icon, () => { display: block; width: var(--mcr-icon-size); height: var(--mcr-icon-size); + color: var(--mcr-icon-color); background-repeat: no-repeat; background-position: center center; background-size: var(--mcr-icon-size) var(--mcr-icon-size); diff --git a/packages/app/src/components/report/report.vue b/packages/app/src/components/report/report.vue index 0b639b66..99802ea6 100644 --- a/packages/app/src/components/report/report.vue +++ b/packages/app/src/components/report/report.vue @@ -335,12 +335,14 @@ const pieHandler = () => { primary: true, list: [ summary.errors, + summary.retries, summary.logs, - summary.attachments, - summary.retries + summary.attachments ] }]; + // console.log(report.amountList, summary); + }; // ==================================================================================== @@ -402,17 +404,22 @@ onActivated(() => { gap="15px" wrap > - - {{ item.name }} {{ Util.NF(item.value) }} - + + {{ item.name }} + + {{ Util.NF(item.value) }} + @@ -421,7 +428,7 @@ onActivated(() => { wrap > @@ -429,7 +436,7 @@ onActivated(() => { diff --git a/packages/app/src/components/report/trend.vue b/packages/app/src/components/report/trend.vue index 7cd46365..ac9ade80 100644 --- a/packages/app/src/components/report/trend.vue +++ b/packages/app/src/components/report/trend.vue @@ -16,12 +16,13 @@ const { const chart = shallowReactive({ padding: 5, + axisHeight: 20, width: 1000, height: 200, lines: [], list: null, - density: 'Serial', + density: 'serial', // depends on duration densityOptions: [], @@ -116,30 +117,33 @@ const getResults = (item) => { const d = new Date(item.date); let dateH = d.toLocaleString(); - const density = item.density; + const items = chart.typeItems[chart.type]; + if (items) { + appendItemResults(item, results, items); + } else { + appendStatusResults(item, results); + } + const density = item.density; if (density) { + + const densityItem = chart.densityOptions.find((it) => it.value === density); + results.push({ icon: 'time', - name: `By ${density}`, + name: densityItem.label, value: item.count }); - if (density === 'Day') { + if (density === 'day') { dateH = d.toLocaleDateString(); } } - const items = chart.typeItems[chart.type]; - if (items) { - appendItemResults(item, results, items); - } else { - appendStatusResults(item, results); - } - results.push({ icon: 'calendar', + colspan: 3, name: dateH }); @@ -164,8 +168,7 @@ const appendStatusResults = (item, results) => { }); // asc caseTypes - const ascCaseTypes = state.reportData.caseTypes; - ascCaseTypes.forEach((k) => { + chart.caseTypes.forEach((k) => { const info = summary[k]; const v = item[ns + k]; results.push({ @@ -203,7 +206,7 @@ const getListByDensity = () => { } const trendList = chart.trendList; - if (density === 'Serial') { + if (density === 'serial') { const list = trendList.map((item, i) => { return { index: i, @@ -222,7 +225,7 @@ const getListByDensity = () => { len: 10, zero: 'T00:00:00.000Z' }; - if (density === 'Hour') { + if (density === 'hour') { dateInfo = { len: 13, zero: ':00:00.000Z' @@ -314,7 +317,7 @@ const getLineD = (currentPoints, backPoints) => { const getStatusLines = (list) => { const padding = chart.padding; const cw = chart.width - padding * 2; - const ch = chart.height - padding * 2; + const ch = chart.height - padding * 2 - chart.axisHeight; const xw = cw / (list.length - 1); let perviousPoints = list.map((t, i) => { @@ -324,9 +327,9 @@ const getStatusLines = (list) => { const summary = state.summary; const maxTests = chart.trendMax.tests; - // desc caseTypes - const descCaseTypes = [].concat(state.reportData.caseTypes).reverse(); - chart.lines = descCaseTypes.map((caseType) => { + const caseTypes = [].concat(chart.caseTypes).reverse(); + + chart.lines = caseTypes.map((caseType) => { const meta = summary[caseType]; const currentPoints = list.map((t, i) => { const [px, py] = perviousPoints[i]; @@ -345,12 +348,13 @@ const getStatusLines = (list) => { d }; }); + }; const getItemLines = (list, items) => { const padding = chart.padding; const cw = chart.width - padding * 2; - const ch = chart.height - padding * 2; + const ch = chart.height - padding * 2 - chart.axisHeight; const xw = cw / (list.length - 1); const trendMax = chart.trendMax; @@ -374,7 +378,7 @@ const getItemLines = (list, items) => { }); const lineFill = chart.bezier ? toBezier(points, 'L') : toStraight(points, 'L'); - const dFill = `M0,${ch}${lineFill}V${ch}z`; + const dFill = `M${padding},${padding + ch}${lineFill}V${padding + ch}z`; lines.push({ fill: color, @@ -394,6 +398,9 @@ const render = () => { return; } + // desc caseTypes + chart.caseTypes = [].concat(state.reportData.caseTypes); + const list = getListByDensity(); chart.list = list; @@ -427,6 +434,20 @@ const render = () => { chart.typeItems = typeItems; chart.typeOptions = ['Status'].concat(Object.keys(typeItems)); + let startDate = new Date(list[0].date); + let endDate = new Date(list[list.length - 1].date); + + if (chart.density === 'day') { + startDate = startDate.toLocaleDateString(); + endDate = endDate.toLocaleDateString(); + } else { + startDate = startDate.toLocaleString(); + endDate = endDate.toLocaleString(); + } + + chart.startDate = startDate; + chart.endDate = endDate; + const items = typeItems[type]; if (items) { return getItemLines(list, items); @@ -436,13 +457,22 @@ const render = () => { }; const initDensity = (duration) => { - const densityOptions = ['Serial']; + const densityOptions = [{ + label: 'Serial', + value: 'serial' + }]; const h = 60 * 60 * 1000; if (duration > h) { - densityOptions.push('Hour'); + densityOptions.push({ + label: 'By Hour', + value: 'hour' + }); } if (duration > 24 * h) { - densityOptions.push('Day'); + densityOptions.push({ + label: 'By Day', + value: 'day' + }); } chart.densityOptions = densityOptions; }; @@ -577,6 +607,19 @@ onMounted(() => { /> + + {{ chart.startDate }} + {{ chart.endDate }} + + { class="mcr-trend-popover" width="200px" > - - - + + - {{ item.name }} - - {{ item.value }} - {{ item.percent }} - {{ item.growth }} - - + + + {{ item.name }} + + + + {{ item.value }} + + + {{ item.percent }} + {{ item.growth }} + + + + @@ -635,4 +683,19 @@ onMounted(() => { max-width: 1000px; } } + +.popover-table { + td { + padding: 3px 10px 3px 0; + text-align: center; + } + + td:last-child { + text-align: right; + } + + td:first-child { + text-align: left; + } +} diff --git a/packages/app/src/images/icons/attachment.svg b/packages/app/src/images/icons/attachment.svg index 83c243cf..30d936d7 100644 --- a/packages/app/src/images/icons/attachment.svg +++ b/packages/app/src/images/icons/attachment.svg @@ -1,3 +1,4 @@ - - + + \ No newline at end of file diff --git a/packages/app/src/images/icons/error.svg b/packages/app/src/images/icons/error.svg index d4d66ace..cb1f208d 100644 --- a/packages/app/src/images/icons/error.svg +++ b/packages/app/src/images/icons/error.svg @@ -1 +1,8 @@ - \ No newline at end of file + + + + + + \ No newline at end of file diff --git a/packages/app/src/images/icons/log.svg b/packages/app/src/images/icons/log.svg index f7821ad2..d238ddea 100644 --- a/packages/app/src/images/icons/log.svg +++ b/packages/app/src/images/icons/log.svg @@ -1,5 +1,5 @@ - - + c-12.9,0-23.4-13.5-23.4-26.4v-548C150.8,113.6,165.1,103.3,178.3,103.3z" /> + \ No newline at end of file diff --git a/packages/app/src/images/icons/retry.svg b/packages/app/src/images/icons/retry.svg index 93a0ff54..026fc04f 100644 --- a/packages/app/src/images/icons/retry.svg +++ b/packages/app/src/images/icons/retry.svg @@ -1 +1,7 @@ - \ No newline at end of file + + + + + + \ No newline at end of file diff --git a/packages/app/src/images/icons/time.svg b/packages/app/src/images/icons/time.svg index 2f7d1e04..1ca535f9 100644 --- a/packages/app/src/images/icons/time.svg +++ b/packages/app/src/images/icons/time.svg @@ -1,7 +1,6 @@ - - - - + + + + \ No newline at end of file diff --git a/packages/app/src/modules/formatters.js b/packages/app/src/modules/formatters.js index f18f5621..22a0ce2d 100644 --- a/packages/app/src/modules/formatters.js +++ b/packages/app/src/modules/formatters.js @@ -48,6 +48,7 @@ const iconFormatter = (options) => { icon: '', size: '16px', button: false, + color: '#333', ... options }; createApp(IconLabel, props).mount(div); @@ -283,6 +284,7 @@ const formatters = { if (rowItem.errorNum) { return iconFormatter({ icon: 'error', + color: '#dd0000', button: true }); }