From 2457ebbeaa69befc824fa609a4e12f4c55bb4c88 Mon Sep 17 00:00:00 2001 From: jonasongg <120372506+jonasongg@users.noreply.github.com> Date: Tue, 7 May 2024 03:23:44 +0800 Subject: [PATCH] Add optimise timeline feature (#2180) Add optimise timeline feature Currently, the ramps have a lot of empty space if the since and until dates are specified far apart. Let's add a checkbox that can eliminate this empty space for each ramp. This is especially useful if RepoSense is to be used to set up a report of an individual's past OSS contributions. --- docs/ug/usingReports.md | 1 + .../chartView_optimiseTimeline.cy.js | 151 ++++++++++++++++++ .../codeView/codeView_renderFilterHash.cy.js | 14 ++ frontend/src/components/c-ramp.vue | 83 +++++++--- frontend/src/components/c-summary-charts.vue | 54 ++++++- frontend/src/views/c-summary.vue | 20 ++- 6 files changed, 293 insertions(+), 30 deletions(-) create mode 100644 frontend/cypress/tests/chartView/chartView_optimiseTimeline.cy.js diff --git a/docs/ug/usingReports.md b/docs/ug/usingReports.md index 6aa5ebae6c..d0ebbd13c6 100644 --- a/docs/ug/usingReports.md +++ b/docs/ug/usingReports.md @@ -119,6 +119,7 @@ The `Tool Bar` at the top of the Chart panel provides a set of configuration opt * `Merge group`: merges all the ramp charts of each group into a single ramp chart; aggregates the contribution of each group. * viewing of authored code of the group as a whole is available when `group by repos`. * `Show tags`: shows the tags of all the repos under a group +* `Trim timeline`: trims the starting and ending portion of each ramp where no commits were made; only the part of each ramp where commits were made will be shown. Notes:
[1] **`Sort groups by`**: each main group has its own index and percentile according to its ranking position after sorting (e.g., if the groups are sorted by contribution in descending order, a 25% percentile indicates that the group is in the top 25% of the whole cohort in terms of contribution)
. diff --git a/frontend/cypress/tests/chartView/chartView_optimiseTimeline.cy.js b/frontend/cypress/tests/chartView/chartView_optimiseTimeline.cy.js new file mode 100644 index 0000000000..43e64806fe --- /dev/null +++ b/frontend/cypress/tests/chartView/chartView_optimiseTimeline.cy.js @@ -0,0 +1,151 @@ +describe('optimise timeline', () => { + it('ramp padding should only exist when optimise timeline is checked', () => { + cy.get('#summary label.optimise-timeline > input:visible') + .should('be.visible') + .uncheck() + .should('be.not.checked'); + + cy.get('#summary-charts .summary-chart') + .first() + .find('.summary-chart__ramp .ramp .ramp-padding') + .should('have.css', 'left', '0px'); + + cy.get('#summary label.optimise-timeline > input:visible') + .should('be.visible') + .check() + .should('be.checked'); + + cy.get('#summary-charts .summary-chart') + .first() + .find('.summary-chart__ramp .ramp .ramp-padding') + .should('have.not.css', 'left', '0px'); + }); + + it('should retain the same number of ramp slices', () => { + cy.get('#summary-charts .summary-chart') + .first() + .find('.summary-chart__ramp .ramp .ramp-padding a') + .then(($el) => { + const rampSlices = $el.length; + + cy.get('#summary label.optimise-timeline > input:visible') + .should('be.visible') + .check() + .should('be.checked'); + + cy.get('#summary-charts .summary-chart') + .first() + .find('.summary-chart__ramp .ramp .ramp-padding a') + .should('have.length', rampSlices); + }); + }); + + it('start and end date indicators should exist', () => { + cy.get('#summary label.optimise-timeline > input:visible') + .should('be.visible') + .check() + .should('be.checked'); + + cy.get('#summary-charts .summary-chart') + .first() + .find('.summary-chart__ramp .date-indicators span') + .first() + .should('have.text', '2018-05-03'); + + cy.get('#summary-charts .summary-chart') + .first() + .find('.summary-chart__ramp .date-indicators span') + .last() + + // 3/3 on GitHub CI, 3/4 on local + .should('have.text', '2023-03-03'); + }); + + it('no commits in range should not have date indicators', () => { + cy.get('#summary label.optimise-timeline > input:visible') + .should('be.visible') + .check() + .should('be.checked'); + + // change since date + cy.get('input[name="since"]') + .type('2018-12-31'); + + // change until date + cy.get('input[name="until"]') + .type('2019-01-01'); + + cy.get('#summary-charts .summary-chart') + .first() + .find('.summary-chart__ramp .date-indicators') + .should('not.exist'); + }); + + it('zoom panel range should work correctly when timeline is optimised', () => { + cy.get('.icon-button.fa-list-ul') + .should('exist') + .first() + .click(); + + cy.get('#tab-zoom') + .should('be.visible'); + + // verifies the ramp chart is not optimised and has empty space on the right + cy.get('#tab-zoom .ramp a') + .first() + .invoke('css', 'right') + .then((val) => parseFloat(val)) + .should('gt', 0); + + cy.get('#summary label.optimise-timeline > input') + .check() + .should('be.checked'); + + cy.get('.icon-button.fa-list-ul') + .should('exist') + .first() + .click(); + + cy.get('#tab-zoom') + .should('be.visible'); + + // verifies the date range is correctly optimised + cy.get('#tab-zoom .period') + .should('contain', '2018-05-03 to 2023-03-03'); + + // verifies the ramp chart is optimised and has no empty space on the right + cy.get('#tab-zoom .ramp a') + .first() + .invoke('css', 'right') + .then((val) => parseFloat(val)) + .should('lt', 1); + }); + + it('subzoom panel range should work correctly when timeline is optimised', () => { + const zoomKey = Cypress.platform === 'darwin' ? '{meta}' : '{ctrl}'; + + cy.get('#summary label.optimise-timeline > input:visible') + .should('be.visible') + .check() + .should('be.checked'); + + // clicking from the 10th px to the 50th px in the ramp + cy.get('body').type(zoomKey, { release: false }) + .get('#summary-charts .summary-chart__ramp .ramp') + .first() + .click(110, 20) + .click(120, 20); + + cy.get('#tab-zoom') + .should('be.visible'); + + cy.get('#tab-zoom .ramp .ramp__slice') + .should('have.length', 1); + + cy.get('#tab-zoom .ramp .ramp__slice') + .invoke('attr', 'title') + .then((title) => { + cy.wrap(title).should('eq', '[2019-08-18] AboutUs: update team members (#867): +94 -12 lines '); + }); + }); +}); diff --git a/frontend/cypress/tests/codeView/codeView_renderFilterHash.cy.js b/frontend/cypress/tests/codeView/codeView_renderFilterHash.cy.js index 1cc456e0e4..fbe6d467aa 100644 --- a/frontend/cypress/tests/codeView/codeView_renderFilterHash.cy.js +++ b/frontend/cypress/tests/codeView/codeView_renderFilterHash.cy.js @@ -316,6 +316,20 @@ describe('render filter hash', () => { .should('contain', 'viewRepoTags=true'); }); + it('optimise timeline: url params should persist after change and reload', () => { + cy.get('#summary label.optimise-timeline input:visible') + .should('be.visible') + .check(); + + cy.url() + .should('contain', 'optimiseTimeline=true'); + + cy.reload(); + + cy.url() + .should('contain', 'optimiseTimeline=true'); + }); + it('checked file types: url params should persist after change and reload', () => { cy.get('#summary label.filter-breakdown input:visible') .should('not.be.checked'); diff --git a/frontend/src/components/c-ramp.vue b/frontend/src/components/c-ramp.vue index 65e1fe780c..40f02b05cb 100644 --- a/frontend/src/components/c-ramp.vue +++ b/frontend/src/components/c-ramp.vue @@ -1,22 +1,25 @@