Commit c3581b0c authored by Alex Buijs's avatar Alex Buijs

Replace visibility level options by dropdown

Add a Vue component for visibility level options
parent 5b86fa32
/* eslint-disable no-new */
import mountProgressBar from 'ee/registrations/groups/new';
import mountComponents from 'ee/registrations/groups/new';
import GroupPathValidator from '~/pages/groups/new/group_path_validator';
import BindInOut from '~/behaviors/bind_in_out';
import Group from '~/group';
document.addEventListener('DOMContentLoaded', () => {
mountProgressBar();
mountComponents();
new GroupPathValidator();
BindInOut.initAll();
new Group();
......
<script>
import { GlNewDropdown, GlNewDropdownItem } from '@gitlab/ui';
export default {
components: {
GlNewDropdown,
GlNewDropdownItem,
},
props: {
visibilityLevelOptions: {
type: Array,
required: true,
},
defaultLevel: {
type: Number,
required: true,
},
},
data() {
return {
selectedOption: this.getDefaultOption(),
};
},
methods: {
getDefaultOption() {
return this.visibilityLevelOptions.find(option => option.level === this.defaultLevel);
},
onClick(option) {
this.selectedOption = option;
},
},
};
</script>
<template>
<div>
<input type="hidden" name="group[visibility_level]" :value="selectedOption.level" />
<gl-new-dropdown :text="selectedOption.label" class="gl-w-full" menu-class="gl-w-full! gl-mb-0">
<gl-new-dropdown-item
v-for="option in visibilityLevelOptions"
:key="option.level"
:secondary-text="option.description"
@click="onClick(option)"
>
<div class="gl-font-weight-bold gl-mb-1">{{ option.label }}</div>
</gl-new-dropdown-item>
</gl-new-dropdown>
</div>
</template>
import Vue from 'vue';
import { STEPS, ONBOARDING_ISSUES_EXPERIMENT_FLOW_STEPS } from '../../constants';
import ProgressBar from '../../components/progress_bar.vue';
import VisibilityLevelDropdown from '../../components/visibility_level_dropdown.vue';
export default () => {
function mountProgressBar() {
const el = document.getElementById('progress-bar');
if (!el) return null;
......@@ -15,4 +16,27 @@ export default () => {
});
},
});
}
function mountVisibilityLevelDropdown() {
const el = document.querySelector('.js-visibility-level-dropdown');
if (!el) return null;
return new Vue({
el,
render(createElement) {
return createElement(VisibilityLevelDropdown, {
props: {
visibilityLevelOptions: JSON.parse(el.dataset.visibilityLevelOptions),
defaultLevel: Number(el.dataset.defaultLevel),
},
});
},
});
}
export default () => {
mountProgressBar();
mountVisibilityLevelDropdown();
};
......@@ -8,7 +8,7 @@ module Registrations
before_action :check_experiment_enabled
def new
@group = Group.new
@group = Group.new(visibility_level: helpers.default_group_visibility)
end
def create
......
......@@ -30,6 +30,16 @@ module EE
end
end
def visibility_level_options
available_visibility_levels(@group).map do |level|
{
level: level,
label: visibility_level_label(level),
description: visibility_level_description(level, @group)
}
end
end
private
def redirect_path
......
......@@ -41,7 +41,7 @@
.form-group.col-sm-12
= f.label :visibility_level, class: 'label-bold' do
= _('Visibility level')
= render 'shared/visibility_level', f: f, visibility_level: default_group_visibility, can_change_visibility_level: true, form_model: @group, with_label: false
.js-visibility-level-dropdown{ data: { visibility_level_options: visibility_level_options.to_json, default_level: f.object.visibility_level } }
.row
.form-group.col-sm-12.mb-0
= button_tag class: %w[btn btn-success w-100] do
......
......@@ -22,6 +22,13 @@ RSpec.describe Registrations::GroupsController do
it { is_expected.to have_gitlab_http_status(:ok) }
it { is_expected.to render_template(:new) }
it 'assigns the group variable to a new Group with the default group visibility' do
subject
expect(assigns(:group)).to be_a_new(Group)
expect(assigns(:group).visibility_level).to eq(Gitlab::CurrentSettings.default_group_visibility)
end
context 'user without the ability to create a group' do
let(:user) { create(:user, can_create_group: false) }
......
import { shallowMount } from '@vue/test-utils';
import { GlNewDropdown, GlNewDropdownItem } from '@gitlab/ui';
import Component from 'ee/registrations/components/visibility_level_dropdown.vue';
describe('Visibility Level Dropdown', () => {
let wrapper;
const options = [
{ level: 0, label: 'Private', description: 'Private description' },
{ level: 20, label: 'Public', description: 'Public description' },
];
const defaultLevel = 0;
const createComponent = propsData => {
wrapper = shallowMount(Component, {
propsData,
});
};
beforeEach(() => {
createComponent({
visibilityLevelOptions: options,
defaultLevel,
});
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const hiddenInputValue = () =>
wrapper.find("input[name='group[visibility_level]']").attributes('value');
const dropdownText = () => wrapper.find(GlNewDropdown).props('text');
const findDropdownItems = () =>
wrapper.findAll(GlNewDropdownItem).wrappers.map(option => ({
text: option.text(),
secondaryText: option.props('secondaryText'),
}));
describe('Default values', () => {
it('sets the value of the hidden input to the default value', () => {
expect(hiddenInputValue()).toBe(options[0].level.toString());
});
it('sets the text of the dropdown to the default value', () => {
expect(dropdownText()).toBe(options[0].label);
});
it('shows all dropdown options', () => {
expect(findDropdownItems()).toEqual(
options.map(({ label, description }) => ({ text: label, secondaryText: description })),
);
});
});
describe('Selecting an option', () => {
beforeEach(() => {
wrapper
.findAll(GlNewDropdownItem)
.at(1)
.vm.$emit('click');
});
it('sets the value of the hidden input to the selected value', () => {
expect(hiddenInputValue()).toBe(options[1].level.toString());
});
it('sets the text of the dropdown to the selected value', () => {
expect(dropdownText()).toBe(options[1].label);
});
});
});
......@@ -69,4 +69,21 @@ RSpec.describe EE::RegistrationsHelper do
end
end
end
describe '#visibility_level_options' do
let(:user) { build(:user) }
before do
allow(helper).to receive(:current_user).and_return(user)
assign(:group, Group.new)
end
it 'returns the desired mapping' do
expect(helper.visibility_level_options).to eq [
{ level: 0, label: 'Private', description: 'The group and its projects can only be viewed by members.' },
{ level: 10, label: 'Internal', description: 'The group and any internal projects can be viewed by any logged in user.' },
{ level: 20, label: 'Public', description: 'The group and any public projects can be viewed without any authentication.' }
]
end
end
end
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