Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-03-05 18:17:54 +00:00
parent 856f7ae4d1
commit 01979f1e76
11 changed files with 19 additions and 271 deletions

View file

@ -3,7 +3,6 @@ import SecretValues from '../behaviors/secret_values';
import CreateItemDropdown from '../create_item_dropdown';
import { parseBoolean } from '../lib/utils/common_utils';
import { s__ } from '../locale';
import setupToggleButtons from '../toggle_buttons';
const ALL_ENVIRONMENTS_STRING = s__('CiVariable|All environments');
@ -115,8 +114,6 @@ export default class VariableList {
initRow(rowEl) {
const $row = $(rowEl);
setupToggleButtons($row[0]);
// Reset the resizable textarea
$row.find(this.inputMap.secret_value.selector).css('height', '');

View file

@ -1,63 +0,0 @@
import $ from 'jquery';
import createFlash from './flash';
import { parseBoolean } from './lib/utils/common_utils';
import { __ } from './locale';
/*
example HAML:
```
%button.js-project-feature-toggle.project-feature-toggle{ type: "button",
class: "#{'is-checked' if enabled?}",
'aria-label': _('Toggle Kubernetes Cluster') }
%input{ type: "hidden", class: 'js-project-feature-toggle-input', value: enabled? }
```
*/
function updateToggle(toggle, isOn) {
toggle.classList.toggle('is-checked', isOn);
}
function onToggleClicked(toggle, input, clickCallback) {
const previousIsOn = parseBoolean(input.value);
// Visually change the toggle and start loading
updateToggle(toggle, !previousIsOn);
toggle.setAttribute('disabled', true);
toggle.classList.toggle('is-loading', true);
Promise.resolve(clickCallback(!previousIsOn, toggle))
.then(() => {
// Actually change the input value
input.setAttribute('value', !previousIsOn);
})
.catch(() => {
// Revert the visuals if something goes wrong
updateToggle(toggle, previousIsOn);
})
.then(() => {
// Remove the loading indicator in any case
toggle.removeAttribute('disabled');
toggle.classList.toggle('is-loading', false);
$(input).trigger('trigger-change');
})
.catch(() => {
createFlash({
message: __('Something went wrong when toggling the button'),
});
});
}
export default function setupToggleButtons(container, clickCallback = () => {}) {
const toggles = container.querySelectorAll('.js-project-feature-toggle');
toggles.forEach((toggle) => {
const input = toggle.querySelector('.js-project-feature-toggle-input');
const isOn = parseBoolean(input.value);
// Get the visible toggle in sync with the hidden input
updateToggle(toggle, isOn);
toggle.addEventListener('click', onToggleClicked.bind(null, toggle, input, clickCallback));
});
}

View file

@ -1,23 +1,16 @@
- form_field = local_assigns.fetch(:form_field, nil)
- variable = local_assigns.fetch(:variable, nil)
- only_key_value = local_assigns.fetch(:only_key_value, false)
- id = variable&.id
- variable_type = variable&.variable_type
- key = variable&.key
- value = variable&.value
- is_protected_default = ci_variable_protected_by_default?
- is_protected = ci_variable_protected?(variable, only_key_value)
- is_masked_default = false
- is_masked = ci_variable_masked?(variable, only_key_value)
- id_input_name = "#{form_field}[variables_attributes][][id]"
- destroy_input_name = "#{form_field}[variables_attributes][][_destroy]"
- variable_type_input_name = "#{form_field}[variables_attributes][][variable_type]"
- key_input_name = "#{form_field}[variables_attributes][][key]"
- value_input_name = "#{form_field}[variables_attributes][][secret_value]"
- protected_input_name = "#{form_field}[variables_attributes][][protected]"
- masked_input_name = "#{form_field}[variables_attributes][][masked]"
%li.js-row.ci-variable-row{ data: { is_persisted: "#{!id.nil?}" } }
.ci-variable-row-body.border-bottom
@ -40,25 +33,5 @@
%p.masking-validation-error.gl-field-error.hide
= s_("CiVariables|Cannot use Masked Variable with current value")
= link_to sprite_icon('question-o'), help_page_path('ci/variables/index', anchor: 'mask-a-cicd-variable'), target: '_blank', rel: 'noopener noreferrer'
- unless only_key_value
.ci-variable-body-item.ci-variable-protected-item.table-section.section-20.mr-0.border-top-0
.gl-mr-3
= s_("CiVariable|Protected")
= render "shared/buttons/project_feature_toggle", is_checked: is_protected, label: s_("CiVariable|Toggle protected") do
%input{ type: "hidden",
class: 'js-ci-variable-input-protected js-project-feature-toggle-input',
name: protected_input_name,
value: is_protected,
data: { default: is_protected_default.to_s } }
.ci-variable-body-item.ci-variable-masked-item.table-section.section-20.mr-0.border-top-0
.gl-mr-3
= s_("CiVariable|Masked")
= render "shared/buttons/project_feature_toggle", is_checked: is_masked, label: s_("CiVariable|Toggle masked"), class_list: "js-project-feature-toggle project-feature-toggle qa-variable-masked" do
%input{ type: "hidden",
class: 'js-ci-variable-input-masked js-project-feature-toggle-input',
name: masked_input_name,
value: is_masked,
data: { default: is_masked_default.to_s } }
= render_if_exists 'ci/variables/environment_scope', form_field: form_field, variable: variable
%button.gl-button.btn.btn-default.btn-icon.js-row-remove-button.ci-variable-row-remove-button.table-section{ type: 'button', 'aria-label': s_('CiVariables|Remove variable row') }
= sprite_icon('close')

View file

@ -25,8 +25,8 @@
#{ s_('PipelineSchedules|Variables') }
%ul.ci-variable-list
- @schedule.variables.each do |variable|
= render 'ci/variables/variable_row', form_field: 'schedule', variable: variable, only_key_value: true
= render 'ci/variables/variable_row', form_field: 'schedule', only_key_value: true
= render 'ci/variables/variable_row', form_field: 'schedule', variable: variable
= render 'ci/variables/variable_row', form_field: 'schedule'
- if @schedule.variables.size > 0
%button.gl-button.btn.btn-confirm-secondary.gl-mt-3.js-secret-value-reveal-button{ type: 'button', data: { secret_reveal_status: "#{@schedule.variables.size == 0}" } }
- if @schedule.variables.size == 0

View file

@ -1,16 +0,0 @@
- class_list ||= "js-project-feature-toggle project-feature-toggle"
- data ||= nil
- disabled ||= false
- is_checked ||= false
- label ||= nil
%button{ type: 'button',
class: "#{class_list} #{'is-disabled' if disabled} #{'is-checked' if is_checked}",
"aria-label": label,
disabled: disabled,
data: data }
- if yield.present?
= yield
%span.toggle-icon
= 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')

View file

@ -7393,24 +7393,12 @@ msgstr ""
msgid "CiVariable|Create wildcard"
msgstr ""
msgid "CiVariable|Masked"
msgstr ""
msgid "CiVariable|New environment"
msgstr ""
msgid "CiVariable|Protected"
msgstr ""
msgid "CiVariable|Search environments"
msgstr ""
msgid "CiVariable|Toggle masked"
msgstr ""
msgid "CiVariable|Toggle protected"
msgstr ""
msgid "Classification Label (optional)"
msgstr ""
@ -34373,9 +34361,6 @@ msgstr ""
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
msgid "Something went wrong when toggling the button"
msgstr ""
msgid "Something went wrong while adding your award. Please try again."
msgstr ""

View file

@ -94,16 +94,7 @@ RSpec.describe 'User Cluster', :js do
expect(page).to have_button('Save changes')
end
context 'when user disables the cluster' do
before do
page.find(:css, '.js-cluster-enable-toggle-area .js-project-feature-toggle').click
page.within('.js-cluster-details-form') { click_button 'Save changes' }
end
it 'user sees the successful message' do
expect(page).to have_content('Kubernetes cluster was successfully updated.')
end
end
include_examples "user disables a cluster"
context 'when user changes cluster parameters' do
before do

View file

@ -118,16 +118,7 @@ RSpec.describe 'Gcp Cluster', :js do
expect(page.find(:css, '.cluster-name').value).to eq(cluster.name)
end
context 'when user disables the cluster' do
before do
page.find(:css, '.js-cluster-enable-toggle-area .js-project-feature-toggle').click
page.within('.js-cluster-details-form') { click_button 'Save changes' }
end
it 'user sees the successful message' do
expect(page).to have_content('Kubernetes cluster was successfully updated.')
end
end
include_examples "user disables a cluster"
context 'when user changes cluster parameters' do
before do

View file

@ -82,16 +82,7 @@ RSpec.describe 'User Cluster', :js do
expect(page).to have_button('Save changes')
end
context 'when user disables the cluster' do
before do
page.find(:css, '.js-cluster-enable-toggle-area .js-project-feature-toggle').click
page.within('.js-cluster-details-form') { click_button 'Save changes' }
end
it 'user sees the successful message' do
expect(page).to have_content('Kubernetes cluster was successfully updated.')
end
end
include_examples "user disables a cluster"
context 'when user changes cluster parameters' do
before do

View file

@ -1,115 +0,0 @@
import $ from 'jquery';
import waitForPromises from 'helpers/wait_for_promises';
import setupToggleButtons from '~/toggle_buttons';
function generateMarkup(isChecked = true) {
return `
<button type="button" class="${isChecked ? 'is-checked' : ''} js-project-feature-toggle">
<input type="hidden" class="js-project-feature-toggle-input" value="${isChecked}" />
</button>
`;
}
function setupFixture(isChecked, clickCallback) {
const wrapper = document.createElement('div');
wrapper.innerHTML = generateMarkup(isChecked);
setupToggleButtons(wrapper, clickCallback);
return wrapper;
}
describe('ToggleButtons', () => {
describe('when input value is true', () => {
it('should initialize as checked', () => {
const wrapper = setupFixture(true);
expect(
wrapper.querySelector('.js-project-feature-toggle').classList.contains('is-checked'),
).toEqual(true);
expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('true');
});
it('should toggle to unchecked when clicked', () => {
const wrapper = setupFixture(true);
const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
toggleButton.click();
return waitForPromises().then(() => {
expect(toggleButton.classList.contains('is-checked')).toEqual(false);
expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('false');
});
});
});
describe('when input value is false', () => {
it('should initialize as unchecked', () => {
const wrapper = setupFixture(false);
expect(
wrapper.querySelector('.js-project-feature-toggle').classList.contains('is-checked'),
).toEqual(false);
expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('false');
});
it('should toggle to checked when clicked', () => {
const wrapper = setupFixture(false);
const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
toggleButton.click();
return waitForPromises().then(() => {
expect(toggleButton.classList.contains('is-checked')).toEqual(true);
expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('true');
});
});
});
it('should emit `trigger-change` event', () => {
const changeSpy = jest.fn();
const wrapper = setupFixture(false);
const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
const input = wrapper.querySelector('.js-project-feature-toggle-input');
$(input).on('trigger-change', changeSpy);
toggleButton.click();
return waitForPromises().then(() => {
expect(changeSpy).toHaveBeenCalled();
});
});
describe('clickCallback', () => {
it('should show loading indicator while waiting', () => {
const isChecked = true;
const clickCallback = (newValue, toggleButton) => {
const input = toggleButton.querySelector('.js-project-feature-toggle-input');
expect(newValue).toEqual(false);
// Check for the loading state
expect(toggleButton.classList.contains('is-checked')).toEqual(false);
expect(toggleButton.classList.contains('is-loading')).toEqual(true);
expect(toggleButton.disabled).toEqual(true);
expect(input.value).toEqual('true');
// After the callback finishes, check that the loading state is gone
return waitForPromises().then(() => {
expect(toggleButton.classList.contains('is-checked')).toEqual(false);
expect(toggleButton.classList.contains('is-loading')).toEqual(false);
expect(toggleButton.disabled).toEqual(false);
expect(input.value).toEqual('false');
});
};
const wrapper = setupFixture(isChecked, clickCallback);
const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
toggleButton.click();
});
});
});

View file

@ -0,0 +1,14 @@
# frozen_string_literal: true
RSpec.shared_examples "user disables a cluster" do
context 'when user disables the cluster' do
before do
page.find(:css, '.js-cluster-enable-toggle-area .js-project-feature-toggle').click
page.within('.js-cluster-details-form') { click_button 'Save changes' }
end
it 'user sees the successful message' do
expect(page).to have_content('Kubernetes cluster was successfully updated.')
end
end
end