Commit 5599a664 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '321974-improve-compliance-frameworks-form-ui-ux' into 'master'

Resolve "Improve compliance frameworks form UI/UX"

See merge request gitlab-org/gitlab!55592
parents ef05b87f 08363ffc
<script>
import * as Sentry from '@sentry/browser';
import { visitUrl } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
import { SAVE_ERROR } from '../constants';
import createComplianceFrameworkMutation from '../graphql/queries/create_compliance_framework.mutation.graphql';
import { initialiseFormData } from '../utils';
......@@ -41,6 +42,7 @@ export default {
},
methods: {
setError(error, userFriendlyText) {
this.saving = false;
this.errorMessage = userFriendlyText;
Sentry.captureException(error);
},
......@@ -70,16 +72,16 @@ export default {
if (error) {
this.setError(new Error(error), error);
} else {
this.saving = false;
visitUrl(this.groupEditPath);
}
} catch (e) {
this.setError(e, SAVE_ERROR);
}
this.saving = false;
},
},
i18n: {
submitButtonText: s__('ComplianceFrameworks|Add framework'),
},
};
</script>
<template>
......@@ -91,6 +93,7 @@ export default {
:description.sync="formData.description"
:pipeline-configuration-full-path.sync="formData.pipelineConfigurationFullPath"
:color.sync="formData.color"
:submit-button-text="$options.i18n.submitButtonText"
@submit="onSubmit"
/>
</form-status>
......
......@@ -2,6 +2,7 @@
import * as Sentry from '@sentry/browser';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { visitUrl } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import { FETCH_ERROR, SAVE_ERROR } from '../constants';
import getComplianceFrameworkQuery from '../graphql/queries/get_compliance_framework.query.graphql';
......@@ -104,6 +105,7 @@ export default {
Sentry.captureException(error);
},
setSavingError(error, userFriendlyText) {
this.saving = false;
this.saveErrorMessage = userFriendlyText;
Sentry.captureException(error);
},
......@@ -133,16 +135,16 @@ export default {
if (error) {
this.setSavingError(new Error(error), error);
} else {
this.saving = false;
visitUrl(this.groupEditPath);
}
} catch (e) {
this.setSavingError(e, SAVE_ERROR);
}
this.saving = false;
},
},
i18n: {
submitButtonText: __('Save changes'),
},
};
</script>
<template>
......@@ -155,6 +157,7 @@ export default {
:description.sync="formData.description"
:pipeline-configuration-full-path.sync="formData.pipelineConfigurationFullPath"
:color.sync="formData.color"
:submit-button-text="$options.i18n.submitButtonText"
@submit="onSubmit"
/>
</form-status>
......
......@@ -98,6 +98,9 @@ export default {
},
},
methods: {
dismissAlertMessage() {
this.message = null;
},
markForDeletion(framework) {
this.markedForDeletion = framework;
this.$refs.modal.show();
......@@ -140,6 +143,7 @@ export default {
class="gl-mt-5"
:variant="alertVariant"
:dismissible="alertDismissible"
@dismiss="dismissAlertMessage"
>
{{ alertMessage }}
</gl-alert>
......
......@@ -47,6 +47,10 @@ export default {
required: false,
default: null,
},
submitButtonText: {
type: String,
required: true,
},
},
data() {
return {
......@@ -141,7 +145,6 @@ export default {
'ComplianceFrameworks|Could not find this configuration location, please try a different location',
),
colorInputLabel: __('Background color'),
submitBtnText: __('Save changes'),
cancelBtnText: __('Cancel'),
},
};
......@@ -223,7 +226,7 @@ export default {
class="js-no-auto-disable"
data-testid="submit-btn"
:disabled="disableSubmitBtn"
>{{ $options.i18n.submitBtnText }}</gl-button
>{{ submitButtonText }}</gl-button
>
<gl-button :href="groupEditPath" data-testid="cancel-btn">{{
$options.i18n.cancelBtnText
......
......@@ -67,6 +67,16 @@ describe('CreateForm', () => {
wrapper.destroy();
});
describe('initialized', () => {
beforeEach(() => {
wrapper = createComponent();
});
it('sets the submit button text on the form', () => {
expect(findForm().props('submitButtonText')).toBe('Add framework');
});
});
describe('loading', () => {
beforeEach(() => {
wrapper = createComponent();
......@@ -120,13 +130,13 @@ describe('CreateForm', () => {
expect(captureExceptionSpy).toHaveBeenCalledWith(sentrySaveError);
});
it('saves inputted values and redirects', async () => {
it('saves inputted values, redirects and continues to show loading while redirecting', async () => {
wrapper = createComponent([[createComplianceFrameworkMutation, create]]);
await submitForm(name, description, pipelineConfigurationFullPath, color);
expect(create).toHaveBeenCalledWith(creationProps);
expect(findFormStatus().props('loading')).toBe(false);
expect(findFormStatus().props('loading')).toBe(true);
expect(visitUrl).toHaveBeenCalledWith(propsData.groupEditPath);
});
});
......
......@@ -104,6 +104,7 @@ describe('EditForm', () => {
name: frameworkFoundResponse.name,
pipelineConfigurationFullPath: frameworkFoundResponse.pipelineConfigurationFullPath,
pipelineConfigurationFullPathEnabled: true,
submitButtonText: 'Save changes',
});
expect(findForm().exists()).toBe(true);
});
......@@ -183,7 +184,7 @@ describe('EditForm', () => {
expect(Sentry.captureException.mock.calls[0][0]).toStrictEqual(sentrySaveError);
});
it('saves inputted values and redirects', async () => {
it('saves inputted values, redirects and continues to show loading while redirecting', async () => {
wrapper = createComponent([
[getComplianceFrameworkQuery, fetchOne],
[updateComplianceFrameworkMutation, update],
......@@ -192,7 +193,7 @@ describe('EditForm', () => {
await submitForm(name, description, pipelineConfigurationFullPath, color);
expect(update).toHaveBeenCalledWith(updateProps);
expect(findFormStatus().props('loading')).toBe(false);
expect(findFormStatus().props('loading')).toBe(true);
expect(visitUrl).toHaveBeenCalledWith(propsData.groupEditPath);
});
});
......
import { GlAlert, GlButton, GlLoadingIcon, GlTab, GlTabs } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import DeleteModal from 'ee/groups/settings/compliance_frameworks/components/delete_modal.vue';
......@@ -256,6 +257,14 @@ describe('List', () => {
expect(findAlert().props('variant')).toBe('info');
expect(findAlert().text()).toBe('Compliance framework deleted successfully');
});
it('can dismiss the alert message', async () => {
findAlert().vm.$emit('dismiss');
await nextTick();
expect(findAlert().exists()).toBe(false);
});
});
});
});
......
......@@ -10,7 +10,11 @@ import { GlFormGroup, GlFormInput } from '../stubs';
describe('SharedForm', () => {
let wrapper;
const defaultPropsData = { groupEditPath: 'group-1', pipelineConfigurationFullPathEnabled: true };
const defaultPropsData = {
groupEditPath: 'group-1',
pipelineConfigurationFullPathEnabled: true,
submitButtonText: 'Save changes',
};
const findForm = () => wrapper.findComponent(GlForm);
const findNameGroup = () => wrapper.find('[data-testid="name-input-group"]');
......@@ -65,6 +69,12 @@ describe('SharedForm', () => {
expect(findNameGroup().text()).toContain('Use :: to create a scoped set (eg. SOX::AWS)');
});
it('sets the submit button text from the property', () => {
wrapper = createComponent();
expect(findSubmitBtn().text()).toBe(defaultPropsData.submitButtonText);
});
it.each([true, false])(
'renders the pipeline configuration correctly when enabled is %s',
(enabled) => {
......
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