Commit bbefccfb authored by Angelo Gulina's avatar Angelo Gulina Committed by Enrique Alcántara

Migrate SSL toggle to GlToggle

This migrates the "Automatic certificate management using Let's Encrypt"
form to use GlToggle instead of a custom toggle implementation.
parent f1ec7d36
import setupToggleButtons from '~/toggle_buttons'; import { initToggle } from '~/toggles';
function updateVisibility(selector, isVisible) { function updateVisibility(selector, isVisible) {
Array.from(document.querySelectorAll(selector)).forEach((el) => { Array.from(document.querySelectorAll(selector)).forEach((el) => {
...@@ -11,12 +11,12 @@ function updateVisibility(selector, isVisible) { ...@@ -11,12 +11,12 @@ function updateVisibility(selector, isVisible) {
} }
export default () => { export default () => {
const toggleContainer = document.querySelector('.js-auto-ssl-toggle-container'); const sslToggle = initToggle(document.querySelector('.js-enable-ssl-gl-toggle'));
const sslToggleInput = document.querySelector('.js-project-feature-toggle-input');
if (toggleContainer) { if (sslToggle) {
const onToggleButtonClicked = (isAutoSslEnabled) => { sslToggle.$on('change', (isAutoSslEnabled) => {
updateVisibility('.js-shown-unless-auto-ssl', !isAutoSslEnabled); updateVisibility('.js-shown-unless-auto-ssl', !isAutoSslEnabled);
updateVisibility('.js-shown-if-auto-ssl', isAutoSslEnabled); updateVisibility('.js-shown-if-auto-ssl', isAutoSslEnabled);
Array.from(document.querySelectorAll('.js-enabled-unless-auto-ssl')).forEach((el) => { Array.from(document.querySelectorAll('.js-enabled-unless-auto-ssl')).forEach((el) => {
...@@ -26,8 +26,9 @@ export default () => { ...@@ -26,8 +26,9 @@ export default () => {
el.removeAttribute('disabled'); el.removeAttribute('disabled');
} }
}); });
};
setupToggleButtons(toggleContainer, onToggleButtonClicked); sslToggleInput.setAttribute('value', isAutoSslEnabled);
});
} }
return sslToggle;
}; };
...@@ -8,16 +8,12 @@ export const initToggle = (el) => { ...@@ -8,16 +8,12 @@ export const initToggle = (el) => {
return false; return false;
} }
const { const { name, id, isChecked, disabled, isLoading, label, help, labelPosition, ...dataset } =
name, el.dataset || {};
isChecked,
disabled, const dataAttrs = Object.fromEntries(
isLoading, Object.entries(dataset).map(([key, value]) => [`data-${kebabCase(key)}`, value]),
label, );
help,
labelPosition,
...dataset
} = el.dataset;
return new Vue({ return new Vue({
el, el,
...@@ -50,9 +46,7 @@ export const initToggle = (el) => { ...@@ -50,9 +46,7 @@ export const initToggle = (el) => {
labelPosition, labelPosition,
}, },
class: el.className, class: el.className,
attrs: Object.fromEntries( attrs: { id, ...dataAttrs },
Object.entries(dataset).map(([key, value]) => [`data-${kebabCase(key)}`, value]),
),
on: { on: {
change: (newValue) => { change: (newValue) => {
this.value = newValue; this.value = newValue;
......
...@@ -14,14 +14,14 @@ ...@@ -14,14 +14,14 @@
- lets_encrypt_link_start = "<a href=\"%{lets_encrypt_link_url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-nowrap\">".html_safe % { lets_encrypt_link_url: lets_encrypt_link_url } - lets_encrypt_link_start = "<a href=\"%{lets_encrypt_link_url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-nowrap\">".html_safe % { lets_encrypt_link_url: lets_encrypt_link_url }
- lets_encrypt_link_end = "</a>".html_safe - lets_encrypt_link_end = "</a>".html_safe
= _("Automatic certificate management using %{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end}").html_safe % { lets_encrypt_link_start: lets_encrypt_link_start, lets_encrypt_link_end: lets_encrypt_link_end } = _("Automatic certificate management using %{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end}").html_safe % { lets_encrypt_link_start: lets_encrypt_link_start, lets_encrypt_link_end: lets_encrypt_link_end }
%button{ type: "button", id: "pages_domain_auto_ssl_enabled_button", = render "shared/gl_toggle",
class: "js-project-feature-toggle project-feature-toggle mt-2 #{"is-checked" if auto_ssl_available_and_enabled}", id: "pages_domain_auto_ssl_enabled_button",
"aria-label": _("Automatic certificate management using Let's Encrypt") } is_checked: auto_ssl_available_and_enabled,
classes: "js-project-feature-toggle js-enable-ssl-gl-toggle mt-2",
label: _("Automatic certificate management using Let's Encrypt"),
label_position: 'hidden'
= f.hidden_field :auto_ssl_enabled?, class: "js-project-feature-toggle-input" = f.hidden_field :auto_ssl_enabled?, class: "js-project-feature-toggle-input"
%span.toggle-icon %p.gl-text-secondary.gl-mt-1
= sprite_icon("status_success_borderless", size: 18, css_class: "gl-text-blue-500 toggle-status-checked")
= sprite_icon("status_failed_borderless", size: 18, css_class: "gl-text-gray-400 toggle-status-unchecked")
%p.text-secondary.mt-3
- docs_link_url = help_page_path("user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md") - docs_link_url = help_page_path("user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md")
- docs_link_start = "<a href=\"%{docs_link_url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-nowrap\">".html_safe % { docs_link_url: docs_link_url } - docs_link_start = "<a href=\"%{docs_link_url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-nowrap\">".html_safe % { docs_link_url: docs_link_url }
- docs_link_end = "</a>".html_safe - docs_link_end = "</a>".html_safe
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
- classes = local_assigns.fetch(:classes) - classes = local_assigns.fetch(:classes)
- name = local_assigns.fetch(:name, nil) - name = local_assigns.fetch(:name, nil)
- id = local_assigns.fetch(:id, nil)
- is_checked = local_assigns.fetch(:is_checked, false).to_s - is_checked = local_assigns.fetch(:is_checked, false).to_s
- disabled = local_assigns.fetch(:disabled, false).to_s - disabled = local_assigns.fetch(:disabled, false).to_s
- is_loading = local_assigns.fetch(:is_loading, false).to_s - is_loading = local_assigns.fetch(:is_loading, false).to_s
...@@ -13,6 +14,7 @@ ...@@ -13,6 +14,7 @@
%span{ class: classes, %span{ class: classes,
data: { name: name, data: { name: name,
id: id,
is_checked: is_checked, is_checked: is_checked,
disabled: disabled, disabled: disabled,
is_loading: is_loading, is_loading: is_loading,
......
...@@ -95,7 +95,7 @@ RSpec.describe 'User adds pages domain', :js do ...@@ -95,7 +95,7 @@ RSpec.describe 'User adds pages domain', :js do
fill_in 'Domain', with: 'my.test.domain.com' fill_in 'Domain', with: 'my.test.domain.com'
find('.js-auto-ssl-toggle-container .project-feature-toggle').click find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click
fill_in 'Certificate (PEM)', with: certificate_pem fill_in 'Certificate (PEM)', with: certificate_pem
fill_in 'Key (PEM)', with: certificate_key fill_in 'Key (PEM)', with: certificate_key
......
...@@ -50,7 +50,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do ...@@ -50,7 +50,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do
expect(page).to have_selector '.card-header', text: 'Certificate' expect(page).to have_selector '.card-header', text: 'Certificate'
expect(page).to have_text domain.subject expect(page).to have_text domain.subject
find('.js-auto-ssl-toggle-container .project-feature-toggle').click find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click
expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'true' expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'true'
expect(page).not_to have_selector '.card-header', text: 'Certificate' expect(page).not_to have_selector '.card-header', text: 'Certificate'
...@@ -74,7 +74,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do ...@@ -74,7 +74,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do
expect(page).not_to have_field 'Certificate (PEM)', type: 'textarea' expect(page).not_to have_field 'Certificate (PEM)', type: 'textarea'
expect(page).not_to have_field 'Key (PEM)', type: 'textarea' expect(page).not_to have_field 'Key (PEM)', type: 'textarea'
find('.js-auto-ssl-toggle-container .project-feature-toggle').click find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click
expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'false' expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'false'
expect(page).to have_field 'Certificate (PEM)', type: 'textarea' expect(page).to have_field 'Certificate (PEM)', type: 'textarea'
......
import initForm from '~/pages/projects/pages_domains/form';
const ENABLED_UNLESS_AUTO_SSL_CLASS = 'js-enabled-unless-auto-ssl';
const SSL_TOGGLE_CLASS = 'js-enable-ssl-gl-toggle';
const SSL_TOGGLE_INPUT_CLASS = 'js-project-feature-toggle-input';
const SHOW_IF_AUTO_SSL_CLASS = 'js-shown-if-auto-ssl';
const SHOW_UNLESS_AUTO_SSL_CLASS = 'js-shown-unless-auto-ssl';
const D_NONE_CLASS = 'd-none';
describe('Page domains form', () => {
let toggle;
const findEnabledUnless = () => document.querySelector(`.${ENABLED_UNLESS_AUTO_SSL_CLASS}`);
const findSslToggle = () => document.querySelector(`.${SSL_TOGGLE_CLASS} button`);
const findSslToggleInput = () => document.querySelector(`.${SSL_TOGGLE_INPUT_CLASS}`);
const findIfAutoSsl = () => document.querySelector(`.${SHOW_IF_AUTO_SSL_CLASS}`);
const findUnlessAutoSsl = () => document.querySelector(`.${SHOW_UNLESS_AUTO_SSL_CLASS}`);
const create = () => {
setFixtures(`
<form>
<span
class="${SSL_TOGGLE_CLASS}"
data-label="SSL toggle"
></span>
<input class="${SSL_TOGGLE_INPUT_CLASS}" type="hidden" />
<span class="${SHOW_UNLESS_AUTO_SSL_CLASS}"></span>
<span class="${SHOW_IF_AUTO_SSL_CLASS}"></span>
<button class="${ENABLED_UNLESS_AUTO_SSL_CLASS}"></button>
</form>
`);
};
it('instantiates the toggle', () => {
create();
initForm();
expect(findSslToggle()).not.toBe(null);
});
describe('when auto SSL is enabled', () => {
beforeEach(() => {
create();
toggle = initForm();
toggle.$emit('change', true);
});
it('sets the correct classes', () => {
expect(Array.from(findIfAutoSsl().classList)).not.toContain(D_NONE_CLASS);
expect(Array.from(findUnlessAutoSsl().classList)).toContain(D_NONE_CLASS);
});
it('sets the correct disabled value', () => {
expect(findEnabledUnless().getAttribute('disabled')).toBe('disabled');
});
it('sets the correct value for the input', () => {
expect(findSslToggleInput().getAttribute('value')).toBe('true');
});
});
describe('when auto SSL is not enabled', () => {
beforeEach(() => {
create();
toggle = initForm();
toggle.$emit('change', false);
});
it('sets the correct classes', () => {
expect(Array.from(findIfAutoSsl().classList)).toContain(D_NONE_CLASS);
expect(Array.from(findUnlessAutoSsl().classList)).not.toContain(D_NONE_CLASS);
});
it('sets the correct disabled value', () => {
expect(findUnlessAutoSsl().getAttribute('disabled')).toBe(null);
});
it('sets the correct value for the input', () => {
expect(findSslToggleInput().getAttribute('value')).toBe('false');
});
});
});
...@@ -99,10 +99,12 @@ describe('toggles/index.js', () => { ...@@ -99,10 +99,12 @@ describe('toggles/index.js', () => {
const name = 'toggle-name'; const name = 'toggle-name';
const help = 'Help text'; const help = 'Help text';
const foo = 'bar'; const foo = 'bar';
const id = 'an-id';
beforeEach(() => { beforeEach(() => {
initToggleWithOptions({ initToggleWithOptions({
name, name,
id,
isChecked: true, isChecked: true,
disabled: true, disabled: true,
isLoading: true, isLoading: true,
...@@ -144,6 +146,10 @@ describe('toggles/index.js', () => { ...@@ -144,6 +146,10 @@ describe('toggles/index.js', () => {
it('passes custom dataset to the wrapper', () => { it('passes custom dataset to the wrapper', () => {
expect(toggleWrapper.dataset.foo).toBe('bar'); expect(toggleWrapper.dataset.foo).toBe('bar');
}); });
it('passes an id to the wrapper', () => {
expect(toggleWrapper.id).toBe(id);
});
}); });
}); });
}); });
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