Commit 7c885d0c authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '335962-add-a-locked-state-to-approval-checkbox' into 'master'

Add a locked state to approval settings checkbox

See merge request gitlab-org/gitlab!66450
parents b6eeb4a9 4be82295
<script>
import { GlFormCheckbox, GlIcon, GlLink } from '@gitlab/ui';
import { GlFormCheckbox, GlIcon, GlLink, GlPopover } from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper';
import { slugify } from '~/lib/utils/text_utility';
import { __ } from '~/locale';
import { APPROVALS_HELP_PATH } from '../constants';
......@@ -9,6 +10,7 @@ export default {
GlFormCheckbox,
GlIcon,
GlLink,
GlPopover,
},
props: {
label: {
......@@ -24,11 +26,24 @@ export default {
required: false,
default: false,
},
locked: {
type: Boolean,
required: false,
default: false,
},
lockedText: {
type: String,
required: false,
default: '',
},
},
computed: {
href() {
return helpPagePath(APPROVALS_HELP_PATH, { anchor: this.anchor });
},
lockIconId() {
return `approval-settings-checkbox-lock-icon-${slugify(this.label)}`;
},
},
methods: {
input(value) {
......@@ -37,15 +52,32 @@ export default {
},
i18n: {
helpLabel: __('Help'),
lockIconTitle: __('Setting enforced'),
},
};
</script>
<template>
<gl-form-checkbox :checked="value" @input="input">
<gl-form-checkbox :disabled="locked" :checked="value" @input="input">
{{ label }}
<template v-if="locked">
<gl-icon :id="lockIconId" data-testid="lock-icon" name="lock" />
<gl-popover
:target="lockIconId"
container="viewport"
placement="top"
:title="$options.i18n.lockIconTitle"
triggers="hover focus"
:content="lockedText"
/>
</template>
<gl-link :href="href" target="_blank">
<gl-icon name="question-o" :aria-label="$options.i18n.helpLabel" :size="16" />
<gl-icon
data-testid="help-icon"
name="question-o"
:aria-label="$options.i18n.helpLabel"
:size="16"
/>
</gl-link>
</gl-form-checkbox>
</template>
import { GlFormCheckbox, GlIcon, GlLink } from '@gitlab/ui';
import { GlFormCheckbox, GlIcon, GlLink, GlPopover } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import ApprovalSettingsCheckbox from 'ee/approvals/components/approval_settings_checkbox.vue';
import { APPROVALS_HELP_PATH } from 'ee/approvals/constants';
import { stubComponent } from 'helpers/stub_component';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { slugify } from '~/lib/utils/text_utility';
describe('ApprovalSettingsCheckbox', () => {
const label = 'Foo';
const anchor = 'bar-baz';
const lockIconId = `approval-settings-checkbox-lock-icon-${slugify(label)}`;
let wrapper;
const createWrapper = (props = {}) => {
wrapper = shallowMount(ApprovalSettingsCheckbox, {
propsData: { label, anchor, ...props },
stubs: {
GlFormCheckbox: stubComponent(GlFormCheckbox, {
props: ['checked'],
}),
GlIcon,
GlLink,
},
});
wrapper = extendedWrapper(
shallowMount(ApprovalSettingsCheckbox, {
propsData: { label, anchor, ...props },
stubs: {
GlFormCheckbox: stubComponent(GlFormCheckbox, {
props: ['checked'],
}),
GlIcon,
GlLink,
},
}),
);
};
const findCheckbox = () => wrapper.findComponent(GlFormCheckbox);
const findIcon = () => wrapper.findComponent(GlIcon);
const findLink = () => wrapper.findComponent(GlLink);
const findPopover = () => wrapper.findComponent(GlPopover);
const findLockIcon = () => wrapper.findByTestId('lock-icon');
const findHelpIcon = () => wrapper.findByTestId('help-icon');
afterEach(() => {
wrapper.destroy();
......@@ -45,8 +52,8 @@ describe('ApprovalSettingsCheckbox', () => {
expect(findLink().attributes('href')).toBe(`/help/${APPROVALS_HELP_PATH}#${anchor}`);
});
it('shows the icon', () => {
expect(findIcon().props('name')).toBe('question-o');
it('shows a help icon', () => {
expect(findHelpIcon().props('name')).toBe('question-o');
});
});
......@@ -71,4 +78,63 @@ describe('ApprovalSettingsCheckbox', () => {
expect(wrapper.emitted('input')[0]).toStrictEqual([true]);
});
});
describe('locked', () => {
describe('when the setting is not locked', () => {
beforeEach(() => {
createWrapper();
});
it('does not render a lock icon', () => {
expect(findLockIcon().exists()).toBe(false);
});
it('does not render a popover', () => {
expect(findPopover().exists()).toBe(false);
});
it('the input is enabled', () => {
expect(findCheckbox().attributes('disabled')).toBeUndefined();
});
});
describe('when the setting is locked', () => {
beforeEach(() => {
createWrapper({ locked: true });
});
it('disables the input', () => {
expect(findCheckbox().attributes('disabled')).toBe('disabled');
});
it('shows a lock icon', () => {
expect(findLockIcon().props('name')).toBe('lock');
expect(findLockIcon().attributes('id')).toBe(lockIconId);
});
it('shows a popover for the lock icon', () => {
expect(findPopover().props('target')).toBe(lockIconId);
});
it('configures how and when the popover should show', () => {
expect(findPopover().props()).toMatchObject({
title: 'Setting enforced',
triggers: 'hover focus',
placement: 'top',
container: 'viewport',
});
});
it('when lockedText is set, then the popover content matches the lockedText', () => {
const lockedText = 'Admin';
createWrapper({ locked: true, lockedText });
expect(findPopover().attributes('content')).toBe(lockedText);
});
it('when lockedText is not set, then the popover content is empty', () => {
expect(findPopover().attributes('content')).toBe('');
});
});
});
});
......@@ -29969,6 +29969,9 @@ msgstr ""
msgid "Setting"
msgstr ""
msgid "Setting enforced"
msgstr ""
msgid "Setting this to 0 means using the system default timeout value."
msgstr ""
......
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