Commit 90443026 authored by garybell's avatar garybell Committed by Alexander Turinske

Implement new alert in callout

- Remove callout usage from jobs
- Change first alert to be non-dismissable
- Change the second alert to us gl-alert
- Remove callout vue file and assocated spec
- Add changelog to go alongside the rest of the changes
- Update the spec to check for the right message
- Update the spec for feature flags
parent ae1f26ee
......@@ -9,10 +9,10 @@ import {
GlSprintf,
GlLink,
GlIcon,
GlAlert,
} from '@gitlab/ui';
import { s__, __ } from '~/locale';
import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
import Callout from '~/vue_shared/components/callout.vue';
export default {
components: {
......@@ -22,10 +22,10 @@ export default {
GlModal,
ModalCopyButton,
GlIcon,
Callout,
GlLoadingIcon,
GlSprintf,
GlLink,
GlAlert,
},
directives: {
......@@ -153,8 +153,7 @@ export default {
</template>
</gl-sprintf>
</p>
<callout category="warning">
<gl-alert variant="warning" class="gl-mb-5" :dismissible="false">
<gl-sprintf
:message="
s__(
......@@ -168,7 +167,7 @@ export default {
}}</gl-link>
</template>
</gl-sprintf>
</callout>
</gl-alert>
<gl-form-group :label="$options.translations.apiUrlLabelText" label-for="api-url">
<gl-form-input-group id="api-url" :value="unleashApiUrl" readonly type="text" name="api-url">
<template #append>
......@@ -212,11 +211,9 @@ export default {
<gl-icon name="warning" class="gl-mr-2" />
<span>{{ $options.translations.instanceIdRegenerateError }}</span>
</div>
<callout
v-if="canUserRotateToken"
category="danger"
:message="$options.translations.instanceIdRegenerateText"
/>
<gl-alert v-if="canUserRotateToken" variant="danger" class="gl-mb-5" :dismissible="false">
{{ $options.translations.instanceIdRegenerateText }}
</gl-alert>
<p v-if="canUserRotateToken" data-testid="prevent-accident-text">
<gl-sprintf
:message="
......
<script>
import { throttle, isEmpty } from 'lodash';
import { mapGetters, mapState, mapActions } from 'vuex';
import { GlLoadingIcon, GlIcon, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
import { GlLoadingIcon, GlIcon, GlSafeHtmlDirective as SafeHtml, GlAlert } from '@gitlab/ui';
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import { isScrolledToBottom } from '~/lib/utils/scroll_utils';
import { polyfillSticky } from '~/lib/utils/sticky';
import CiHeader from '~/vue_shared/components/header_ci_component.vue';
import Callout from '~/vue_shared/components/callout.vue';
import EmptyState from './empty_state.vue';
import EnvironmentsBlock from './environments_block.vue';
import ErasedBlock from './erased_block.vue';
......@@ -22,7 +21,6 @@ export default {
name: 'JobPageApp',
components: {
CiHeader,
Callout,
EmptyState,
EnvironmentsBlock,
ErasedBlock,
......@@ -34,6 +32,7 @@ export default {
Sidebar,
GlLoadingIcon,
SharedRunner: () => import('ee_component/jobs/components/shared_runner_limit_block.vue'),
GlAlert,
},
directives: {
SafeHtml,
......@@ -223,10 +222,14 @@ export default {
@clickedSidebarButton="toggleSidebar"
/>
</div>
<callout v-if="shouldRenderHeaderCallout">
<gl-alert
v-if="shouldRenderHeaderCallout"
variant="danger"
class="gl-mt-3"
:dismissible="false"
>
<div v-safe-html="job.callout_message"></div>
</callout>
</gl-alert>
</header>
<!-- EO Header Section -->
......
<script>
const calloutVariants = ['danger', 'success', 'info', 'warning'];
export default {
props: {
category: {
type: String,
required: false,
default: calloutVariants[0],
validator: value => calloutVariants.includes(value),
},
message: {
type: String,
required: false,
default: '',
},
},
};
</script>
<template>
<div :class="`bs-callout bs-callout-${category}`" role="alert" aria-live="assertive">
{{ message }} <slot></slot>
</div>
</template>
---
title: Migrate bs-callout to GlAlert for components using app/assets/javascripts/vue_shared/components/callout.vue
merge_request: 49732
author: Gary Bell @garybell
type: other
import { shallowMount } from '@vue/test-utils';
import { GlModal, GlSprintf } from '@gitlab/ui';
import { GlModal, GlSprintf, GlAlert } from '@gitlab/ui';
import Component from '~/feature_flags/components/configure_feature_flags_modal.vue';
import Callout from '~/vue_shared/components/callout.vue';
describe('Configure Feature Flags Modal', () => {
const mockEvent = { preventDefault: jest.fn() };
......@@ -36,8 +35,8 @@ describe('Configure Feature Flags Modal', () => {
const findGlModal = () => wrapper.find(GlModal);
const findPrimaryAction = () => findGlModal().props('actionPrimary');
const findProjectNameInput = () => wrapper.find('#project_name_verification');
const findDangerCallout = () =>
wrapper.findAll(Callout).filter(c => c.props('category') === 'danger');
const findDangerGlAlert = () =>
wrapper.findAll(GlAlert).filter(c => c.props('variant') === 'danger');
describe('idle', () => {
afterEach(() => wrapper.destroy());
......@@ -86,10 +85,10 @@ describe('Configure Feature Flags Modal', () => {
);
});
it('should display one and only one danger callout', () => {
const dangerCallout = findDangerCallout();
expect(dangerCallout.length).toBe(1);
expect(dangerCallout.at(0).props('message')).toMatch(/Regenerating the instance ID/);
it('should display one and only one danger alert', () => {
const dangerGlAlert = findDangerGlAlert();
expect(dangerGlAlert.length).toBe(1);
expect(dangerGlAlert.at(0).text()).toMatch(/Regenerating the instance ID/);
});
it('should display a message asking to fill the project name', () => {
......@@ -130,7 +129,7 @@ describe('Configure Feature Flags Modal', () => {
});
it('should not display regenerating instance ID', async () => {
expect(findDangerCallout().exists()).toBe(false);
expect(findDangerGlAlert().exists()).toBe(false);
});
it('should disable the project name input', async () => {
......
import { shallowMount } from '@vue/test-utils';
import Callout from '~/vue_shared/components/callout.vue';
const TEST_MESSAGE = 'This is a callout message!';
const TEST_SLOT = '<button>This is a callout slot!</button>';
describe('Callout Component', () => {
let wrapper;
const factory = options => {
wrapper = shallowMount(Callout, {
...options,
});
};
afterEach(() => {
wrapper.destroy();
});
it('should render the appropriate variant of callout', () => {
factory({
propsData: {
category: 'info',
message: TEST_MESSAGE,
},
});
expect(wrapper.classes()).toEqual(['bs-callout', 'bs-callout-info']);
expect(wrapper.element.tagName).toEqual('DIV');
});
it('should render accessibility attributes', () => {
factory({
propsData: {
message: TEST_MESSAGE,
},
});
expect(wrapper.attributes('role')).toEqual('alert');
expect(wrapper.attributes('aria-live')).toEqual('assertive');
});
it('should render the provided message', () => {
factory({
propsData: {
message: TEST_MESSAGE,
},
});
expect(wrapper.element.innerHTML.trim()).toEqual(TEST_MESSAGE);
});
it('should render the provided slot', () => {
factory({
slots: {
default: TEST_SLOT,
},
});
expect(wrapper.element.innerHTML.trim()).toEqual(TEST_SLOT);
});
});
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