summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEzekiel Kigbo <ekigbo@gitlab.com>2019-04-03 08:27:16 +0000
committerFilipa Lacerda <filipa@gitlab.com>2019-04-03 08:27:16 +0000
commit46fdec84dd787c5311cf45fcf1967a8907e62458 (patch)
tree8a8bbcec151943935fa028d8879c17353dbb2e2e
parent1926bb24d892e1010be21e2087474a70a412cd53 (diff)
downloadgitlab-ce-46fdec84dd787c5311cf45fcf1967a8907e62458.tar.gz
Extend timezone dropdown
Adds optional paramters to the constructor to allow reuse of the timezone dropdown on other pages
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js51
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js8
-rw-r--r--changelogs/unreleased/ekigbo-extend-timezone-dropdown.yml5
-rw-r--r--spec/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js167
4 files changed, 205 insertions, 26 deletions
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js
index 95b57d5e048..c1f6edf2f27 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js
@@ -1,17 +1,33 @@
-/* eslint-disable class-methods-use-this */
+const defaultTimezone = 'UTC';
+
+export const formatUtcOffset = offset => {
+ const parsed = parseInt(offset, 10);
+ if (Number.isNaN(parsed) || parsed === 0) {
+ return `0`;
+ }
+ const prefix = offset > 0 ? '+' : '-';
+ return `${prefix} ${Math.abs(offset / 3600)}`;
+};
-import $ from 'jquery';
+export const formatTimezone = item => `[UTC ${formatUtcOffset(item.offset)}] ${item.name}`;
-const defaultTimezone = 'UTC';
+const defaults = {
+ $inputEl: null,
+ $dropdownEl: null,
+ onSelectTimezone: null,
+};
export default class TimezoneDropdown {
- constructor() {
- this.$dropdown = $('.js-timezone-dropdown');
+ constructor({ $dropdownEl, $inputEl, onSelectTimezone } = defaults) {
+ this.$dropdown = $dropdownEl;
this.$dropdownToggle = this.$dropdown.find('.dropdown-toggle-text');
- this.$input = $('#schedule_cron_timezone');
+ this.$input = $inputEl;
this.timezoneData = this.$dropdown.data('data');
+
this.initDefaultTimezone();
this.initDropdown();
+
+ this.onSelectTimezone = onSelectTimezone;
}
initDropdown() {
@@ -24,28 +40,12 @@ export default class TimezoneDropdown {
fields: ['name'],
},
clicked: cfg => this.updateInputValue(cfg),
- text: item => this.formatTimezone(item),
+ text: item => formatTimezone(item),
});
this.setDropdownToggle();
}
- formatUtcOffset(offset) {
- let prefix = '';
-
- if (offset > 0) {
- prefix = '+';
- } else if (offset < 0) {
- prefix = '-';
- }
-
- return `${prefix} ${Math.abs(offset / 3600)}`;
- }
-
- formatTimezone(item) {
- return `[UTC ${this.formatUtcOffset(item.offset)}] ${item.name}`;
- }
-
initDefaultTimezone() {
const initialValue = this.$input.val();
@@ -56,13 +56,14 @@ export default class TimezoneDropdown {
setDropdownToggle() {
const initialValue = this.$input.val();
-
this.$dropdownToggle.text(initialValue);
}
updateInputValue({ selectedObj, e }) {
e.preventDefault();
this.$input.val(selectedObj.identifier);
- gl.pipelineScheduleFieldErrors.updateFormValidityState();
+ if (this.onSelectTimezone) {
+ this.onSelectTimezone({ selectedObj, e });
+ }
}
}
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js
index 4d494efef6c..dc6df27f1c7 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js
@@ -41,7 +41,13 @@ export default () => {
const formElement = document.getElementById('new-pipeline-schedule-form');
- gl.timezoneDropdown = new TimezoneDropdown();
+ gl.timezoneDropdown = new TimezoneDropdown({
+ $dropdownEl: $('.js-timezone-dropdown'),
+ $inputEl: $('#schedule_cron_timezone'),
+ onSelectTimezone: () => {
+ gl.pipelineScheduleFieldErrors.updateFormValidityState();
+ },
+ });
gl.targetBranchDropdown = new TargetBranchDropdown();
gl.pipelineScheduleFieldErrors = new GlFieldErrors(formElement);
diff --git a/changelogs/unreleased/ekigbo-extend-timezone-dropdown.yml b/changelogs/unreleased/ekigbo-extend-timezone-dropdown.yml
new file mode 100644
index 00000000000..42bc320a542
--- /dev/null
+++ b/changelogs/unreleased/ekigbo-extend-timezone-dropdown.yml
@@ -0,0 +1,5 @@
+---
+title: Extend timezone dropdown
+merge_request: 26311
+author:
+type: changed
diff --git a/spec/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js b/spec/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js
new file mode 100644
index 00000000000..a89952ee435
--- /dev/null
+++ b/spec/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js
@@ -0,0 +1,167 @@
+import $ from 'jquery';
+import GLDropdown from '~/gl_dropdown'; // eslint-disable-line no-unused-vars
+import TimezoneDropdown, {
+ formatUtcOffset,
+ formatTimezone,
+} from '~/pages/projects/pipeline_schedules/shared/components/timezone_dropdown';
+
+describe('Timezone Dropdown', function() {
+ preloadFixtures('pipeline_schedules/edit.html');
+
+ let $inputEl = null;
+ let $dropdownEl = null;
+ let $wrapper = null;
+ const tzListSel = '.dropdown-content ul li a.is-active';
+
+ describe('Initialize', () => {
+ describe('with dropdown already loaded', () => {
+ beforeEach(() => {
+ loadFixtures('pipeline_schedules/edit.html');
+ $wrapper = $('.dropdown');
+ $inputEl = $('#schedule_cron_timezone');
+ $dropdownEl = $('.js-timezone-dropdown');
+
+ // eslint-disable-next-line no-new
+ new TimezoneDropdown({
+ $inputEl,
+ $dropdownEl,
+ });
+ });
+
+ it('can take an $inputEl in the constructor', () => {
+ const tzStr = '[UTC + 5.5] Sri Jayawardenepura';
+ const tzValue = 'Asia/Colombo';
+
+ expect($inputEl.val()).toBe('UTC');
+
+ $(`${tzListSel}:contains('${tzStr}')`, $wrapper).trigger('click');
+
+ const val = $inputEl.val();
+
+ expect(val).toBe(tzValue);
+ expect(val).not.toBe('UTC');
+ });
+
+ it('will format data array of timezones into a list of offsets', () => {
+ const data = $dropdownEl.data('data');
+ const formatted = $wrapper.find(tzListSel).text();
+
+ data.forEach(item => {
+ expect(formatted).toContain(formatTimezone(item));
+ });
+ });
+
+ it('will default the timezone to UTC', () => {
+ const tz = $inputEl.val();
+
+ expect(tz).toBe('UTC');
+ });
+ });
+
+ describe('without dropdown loaded', () => {
+ beforeEach(() => {
+ loadFixtures('pipeline_schedules/edit.html');
+ $wrapper = $('.dropdown');
+ $inputEl = $('#schedule_cron_timezone');
+ $dropdownEl = $('.js-timezone-dropdown');
+ });
+
+ it('will populate the list of UTC offsets after the dropdown is loaded', () => {
+ expect($wrapper.find(tzListSel).length).toEqual(0);
+
+ // eslint-disable-next-line no-new
+ new TimezoneDropdown({
+ $inputEl,
+ $dropdownEl,
+ });
+
+ expect($wrapper.find(tzListSel).length).toEqual($($dropdownEl).data('data').length);
+ });
+
+ it('will call a provided handler when a new timezone is selected', () => {
+ const onSelectTimezone = jasmine.createSpy('onSelectTimezoneMock');
+ // eslint-disable-next-line no-new
+ new TimezoneDropdown({
+ $inputEl,
+ $dropdownEl,
+ onSelectTimezone,
+ });
+
+ $wrapper
+ .find(tzListSel)
+ .first()
+ .trigger('click');
+
+ expect(onSelectTimezone).toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('formatUtcOffset', () => {
+ it('will convert negative utc offsets in seconds to hours and minutes', () => {
+ expect(formatUtcOffset(-21600)).toEqual('- 6');
+ });
+
+ it('will convert positive utc offsets in seconds to hours and minutes', () => {
+ expect(formatUtcOffset(25200)).toEqual('+ 7');
+ expect(formatUtcOffset(49500)).toEqual('+ 13.75');
+ });
+
+ it('will return 0 when given a string', () => {
+ expect(formatUtcOffset('BLAH')).toEqual('0');
+ expect(formatUtcOffset('$%$%')).toEqual('0');
+ });
+
+ it('will return 0 when given an array', () => {
+ expect(formatUtcOffset(['an', 'array'])).toEqual('0');
+ });
+
+ it('will return 0 when given an object', () => {
+ expect(formatUtcOffset({ some: '', object: '' })).toEqual('0');
+ });
+
+ it('will return 0 when given null', () => {
+ expect(formatUtcOffset(null)).toEqual('0');
+ });
+
+ it('will return 0 when given undefined', () => {
+ expect(formatUtcOffset(undefined)).toEqual('0');
+ });
+
+ it('will return 0 when given empty input', () => {
+ expect(formatUtcOffset('')).toEqual('0');
+ });
+ });
+
+ describe('formatTimezone', () => {
+ it('given name: "Chatham Is.", offset: "49500", will format for display as "[UTC + 13.75] Chatham Is."', () => {
+ expect(
+ formatTimezone({
+ name: 'Chatham Is.',
+ offset: 49500,
+ identifier: 'Pacific/Chatham',
+ }),
+ ).toEqual('[UTC + 13.75] Chatham Is.');
+ });
+
+ it('given name: "Saskatchewan", offset: "-21600", will format for display as "[UTC - 6] Saskatchewan"', () => {
+ expect(
+ formatTimezone({
+ name: 'Saskatchewan',
+ offset: -21600,
+ identifier: 'America/Regina',
+ }),
+ ).toEqual('[UTC - 6] Saskatchewan');
+ });
+
+ it('given name: "Accra", offset: "0", will format for display as "[UTC 0] Accra"', () => {
+ expect(
+ formatTimezone({
+ name: 'Accra',
+ offset: 0,
+ identifier: 'Africa/Accra',
+ }),
+ ).toEqual('[UTC 0] Accra');
+ });
+ });
+});