Commit a14e0ccf authored by peterhegman's avatar peterhegman

Add GitLab UI form builder and custom checkbox method

Makes it so we can easily add GitLab UI styled checkboxes in HAML
parent a44023b1
......@@ -413,6 +413,12 @@ module ApplicationHelper
end
end
def gitlab_ui_form_for(record, *args, &block)
options = args.extract_options!
form_for(record, *(args << options.merge({ builder: ::Gitlab::FormBuilders::GitlabUiFormBuilder })), &block)
end
private
def appearance
......
= form_for @group, html: { multipart: true, class: 'gl-show-field-errors js-general-permissions-form' }, authenticity_token: true do |f|
= gitlab_ui_form_for @group, html: { multipart: true, class: 'gl-show-field-errors js-general-permissions-form' }, authenticity_token: true do |f|
%input{ type: 'hidden', name: 'update_section', value: 'js-permissions-settings' }
= form_errors(@group)
......@@ -9,12 +9,10 @@
- if @group.root?
.form-group.gl-mb-3
.gl-form-checkbox.custom-control.custom-checkbox
= f.check_box :prevent_sharing_groups_outside_hierarchy, disabled: !can_change_prevent_sharing_groups_outside_hierarchy?(@group), class: 'custom-control-input'
= f.label :prevent_sharing_groups_outside_hierarchy, class: 'custom-control-label' do
%span
= s_('GroupSettings|Prevent members from sending invitations to groups outside of %{group} and its subgroups.').html_safe % { group: link_to_group(@group) }
%p.js-descr.help-text= prevent_sharing_groups_outside_hierarchy_help_text(@group)
= f.gitlab_ui_checkbox_component :prevent_sharing_groups_outside_hierarchy,
s_('GroupSettings|Prevent members from sending invitations to groups outside of %{group} and its subgroups.').html_safe % { group: link_to_group(@group) },
help_text: prevent_sharing_groups_outside_hierarchy_help_text(@group),
checkbox_options: { disabled: !can_change_prevent_sharing_groups_outside_hierarchy?(@group) }
.form-group.gl-mb-3
.gl-form-checkbox.custom-control.custom-checkbox
......
# frozen_string_literal: true
module Gitlab
module FormBuilders
class GitlabUiFormBuilder < ActionView::Helpers::FormBuilder
def gitlab_ui_checkbox_component(method, label, help_text: nil, checkbox_options: {}, label_options: {})
@template.content_tag(
:div,
class: 'gl-form-checkbox custom-control custom-checkbox'
) do
@template.check_box(
@object_name, method, format_options(checkbox_options, ['custom-control-input'])
) +
@template.label(
@object_name, method, format_options(label_options, ['custom-control-label'])
) do
if help_text
@template.content_tag(
:span,
label
) +
@template.content_tag(
:p,
help_text,
class: 'help-text'
)
else
label
end
end
end
end
private
def format_options(options, classes)
classes << options[:class]
objectify_options(options.merge({ class: classes.flatten.compact }))
end
end
end
end
......@@ -472,4 +472,23 @@ RSpec.describe ApplicationHelper do
allow(helper.controller).to receive(method_name).and_return(value)
end
end
describe '#gitlab_ui_form_for' do
let_it_be(:user) { build(:user) }
before do
allow(helper).to receive(:users_path).and_return('/root')
allow(helper).to receive(:form_for).and_call_original
end
it 'adds custom form builder to options and calls `form_for`' do
options = { html: { class: 'foo-bar' } }
expected_options = options.merge({ builder: ::Gitlab::FormBuilders::GitlabUiFormBuilder, url: '/root' })
expect do |b|
helper.gitlab_ui_form_for(user, options, &b)
end.to yield_with_args(::Gitlab::FormBuilders::GitlabUiFormBuilder)
expect(helper).to have_received(:form_for).with(user, expected_options)
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::FormBuilders::GitlabUiFormBuilder do
let_it_be(:user) { build(:user) }
let_it_be(:fake_template) do
Object.new.tap do |template|
template.extend ActionView::Helpers::FormHelper
template.extend ActionView::Helpers::FormOptionsHelper
template.extend ActionView::Helpers::TagHelper
template.extend ActionView::Context
end
end
let_it_be(:form_builder) { described_class.new(:user, user, fake_template, {}) }
describe '#gitlab_ui_checkbox_component' do
let(:optional_args) { {} }
subject(:checkbox_html) { form_builder.gitlab_ui_checkbox_component(:view_diffs_file_by_file, "Show one file at a time on merge request's Changes tab", **optional_args) }
context 'without optional arguments' do
it 'renders correct html' do
expected_html = <<~EOS
<div class="gl-form-checkbox custom-control custom-checkbox">
<input name="user[view_diffs_file_by_file]" type="hidden" value="0" />
<input class="custom-control-input" type="checkbox" value="1" name="user[view_diffs_file_by_file]" id="user_view_diffs_file_by_file" />
<label class="custom-control-label" for="user_view_diffs_file_by_file">
Show one file at a time on merge request&#39;s Changes tab
</label>
</div>
EOS
expect(checkbox_html).to eq(html_strip_whitespace(expected_html))
end
end
context 'with optional arguments' do
let(:optional_args) do
{
help_text: 'Instead of all the files changed, show only one file at a time.',
checkbox_options: { class: 'checkbox-foo-bar' },
label_options: { class: 'label-foo-bar' }
}
end
it 'renders help text' do
expected_html = <<~EOS
<div class="gl-form-checkbox custom-control custom-checkbox">
<input name="user[view_diffs_file_by_file]" type="hidden" value="0" />
<input class="custom-control-input checkbox-foo-bar" type="checkbox" value="1" name="user[view_diffs_file_by_file]" id="user_view_diffs_file_by_file" />
<label class="custom-control-label label-foo-bar" for="user_view_diffs_file_by_file">
<span>Show one file at a time on merge request&#39;s Changes tab</span>
<p class="help-text">Instead of all the files changed, show only one file at a time.</p>
</label>
</div>
EOS
expect(checkbox_html).to eq(html_strip_whitespace(expected_html))
end
end
end
private
def html_strip_whitespace(html)
html.lines.map(&:strip).join('')
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