From f07af5a45d883cb629d4d0ef7e953cf8444619d3 Mon Sep 17 00:00:00 2001 From: jonasongg <120372506+jonasongg@users.noreply.github.com> Date: Thu, 18 Apr 2024 21:30:32 +0800 Subject: [PATCH] [#2130] Add highlight and scroll to group (#2131) Add highlight and scroll to group It can be useful to have a way to send a RepoSense link that automatically scrolls to and highlights the group that the sender thinks the recipient should pay attention to, saving them time to find the repo in question. Let's add this functionality to add convenience when sending around RepoSense reports. --- .../chartView_scrollToActiveRepo.cy.js | 62 +++++++++++++++++++ frontend/src/components/c-summary-charts.vue | 21 ++++++- 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 frontend/cypress/tests/chartView/chartView_scrollToActiveRepo.cy.js diff --git a/frontend/cypress/tests/chartView/chartView_scrollToActiveRepo.cy.js b/frontend/cypress/tests/chartView/chartView_scrollToActiveRepo.cy.js new file mode 100644 index 0000000000..97afc7b1ea --- /dev/null +++ b/frontend/cypress/tests/chartView/chartView_scrollToActiveRepo.cy.js @@ -0,0 +1,62 @@ +describe('scroll to active repo', () => { + // need to set scrollBehavior to false because the default behavior is to scroll the element into view + it('selecting a visible repo should not scroll', { scrollBehavior: false }, () => { + // close the error message box + cy.get('.error-message-box') + .should('be.visible'); + + cy.get('#summary-wrapper > #summary > .error-message-box > .error-message-box__close-button') + .click(); + + cy.get('.error-message-box') + .should('not.be.visible'); + + cy.get('.icon-button.fa-code') + .should('exist') + .first(); + + let scrollTopOriginal = 0; + cy.get('#summary-wrapper') + .first() + .then(($el) => { + scrollTopOriginal = $el.prop('scrollTop'); + }); + + cy.get('.icon-button.fa-code') + .should('exist') + .first() + .click(); + + cy.get('#summary-wrapper') + .first() + .then(($el) => { + const scrollTop = $el.prop('scrollTop'); + expect(scrollTop).to.equal(scrollTopOriginal); + }); + }); + + it('selecting a non-visible repo should scroll', () => { + cy.get('.icon-button.fa-code') + .should('exist') + .last() + .click(); + + cy.get('#summary-wrapper') + .first() + .then(($el) => { + const scrollTop = $el.prop('scrollTop'); + expect(scrollTop).to.not.equal(0); + }); + + cy.url() + .should('contain', 'tabAuthor=yong24s') + .should('contain', 'tabRepo=reposense%2FRepoSense%5Bcypress%5D'); + + cy.reload(); + + cy.get('.icon-button.fa-code') + .should('exist') + .last() + .should('be.visible'); + }); +}); diff --git a/frontend/src/components/c-summary-charts.vue b/frontend/src/components/c-summary-charts.vue index e017ec6045..7ebe313ddf 100644 --- a/frontend/src/components/c-summary-charts.vue +++ b/frontend/src/components/c-summary-charts.vue @@ -153,7 +153,8 @@ .summary-chart( v-for="(user, j) in getRepo(repo)", v-bind:style="isChartGroupWidgetMode && j === getRepo(repo).length - 1 ? {'marginBottom': 0} : {}", - v-bind:ref="'summary-chart-' + j" + v-bind:ref="'summary-chart-' + j", + v-bind:id="user.name === activeUser && user.repoName === activeRepo ? 'selectedChart' : null" ) .summary-chart__title( v-if="!isGroupMerged(getGroupName(repo))", @@ -428,6 +429,15 @@ export default defineComponent({ this.removeSelectedTab(); } }, + + // watching so highlighted only when summary charts are rendered + filteredRepos() { + this.$nextTick(() => { + if (this.activeRepo !== null && this.activeUser !== null) { + this.scrollToActiveRepo(); + } + }); + }, }, created(): void { this.retrieveSelectedTabHash(); @@ -829,6 +839,8 @@ export default defineComponent({ this.activeTabType = tabType; window.encodeHash(); + + this.$nextTick(() => this.scrollToActiveRepo()); }, removeSelectedTab(): void { @@ -881,6 +893,13 @@ export default defineComponent({ return totalContribution / totalCommits; }, + + scrollToActiveRepo(): void { + const chart = document.getElementById('selectedChart'); + if (chart) { + chart.scrollIntoView({ block: 'nearest' }); + } + }, }, });