Commit 3343c317 authored by Dheeraj Joshi's avatar Dheeraj Joshi

Persist feedback alert for SAST Configuration

This should not show feedback alert again upon
dismissible until local storage gets cleared.

Changelog: fixed
EE: true
parent 9433aa72
<script> <script>
import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui'; import { GlAlert } from '@gitlab/ui';
import { slugifyWithUnderscore } from '~/lib/utils/text_utility'; import { slugifyWithUnderscore } from '~/lib/utils/text_utility';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
export default { export default {
components: { components: {
GlAlert, GlAlert,
GlSprintf,
GlLink,
LocalStorageSync, LocalStorageSync,
}, },
props: { props: {
...@@ -15,10 +13,6 @@ export default { ...@@ -15,10 +13,6 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
feedbackLink: {
type: String,
required: true,
},
}, },
data() { data() {
return { return {
...@@ -44,19 +38,8 @@ export default { ...@@ -44,19 +38,8 @@ export default {
<template> <template>
<div v-show="showAlert"> <div v-show="showAlert">
<local-storage-sync v-model="isDismissed" :storage-key="storageKey" as-json /> <local-storage-sync v-model="isDismissed" :storage-key="storageKey" as-json />
<gl-alert v-if="showAlert" class="gl-mt-5" @dismiss="dismissFeedbackAlert"> <gl-alert v-if="showAlert" @dismiss="dismissFeedbackAlert">
<gl-sprintf <slot></slot>
:message="
__(
'Please share your feedback about %{featureName} %{linkStart}in this issue%{linkEnd} to help us improve the experience.',
)
"
>
<template #featureName>{{ featureName }}</template>
<template #link="{ content }">
<gl-link :href="feedbackLink" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</gl-alert> </gl-alert>
</div> </div>
</template> </template>
<script>
import { GlAlert } from '@gitlab/ui';
export default {
components: {
GlAlert,
},
data() {
return { isAlertDismissed: false };
},
computed: {
showPageAlert() {
return Boolean(this.$slots.alert) && !this.isAlertDismissed;
},
},
};
</script>
<template> <template>
<article> <article>
<gl-alert <slot name="alert"></slot>
v-if="showPageAlert"
data-testid="configuration-page-alert"
class="gl-mt-4"
@dismiss="isAlertDismissed = true"
>
<slot name="alert"></slot
></gl-alert>
<header class="gl-my-5 gl-border-b-1 gl-border-b-gray-100 gl-border-b-solid"> <header class="gl-my-5 gl-border-b-1 gl-border-b-gray-100 gl-border-b-solid">
<h4> <h4>
<slot name="heading"></slot> <slot name="heading"></slot>
...@@ -35,7 +9,6 @@ export default { ...@@ -35,7 +9,6 @@ export default {
<slot name="description"></slot> <slot name="description"></slot>
</p> </p>
</header> </header>
<slot></slot> <slot></slot>
</article> </article>
</template> </template>
<script> <script>
import { GlAlert, GlLink, GlLoadingIcon, GlSprintf } from '@gitlab/ui'; import { GlAlert, GlLink, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import DismissibleFeedbackAlert from '~/vue_shared/components/dismissible_feedback_alert.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import ConfigurationPageLayout from '../../components/configuration_page_layout.vue'; import ConfigurationPageLayout from '../../components/configuration_page_layout.vue';
import sastCiConfigurationQuery from '../graphql/sast_ci_configuration.query.graphql'; import sastCiConfigurationQuery from '../graphql/sast_ci_configuration.query.graphql';
...@@ -10,6 +11,7 @@ export default { ...@@ -10,6 +11,7 @@ export default {
components: { components: {
ConfigurationForm, ConfigurationForm,
ConfigurationPageLayout, ConfigurationPageLayout,
DismissibleFeedbackAlert,
GlAlert, GlAlert,
GlLink, GlLink,
GlLoadingIcon, GlLoadingIcon,
...@@ -80,11 +82,17 @@ export default { ...@@ -80,11 +82,17 @@ export default {
<template> <template>
<configuration-page-layout> <configuration-page-layout>
<template #alert> <template #alert>
<gl-sprintf :message="$options.i18n.feedbackAlertMessage"> <dismissible-feedback-alert
<template #link="{ content }"> feature-name="sast"
<gl-link :href="$options.feedbackIssue" target="_blank">{{ content }}</gl-link> class="gl-mt-4"
</template> data-testid="configuration-page-alert"
</gl-sprintf> >
<gl-sprintf :message="$options.i18n.feedbackAlertMessage">
<template #link="{ content }">
<gl-link :href="$options.feedbackIssue" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</dismissible-feedback-alert>
</template> </template>
<template #heading> {{ s__('SecurityConfiguration|SAST Configuration') }} </template> <template #heading> {{ s__('SecurityConfiguration|SAST Configuration') }} </template>
......
...@@ -2,21 +2,7 @@ ...@@ -2,21 +2,7 @@
exports[`Security Configuration Page Layout component matches the snapshot 1`] = ` exports[`Security Configuration Page Layout component matches the snapshot 1`] = `
<article> <article>
<gl-alert-stub Page alert
class="gl-mt-4"
data-testid="configuration-page-alert"
dismissible="true"
dismisslabel="Dismiss"
primarybuttonlink=""
primarybuttontext=""
secondarybuttonlink=""
secondarybuttontext=""
title=""
variant="info"
>
Page alert
</gl-alert-stub>
<header <header
class="gl-my-5 gl-border-b-1 gl-border-b-gray-100 gl-border-b-solid" class="gl-my-5 gl-border-b-1 gl-border-b-gray-100 gl-border-b-solid"
> >
......
...@@ -5,21 +5,17 @@ describe('Security Configuration Page Layout component', () => { ...@@ -5,21 +5,17 @@ describe('Security Configuration Page Layout component', () => {
let wrapper; let wrapper;
const createComponent = (options = {}) => { const createComponent = (options = {}) => {
const { slots = {} } = options;
wrapper = shallowMountExtended(ConfigurationPageLayout, { wrapper = shallowMountExtended(ConfigurationPageLayout, {
slots: { slots: {
alert: 'Page alert', alert: 'Page alert',
heading: 'Page title', heading: 'Page title',
description: 'Scanner description', description: 'Scanner description',
default: '<div>form</div>', default: '<div>form</div>',
...slots,
}, },
...options, ...options,
}); });
}; };
const findPageAlert = () => wrapper.findByTestId('configuration-page-alert');
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
}); });
...@@ -28,29 +24,4 @@ describe('Security Configuration Page Layout component', () => { ...@@ -28,29 +24,4 @@ describe('Security Configuration Page Layout component', () => {
createComponent(); createComponent();
expect(wrapper.element).toMatchSnapshot(); expect(wrapper.element).toMatchSnapshot();
}); });
describe('page level alert', () => {
it('should render correctly', () => {
createComponent();
expect(findPageAlert().exists()).toBe(true);
});
it('should be disabled when slot is not present', () => {
createComponent({
slots: {
alert: '',
},
});
expect(findPageAlert().exists()).toBe(false);
});
it('should be disabled after dismissal', async () => {
createComponent();
findPageAlert().vm.$emit('dismiss');
await wrapper.vm.$nextTick();
expect(findPageAlert().exists()).toBe(false);
});
});
}); });
...@@ -75,17 +75,6 @@ describe('SAST Configuration App', () => { ...@@ -75,17 +75,6 @@ describe('SAST Configuration App', () => {
target: '_blank', target: '_blank',
}); });
}); });
describe('when it is dismissed', () => {
beforeEach(() => {
findFeedbackAlert().vm.$emit('dismiss');
return wrapper.vm.$nextTick();
});
it('should not be displayed', () => {
expect(findFeedbackAlert().exists()).toBe(false);
});
});
}); });
describe('header', () => { describe('header', () => {
......
...@@ -25348,9 +25348,6 @@ msgstr "" ...@@ -25348,9 +25348,6 @@ msgstr ""
msgid "Please set a new password before proceeding." msgid "Please set a new password before proceeding."
msgstr "" msgstr ""
msgid "Please share your feedback about %{featureName} %{linkStart}in this issue%{linkEnd} to help us improve the experience."
msgstr ""
msgid "Please solve the captcha" msgid "Please solve the captcha"
msgstr "" msgstr ""
......
import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui'; import { GlAlert, GlSprintf } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils'; import { mount, shallowMount } from '@vue/test-utils';
import { useLocalStorageSpy } from 'helpers/local_storage_helper'; import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import Component from '~/vue_shared/components/dismissible_feedback_alert.vue'; import Component from '~/vue_shared/components/dismissible_feedback_alert.vue';
...@@ -8,20 +8,13 @@ describe('Dismissible Feedback Alert', () => { ...@@ -8,20 +8,13 @@ describe('Dismissible Feedback Alert', () => {
let wrapper; let wrapper;
const defaultProps = { const featureName = 'Dependency List';
featureName: 'Dependency List',
feedbackLink: 'https://gitlab.link',
};
const STORAGE_DISMISSAL_KEY = 'dependency_list_feedback_dismissed'; const STORAGE_DISMISSAL_KEY = 'dependency_list_feedback_dismissed';
const createComponent = ({ props, shallow } = {}) => { const createComponent = ({ mountFn = shallowMount } = {}) => {
const mountFn = shallow ? shallowMount : mount;
wrapper = mountFn(Component, { wrapper = mountFn(Component, {
propsData: { propsData: {
...defaultProps, featureName,
...props,
}, },
stubs: { stubs: {
GlSprintf, GlSprintf,
...@@ -34,8 +27,8 @@ describe('Dismissible Feedback Alert', () => { ...@@ -34,8 +27,8 @@ describe('Dismissible Feedback Alert', () => {
wrapper = null; wrapper = null;
}); });
const findAlert = () => wrapper.find(GlAlert); const createFullComponent = () => createComponent({ mountFn: mount });
const findLink = () => wrapper.find(GlLink); const findAlert = () => wrapper.findComponent(GlAlert);
describe('with default', () => { describe('with default', () => {
beforeEach(() => { beforeEach(() => {
...@@ -46,17 +39,6 @@ describe('Dismissible Feedback Alert', () => { ...@@ -46,17 +39,6 @@ describe('Dismissible Feedback Alert', () => {
expect(findAlert().exists()).toBe(true); expect(findAlert().exists()).toBe(true);
}); });
it('contains feature name', () => {
expect(findAlert().text()).toContain(defaultProps.featureName);
});
it('contains provided link', () => {
const link = findLink();
expect(link.attributes('href')).toBe(defaultProps.feedbackLink);
expect(link.attributes('target')).toBe('_blank');
});
it('should have the storage key set', () => { it('should have the storage key set', () => {
expect(wrapper.vm.storageKey).toBe(STORAGE_DISMISSAL_KEY); expect(wrapper.vm.storageKey).toBe(STORAGE_DISMISSAL_KEY);
}); });
...@@ -65,7 +47,7 @@ describe('Dismissible Feedback Alert', () => { ...@@ -65,7 +47,7 @@ describe('Dismissible Feedback Alert', () => {
describe('dismissible', () => { describe('dismissible', () => {
describe('after dismissal', () => { describe('after dismissal', () => {
beforeEach(() => { beforeEach(() => {
createComponent({ shallow: false }); createFullComponent();
findAlert().vm.$emit('dismiss'); findAlert().vm.$emit('dismiss');
}); });
...@@ -81,7 +63,7 @@ describe('Dismissible Feedback Alert', () => { ...@@ -81,7 +63,7 @@ describe('Dismissible Feedback Alert', () => {
describe('already dismissed', () => { describe('already dismissed', () => {
it('should not show the alert once dismissed', async () => { it('should not show the alert once dismissed', async () => {
localStorage.setItem(STORAGE_DISMISSAL_KEY, 'true'); localStorage.setItem(STORAGE_DISMISSAL_KEY, 'true');
createComponent({ shallow: false }); createFullComponent();
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(findAlert().exists()).toBe(false); expect(findAlert().exists()).toBe(false);
......
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