Improve loading UX

Put clicked button in the loading state and disable other buttons
parent 755b86a1
......@@ -19,11 +19,17 @@ export default {
required: true,
},
},
data: () => ({
isRunningScan: null,
}),
methods: {
async runScan({ id }) {
this.isRunningScan = id;
try {
const {
data: {
dastProfileRun: { pipelineUrl, errors },
},
} = await this.$apollo.mutate({
mutation: dastProfileRunMutation,
variables: {
......@@ -44,6 +50,7 @@ export default {
}
},
handleError(error) {
this.isRunningScan = null;
createFlash({ message: ERROR_MESSAGES[ERROR_RUN_SCAN], error, captureError: true });
},
},
......@@ -58,9 +65,14 @@ export default {
</template>
<template #actions="{ profile }">
<gl-button size="small" data-testid="dast-scan-run-button" @click="runScan(profile)">{{
s__('DastProfiles|Run scan')
}}</gl-button>
<gl-button
size="small"
data-testid="dast-scan-run-button"
:loading="isRunningScan === profile.id"
:disabled="Boolean(isRunningScan)"
@click="runScan(profile)"
>{{ s__('DastProfiles|Run scan') }}</gl-button
>
</template>
</profiles-list>
</template>
......@@ -78,18 +78,42 @@ describe('EE - DastSavedScansList', () => {
});
describe('run scan', () => {
it('redirects to the running pipeline page on success', async () => {
const pipelineUrl = '/pipeline/url';
const successHandler = jest.fn().mockResolvedValue({
data: {
dastProfileRun: {
pipelineUrl,
errors: [],
},
},
});
it('puts the clicked button in the loading state and disabled other buttons', async () => {
createFullComponent({
propsData: { profiles: savedScans },
mocks: {
$apollo: {
mutate: jest.fn().mockResolvedValue({
dastProfileRun: {
pipelineUrl,
errors: [],
mutate: successHandler,
},
}),
},
});
const buttons = wrapper.findAll('[data-testid="dast-scan-run-button"]');
expect(buttons.at(0).props('loading')).toBe(false);
expect(buttons.at(1).props('disabled')).toBe(false);
await buttons.at(0).trigger('click');
expect(buttons.at(0).props('loading')).toBe(true);
expect(buttons.at(1).props('disabled')).toBe(true);
});
it('redirects to the running pipeline page on success', async () => {
createFullComponent({
propsData: { profiles: savedScans },
mocks: {
$apollo: {
mutate: successHandler,
},
},
});
......
......@@ -64,10 +64,17 @@ export const scannerProfiles = [
export const savedScans = [
{
id: 'gid://gitlab/DastScan/1',
id: 'gid://gitlab/DastProfile/1',
name: 'Scan 1',
dastSiteProfile: siteProfiles[0],
dastScannerProfile: scannerProfiles[0],
editPath: '/1/edit',
},
{
id: 'gid://gitlab/DastProfile/2',
name: 'Scan 2',
dastSiteProfile: siteProfiles[1],
dastScannerProfile: scannerProfiles[1],
editPath: '/2/edit',
},
];
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