From bc9f9fbdec8614f5be1b016ee4e3f8a6a1364e93 Mon Sep 17 00:00:00 2001 From: therealrinku Date: Mon, 15 Dec 2025 18:41:06 +0545 Subject: [PATCH 1/2] Disable the star button when query is loading Changelog: fixed --- .../stars/components/star_count.vue | 7 ++++- .../stars/components/star_count_spec.js | 30 ++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/stars/components/star_count.vue b/app/assets/javascripts/stars/components/star_count.vue index d3a44152d3e465..fc168d580d28e4 100644 --- a/app/assets/javascripts/stars/components/star_count.vue +++ b/app/assets/javascripts/stars/components/star_count.vue @@ -36,6 +36,7 @@ export default { }, data() { return { + isLoading: false, count: this.starCount, isStarred: this.starred, }; @@ -52,7 +53,7 @@ export default { }, tooltip() { if (isLoggedIn()) { - return this.starText; + return ''; } return s__('ProjectOverview|You must sign in to star a project'); @@ -75,6 +76,7 @@ export default { } try { + this.isLoading = true; const { data } = await this.$apollo.mutate({ mutation: setStarStatusMutation, variables: { @@ -90,9 +92,11 @@ export default { this.count = data.starProject.count; this.isStarred = !this.isStarred; } + this.isLoading = false; } catch (failure) { reportToSentry(this.$options.name, failure); this.showToastMessage(); + this.isLoading = false; } }, }, @@ -109,6 +113,7 @@ export default { data-testid="star-button" :title="tooltip" :href="starHref" + :disabled="isLoading" @click="setStarStatus()" > diff --git a/spec/frontend/stars/components/star_count_spec.js b/spec/frontend/stars/components/star_count_spec.js index b07ae1d9e29288..27feb04cda2e1c 100644 --- a/spec/frontend/stars/components/star_count_spec.js +++ b/spec/frontend/stars/components/star_count_spec.js @@ -1,5 +1,5 @@ import VueApollo from 'vue-apollo'; -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import StarCount from '~/stars/components/star_count.vue'; import createMockApollo from 'helpers/mock_apollo_helper'; @@ -151,4 +151,32 @@ describe('StarCount', () => { expect(findStarButton().attributes('href')).toBe('sign/in/path'); }); }); + + describe('star button state', () => { + it('is disabled when query is running and enabled when query is succesful', async () => { + createComponent(); + const starButton = findStarButton(); + + starButton.vm.$emit('click'); + await nextTick(); + expect(starButton.props('disabled')).toBe(true); + + await waitForPromises(); + expect(starButton.props('disabled')).toBe(false); + }); + + it('is disabled when query is running and enabled when query fails', async () => { + createComponent({ + setStarStatusHandler: jest.fn().mockRejectedValue('Internal server error'), + }); + const starButton = findStarButton(); + + starButton.vm.$emit('click'); + await nextTick(); + expect(starButton.props('disabled')).toBe(true); + + await waitForPromises(); + expect(starButton.props('disabled')).toBe(false); + }); + }); }); -- GitLab From 4b20d239a178cbc82bc09a0f5e6197262ed74c13 Mon Sep 17 00:00:00 2001 From: therealrinku Date: Tue, 16 Dec 2025 19:54:17 +0545 Subject: [PATCH 2/2] Add finally block --- app/assets/javascripts/stars/components/star_count.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/stars/components/star_count.vue b/app/assets/javascripts/stars/components/star_count.vue index fc168d580d28e4..332d58d39282eb 100644 --- a/app/assets/javascripts/stars/components/star_count.vue +++ b/app/assets/javascripts/stars/components/star_count.vue @@ -92,10 +92,10 @@ export default { this.count = data.starProject.count; this.isStarred = !this.isStarred; } - this.isLoading = false; } catch (failure) { reportToSentry(this.$options.name, failure); this.showToastMessage(); + } finally { this.isLoading = false; } }, -- GitLab