Improve loading UX

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