Commit 15fc6703 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '241763-Replace-Loading-Icon-With-Infinite-Scrolling' into 'master'

Replace Loading Button with Icon on All Vulnerability Lists

See merge request gitlab-org/gitlab!41019
parents 6ec64f96 457658a5
<script>
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 vulnerabilitiesQuery from '../graphql/group_vulnerabilities.graphql';
import { VULNERABILITIES_PER_PAGE } from '../store/constants';
......@@ -9,7 +9,7 @@ import { preparePageInfo } from '../helpers';
export default {
components: {
GlAlert,
GlButton,
GlLoadingIcon,
GlIntersectionObserver,
VulnerabilityList,
},
......@@ -120,9 +120,7 @@ export default {
class="text-center"
@appear="fetchNextPage"
>
<gl-button :loading="isLoadingQuery" :disabled="isLoadingQuery" @click="fetchNextPage">{{
s__('SecurityReports|Load more vulnerabilities')
}}</gl-button>
<gl-loading-icon v-if="isLoadingQuery" size="md" />
</gl-intersection-observer>
</div>
</template>
<script>
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 VulnerabilityList from './vulnerability_list.vue';
import vulnerabilitiesQuery from '../graphql/instance_vulnerabilities.graphql';
......@@ -10,7 +10,6 @@ import { preparePageInfo } from '../helpers';
export default {
components: {
GlAlert,
GlButton,
GlIntersectionObserver,
GlLoadingIcon,
VulnerabilityList,
......@@ -33,7 +32,7 @@ export default {
};
},
computed: {
isQueryLoading() {
isLoadingQuery() {
return this.$apollo.queries.vulnerabilities.loading;
},
sort() {
......@@ -117,10 +116,7 @@ export default {
class="text-center"
@appear="fetchNextPage"
>
<gl-button :disabled="isFirstResultLoading" @click="fetchNextPage">
<gl-loading-icon v-if="isQueryLoading" size="md" />
<template v-else>{{ s__('SecurityReports|Load more vulnerabilities') }}</template>
</gl-button>
<gl-loading-icon v-if="isLoadingQuery" size="md" />
</gl-intersection-observer>
</div>
</template>
<script>
import produce from 'immer';
import { GlAlert, GlButton, GlIntersectionObserver } from '@gitlab/ui';
import { GlAlert, GlLoadingIcon, GlIntersectionObserver } from '@gitlab/ui';
import { __ } from '~/locale';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import VulnerabilityList from './vulnerability_list.vue';
......@@ -13,7 +13,7 @@ export default {
name: 'ProjectVulnerabilitiesApp',
components: {
GlAlert,
GlButton,
GlLoadingIcon,
GlIntersectionObserver,
VulnerabilityList,
},
......@@ -152,12 +152,8 @@ export default {
class="text-center"
@appear="fetchNextPage"
>
<gl-button
:loading="isLoadingVulnerabilities"
:disabled="isLoadingVulnerabilities"
@click="fetchNextPage"
>{{ s__('SecurityReports|Load more vulnerabilities') }}</gl-button
>
<gl-loading-icon v-if="isLoadingVulnerabilities" size="md" />
<span v-else>&nbsp;</span>
</gl-intersection-observer>
</div>
</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 { 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 VulnerabilityList from 'ee/security_dashboard/components/vulnerability_list.vue';
import { generateVulnerabilities } from './mock_data';
......@@ -12,6 +12,7 @@ describe('First Class Group Dashboard Vulnerabilities Component', () => {
const findIntersectionObserver = () => wrapper.find(GlIntersectionObserver);
const findVulnerabilities = () => wrapper.find(VulnerabilityList);
const findAlert = () => wrapper.find(GlAlert);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
const createWrapper = ({ $apollo, stubs }) => {
return shallowMount(FirstClassGroupVulnerabilities, {
......@@ -42,6 +43,10 @@ describe('First Class Group Dashboard Vulnerabilities Component', () => {
it('passes down isLoading correctly', () => {
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', () => {
......@@ -150,4 +155,24 @@ describe('First Class Group Dashboard Vulnerabilities Component', () => {
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 { 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 VulnerabilityList from 'ee/security_dashboard/components/vulnerability_list.vue';
import { generateVulnerabilities } from './mock_data';
......@@ -15,6 +15,7 @@ describe('First Class Instance Dashboard Vulnerabilities Component', () => {
const findIntersectionObserver = () => wrapper.find(GlIntersectionObserver);
const findVulnerabilities = () => wrapper.find(VulnerabilityList);
const findAlert = () => wrapper.find(GlAlert);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
const createWrapper = ({ stubs, loading = false, isUpdatingProjects, data } = {}) => {
store = new Vuex.Store({
......@@ -64,6 +65,10 @@ describe('First Class Instance Dashboard Vulnerabilities Component', () => {
it('passes down isLoading correctly', () => {
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', () => {
......@@ -162,4 +167,25 @@ describe('First Class Instance Dashboard Vulnerabilities Component', () => {
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 ProjectVulnerabilitiesApp from 'ee/security_dashboard/components/project_vulnerabilities.vue';
import VulnerabilityList from 'ee/security_dashboard/components/vulnerability_list.vue';
......@@ -29,6 +29,7 @@ describe('Vulnerabilities app component', () => {
const findIntersectionObserver = () => wrapper.find(GlIntersectionObserver);
const findAlert = () => wrapper.find(GlAlert);
const findVulnerabilityList = () => wrapper.find(VulnerabilityList);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
beforeEach(() => {
createWrapper();
......@@ -47,6 +48,10 @@ describe('Vulnerabilities app component', () => {
it('should be in the loading state', () => {
expect(findVulnerabilityList().props().isLoading).toBe(true);
});
it('should not render the loading spinner', () => {
expect(findLoadingIcon().exists()).toBe(false);
});
});
describe('with some vulnerabilities', () => {
......@@ -93,6 +98,10 @@ describe('Vulnerabilities app component', () => {
expect(wrapper.vm.sortBy).toBe('description');
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', () => {
......@@ -113,6 +122,10 @@ describe('Vulnerabilities app component', () => {
it('should render the observer component', () => {
expect(findIntersectionObserver().exists()).toBe(true);
});
it('should render the loading spinner', () => {
expect(findLoadingIcon().exists()).toBe(true);
});
});
describe("when there's an error loading vulnerabilities", () => {
......
......@@ -22565,9 +22565,6 @@ msgstr ""
msgid "SecurityReports|Learn more about setting up your dashboard"
msgstr ""
msgid "SecurityReports|Load more vulnerabilities"
msgstr ""
msgid "SecurityReports|Monitor vulnerabilities in your code"
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