Commit 457658a5 authored by Kev's avatar Kev Committed by Kushal Pandya

Replace Loading Button with Icon on All Vulnerability Lists

parent 3d94bb44
<script> <script>
import produce from 'immer'; import produce from 'immer';
import { GlAlert, GlButton, GlIntersectionObserver } from '@gitlab/ui'; import { GlAlert, GlLoadingIcon, GlIntersectionObserver } from '@gitlab/ui';
import VulnerabilityList from './vulnerability_list.vue'; import VulnerabilityList from './vulnerability_list.vue';
import vulnerabilitiesQuery from '../graphql/group_vulnerabilities.graphql'; import vulnerabilitiesQuery from '../graphql/group_vulnerabilities.graphql';
import { VULNERABILITIES_PER_PAGE } from '../store/constants'; import { VULNERABILITIES_PER_PAGE } from '../store/constants';
...@@ -9,7 +9,7 @@ import { preparePageInfo } from '../helpers'; ...@@ -9,7 +9,7 @@ import { preparePageInfo } from '../helpers';
export default { export default {
components: { components: {
GlAlert, GlAlert,
GlButton, GlLoadingIcon,
GlIntersectionObserver, GlIntersectionObserver,
VulnerabilityList, VulnerabilityList,
}, },
...@@ -120,9 +120,7 @@ export default { ...@@ -120,9 +120,7 @@ export default {
class="text-center" class="text-center"
@appear="fetchNextPage" @appear="fetchNextPage"
> >
<gl-button :loading="isLoadingQuery" :disabled="isLoadingQuery" @click="fetchNextPage">{{ <gl-loading-icon v-if="isLoadingQuery" size="md" />
s__('SecurityReports|Load more vulnerabilities')
}}</gl-button>
</gl-intersection-observer> </gl-intersection-observer>
</div> </div>
</template> </template>
<script> <script>
import produce from 'immer'; import produce from 'immer';
import { GlAlert, GlButton, GlIntersectionObserver, GlLoadingIcon } from '@gitlab/ui'; import { GlAlert, GlIntersectionObserver, GlLoadingIcon } from '@gitlab/ui';
import { fetchPolicies } from '~/lib/graphql'; import { fetchPolicies } from '~/lib/graphql';
import VulnerabilityList from './vulnerability_list.vue'; import VulnerabilityList from './vulnerability_list.vue';
import vulnerabilitiesQuery from '../graphql/instance_vulnerabilities.graphql'; import vulnerabilitiesQuery from '../graphql/instance_vulnerabilities.graphql';
...@@ -10,7 +10,6 @@ import { preparePageInfo } from '../helpers'; ...@@ -10,7 +10,6 @@ import { preparePageInfo } from '../helpers';
export default { export default {
components: { components: {
GlAlert, GlAlert,
GlButton,
GlIntersectionObserver, GlIntersectionObserver,
GlLoadingIcon, GlLoadingIcon,
VulnerabilityList, VulnerabilityList,
...@@ -33,7 +32,7 @@ export default { ...@@ -33,7 +32,7 @@ export default {
}; };
}, },
computed: { computed: {
isQueryLoading() { isLoadingQuery() {
return this.$apollo.queries.vulnerabilities.loading; return this.$apollo.queries.vulnerabilities.loading;
}, },
sort() { sort() {
...@@ -117,10 +116,7 @@ export default { ...@@ -117,10 +116,7 @@ export default {
class="text-center" class="text-center"
@appear="fetchNextPage" @appear="fetchNextPage"
> >
<gl-button :disabled="isFirstResultLoading" @click="fetchNextPage"> <gl-loading-icon v-if="isLoadingQuery" size="md" />
<gl-loading-icon v-if="isQueryLoading" size="md" />
<template v-else>{{ s__('SecurityReports|Load more vulnerabilities') }}</template>
</gl-button>
</gl-intersection-observer> </gl-intersection-observer>
</div> </div>
</template> </template>
<script> <script>
import produce from 'immer'; import produce from 'immer';
import { GlAlert, GlButton, GlIntersectionObserver } from '@gitlab/ui'; import { GlAlert, GlLoadingIcon, GlIntersectionObserver } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import VulnerabilityList from './vulnerability_list.vue'; import VulnerabilityList from './vulnerability_list.vue';
...@@ -13,7 +13,7 @@ export default { ...@@ -13,7 +13,7 @@ export default {
name: 'ProjectVulnerabilitiesApp', name: 'ProjectVulnerabilitiesApp',
components: { components: {
GlAlert, GlAlert,
GlButton, GlLoadingIcon,
GlIntersectionObserver, GlIntersectionObserver,
VulnerabilityList, VulnerabilityList,
}, },
...@@ -152,12 +152,8 @@ export default { ...@@ -152,12 +152,8 @@ export default {
class="text-center" class="text-center"
@appear="fetchNextPage" @appear="fetchNextPage"
> >
<gl-button <gl-loading-icon v-if="isLoadingVulnerabilities" size="md" />
:loading="isLoadingVulnerabilities" <span v-else>&nbsp;</span>
:disabled="isLoadingVulnerabilities"
@click="fetchNextPage"
>{{ s__('SecurityReports|Load more vulnerabilities') }}</gl-button
>
</gl-intersection-observer> </gl-intersection-observer>
</div> </div>
</template> </template>
---
title: Replace Loading Button with Icon on All Vulnerability Lists
merge_request: 41019
author: Kev @KevSlashNull
type: other
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlAlert, GlTable, GlEmptyState, GlIntersectionObserver } from '@gitlab/ui'; import { GlAlert, GlTable, GlEmptyState, GlIntersectionObserver, GlLoadingIcon } from '@gitlab/ui';
import FirstClassGroupVulnerabilities from 'ee/security_dashboard/components/first_class_group_security_dashboard_vulnerabilities.vue'; import FirstClassGroupVulnerabilities from 'ee/security_dashboard/components/first_class_group_security_dashboard_vulnerabilities.vue';
import VulnerabilityList from 'ee/security_dashboard/components/vulnerability_list.vue'; import VulnerabilityList from 'ee/security_dashboard/components/vulnerability_list.vue';
import { generateVulnerabilities } from './mock_data'; import { generateVulnerabilities } from './mock_data';
...@@ -12,6 +12,7 @@ describe('First Class Group Dashboard Vulnerabilities Component', () => { ...@@ -12,6 +12,7 @@ describe('First Class Group Dashboard Vulnerabilities Component', () => {
const findIntersectionObserver = () => wrapper.find(GlIntersectionObserver); const findIntersectionObserver = () => wrapper.find(GlIntersectionObserver);
const findVulnerabilities = () => wrapper.find(VulnerabilityList); const findVulnerabilities = () => wrapper.find(VulnerabilityList);
const findAlert = () => wrapper.find(GlAlert); const findAlert = () => wrapper.find(GlAlert);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
const createWrapper = ({ $apollo, stubs }) => { const createWrapper = ({ $apollo, stubs }) => {
return shallowMount(FirstClassGroupVulnerabilities, { return shallowMount(FirstClassGroupVulnerabilities, {
...@@ -42,6 +43,10 @@ describe('First Class Group Dashboard Vulnerabilities Component', () => { ...@@ -42,6 +43,10 @@ describe('First Class Group Dashboard Vulnerabilities Component', () => {
it('passes down isLoading correctly', () => { it('passes down isLoading correctly', () => {
expect(findVulnerabilities().props()).toMatchObject({ isLoading: true }); expect(findVulnerabilities().props()).toMatchObject({ isLoading: true });
}); });
it('does not show the loading spinner', () => {
expect(findLoadingIcon().exists()).toBe(false);
});
}); });
describe('when the query returned an error status', () => { describe('when the query returned an error status', () => {
...@@ -150,4 +155,24 @@ describe('First Class Group Dashboard Vulnerabilities Component', () => { ...@@ -150,4 +155,24 @@ describe('First Class Group Dashboard Vulnerabilities Component', () => {
expect(findIntersectionObserver().exists()).toBe(true); expect(findIntersectionObserver().exists()).toBe(true);
}); });
}); });
describe('when the query is loading and there is another page', () => {
beforeEach(() => {
wrapper = createWrapper({
$apollo: {
queries: { vulnerabilities: { loading: true } },
},
});
wrapper.setData({
pageInfo: {
hasNextPage: true,
},
});
});
it('should render the loading spinner', () => {
expect(findLoadingIcon().exists()).toBe(true);
});
});
}); });
import Vuex from 'vuex'; import Vuex from 'vuex';
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount, createLocalVue } from '@vue/test-utils';
import { GlAlert, GlTable, GlEmptyState, GlIntersectionObserver } from '@gitlab/ui'; import { GlAlert, GlTable, GlEmptyState, GlIntersectionObserver, GlLoadingIcon } from '@gitlab/ui';
import FirstClassInstanceVulnerabilities from 'ee/security_dashboard/components/first_class_instance_security_dashboard_vulnerabilities.vue'; import FirstClassInstanceVulnerabilities from 'ee/security_dashboard/components/first_class_instance_security_dashboard_vulnerabilities.vue';
import VulnerabilityList from 'ee/security_dashboard/components/vulnerability_list.vue'; import VulnerabilityList from 'ee/security_dashboard/components/vulnerability_list.vue';
import { generateVulnerabilities } from './mock_data'; import { generateVulnerabilities } from './mock_data';
...@@ -15,6 +15,7 @@ describe('First Class Instance Dashboard Vulnerabilities Component', () => { ...@@ -15,6 +15,7 @@ describe('First Class Instance Dashboard Vulnerabilities Component', () => {
const findIntersectionObserver = () => wrapper.find(GlIntersectionObserver); const findIntersectionObserver = () => wrapper.find(GlIntersectionObserver);
const findVulnerabilities = () => wrapper.find(VulnerabilityList); const findVulnerabilities = () => wrapper.find(VulnerabilityList);
const findAlert = () => wrapper.find(GlAlert); const findAlert = () => wrapper.find(GlAlert);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
const createWrapper = ({ stubs, loading = false, isUpdatingProjects, data } = {}) => { const createWrapper = ({ stubs, loading = false, isUpdatingProjects, data } = {}) => {
store = new Vuex.Store({ store = new Vuex.Store({
...@@ -64,6 +65,10 @@ describe('First Class Instance Dashboard Vulnerabilities Component', () => { ...@@ -64,6 +65,10 @@ describe('First Class Instance Dashboard Vulnerabilities Component', () => {
it('passes down isLoading correctly', () => { it('passes down isLoading correctly', () => {
expect(findVulnerabilities().props()).toMatchObject({ isLoading: true }); expect(findVulnerabilities().props()).toMatchObject({ isLoading: true });
}); });
it('does not render the loading spinner', () => {
expect(findLoadingIcon().exists()).toBe(false);
});
}); });
describe('when the query returned an error status', () => { describe('when the query returned an error status', () => {
...@@ -162,4 +167,25 @@ describe('First Class Instance Dashboard Vulnerabilities Component', () => { ...@@ -162,4 +167,25 @@ describe('First Class Instance Dashboard Vulnerabilities Component', () => {
expect(findIntersectionObserver().exists()).toBe(true); expect(findIntersectionObserver().exists()).toBe(true);
}); });
}); });
describe('when the query is loading and there is another page', () => {
beforeEach(() => {
wrapper = createWrapper({
loading: true,
data: () => ({
pageInfo: {
hasNextPage: true,
},
}),
});
});
it('should render the observer component', () => {
expect(findIntersectionObserver().exists()).toBe(true);
});
it('should render the loading spinner', () => {
expect(findLoadingIcon().exists()).toBe(true);
});
});
}); });
import { GlAlert, GlIntersectionObserver } from '@gitlab/ui'; import { GlAlert, GlIntersectionObserver, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import ProjectVulnerabilitiesApp from 'ee/security_dashboard/components/project_vulnerabilities.vue'; import ProjectVulnerabilitiesApp from 'ee/security_dashboard/components/project_vulnerabilities.vue';
import VulnerabilityList from 'ee/security_dashboard/components/vulnerability_list.vue'; import VulnerabilityList from 'ee/security_dashboard/components/vulnerability_list.vue';
...@@ -29,6 +29,7 @@ describe('Vulnerabilities app component', () => { ...@@ -29,6 +29,7 @@ describe('Vulnerabilities app component', () => {
const findIntersectionObserver = () => wrapper.find(GlIntersectionObserver); const findIntersectionObserver = () => wrapper.find(GlIntersectionObserver);
const findAlert = () => wrapper.find(GlAlert); const findAlert = () => wrapper.find(GlAlert);
const findVulnerabilityList = () => wrapper.find(VulnerabilityList); const findVulnerabilityList = () => wrapper.find(VulnerabilityList);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
beforeEach(() => { beforeEach(() => {
createWrapper(); createWrapper();
...@@ -47,6 +48,10 @@ describe('Vulnerabilities app component', () => { ...@@ -47,6 +48,10 @@ describe('Vulnerabilities app component', () => {
it('should be in the loading state', () => { it('should be in the loading state', () => {
expect(findVulnerabilityList().props().isLoading).toBe(true); expect(findVulnerabilityList().props().isLoading).toBe(true);
}); });
it('should not render the loading spinner', () => {
expect(findLoadingIcon().exists()).toBe(false);
});
}); });
describe('with some vulnerabilities', () => { describe('with some vulnerabilities', () => {
...@@ -93,6 +98,10 @@ describe('Vulnerabilities app component', () => { ...@@ -93,6 +98,10 @@ describe('Vulnerabilities app component', () => {
expect(wrapper.vm.sortBy).toBe('description'); expect(wrapper.vm.sortBy).toBe('description');
expect(wrapper.vm.sortDirection).toBe('asc'); expect(wrapper.vm.sortDirection).toBe('asc');
}); });
it('should render the loading spinner', () => {
expect(findLoadingIcon().exists()).toBe(false);
});
}); });
describe('with more than a page of vulnerabilities', () => { describe('with more than a page of vulnerabilities', () => {
...@@ -113,6 +122,10 @@ describe('Vulnerabilities app component', () => { ...@@ -113,6 +122,10 @@ describe('Vulnerabilities app component', () => {
it('should render the observer component', () => { it('should render the observer component', () => {
expect(findIntersectionObserver().exists()).toBe(true); expect(findIntersectionObserver().exists()).toBe(true);
}); });
it('should render the loading spinner', () => {
expect(findLoadingIcon().exists()).toBe(true);
});
}); });
describe("when there's an error loading vulnerabilities", () => { describe("when there's an error loading vulnerabilities", () => {
......
...@@ -22559,9 +22559,6 @@ msgstr "" ...@@ -22559,9 +22559,6 @@ msgstr ""
msgid "SecurityReports|Learn more about setting up your dashboard" msgid "SecurityReports|Learn more about setting up your dashboard"
msgstr "" msgstr ""
msgid "SecurityReports|Load more vulnerabilities"
msgstr ""
msgid "SecurityReports|Monitor vulnerabilities in your code" msgid "SecurityReports|Monitor vulnerabilities in your code"
msgstr "" msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment