diff options
author | Phil Hughes <me@iamphill.com> | 2018-02-15 09:15:57 +0000 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2018-02-15 09:15:57 +0000 |
commit | 91b2182bc0c79e43126963595db3fe30e0a5fff6 (patch) | |
tree | 3effa29f7f15ea78f2b4f3d07f5cf609c68696b8 /app/assets/javascripts/pages/projects/pipeline_schedules/shared/components | |
parent | 02d9f54f197a28f2d102b7346b1212edb7ddc117 (diff) | |
download | gitlab-ce-91b2182bc0c79e43126963595db3fe30e0a5fff6.tar.gz |
Converted pipeline_schedules bundles into automatic webpack entriespipeline-schedule-webpack
#41341
Diffstat (limited to 'app/assets/javascripts/pages/projects/pipeline_schedules/shared/components')
4 files changed, 345 insertions, 0 deletions
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue new file mode 100644 index 00000000000..2d18fa2044b --- /dev/null +++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue @@ -0,0 +1,160 @@ +<script> + import _ from 'underscore'; + + export default { + props: { + initialCronInterval: { + type: String, + required: false, + default: '', + }, + }, + data() { + return { + inputNameAttribute: 'schedule[cron]', + cronInterval: this.initialCronInterval, + cronIntervalPresets: { + everyDay: '0 4 * * *', + everyWeek: '0 4 * * 0', + everyMonth: '0 4 1 * *', + }, + cronSyntaxUrl: 'https://en.wikipedia.org/wiki/Cron', + customInputEnabled: false, + }; + }, + computed: { + intervalIsPreset() { + return _.contains(this.cronIntervalPresets, this.cronInterval); + }, + // The text input is editable when there's a custom interval, or when it's + // a preset interval and the user clicks the 'custom' radio button + isEditable() { + return !!(this.customInputEnabled || !this.intervalIsPreset); + }, + }, + watch: { + cronInterval() { + // updates field validation state when model changes, as + // glFieldError only updates on input. + this.$nextTick(() => { + gl.pipelineScheduleFieldErrors.updateFormValidityState(); + }); + }, + }, + created() { + if (this.intervalIsPreset) { + this.enableCustomInput = false; + } + }, + methods: { + toggleCustomInput(shouldEnable) { + this.customInputEnabled = shouldEnable; + + if (shouldEnable) { + // We need to change the value so other radios don't remain selected + // because the model (cronInterval) hasn't changed. The server trims it. + this.cronInterval = `${this.cronInterval} `; + } + }, + }, + }; +</script> + +<template> + <div class="interval-pattern-form-group"> + <div class="cron-preset-radio-input"> + <input + id="custom" + class="label-light" + type="radio" + :name="inputNameAttribute" + :value="cronInterval" + :checked="isEditable" + @click="toggleCustomInput(true)" + /> + + <label for="custom"> + {{ s__('PipelineSheduleIntervalPattern|Custom') }} + </label> + + <span class="cron-syntax-link-wrap"> + (<a + :href="cronSyntaxUrl" + target="_blank" + > + {{ __('Cron syntax') }} + </a>) + </span> + </div> + + <div class="cron-preset-radio-input"> + <input + id="every-day" + class="label-light" + type="radio" + v-model="cronInterval" + :name="inputNameAttribute" + :value="cronIntervalPresets.everyDay" + @click="toggleCustomInput(false)" + /> + + <label + class="label-light" + for="every-day" + > + {{ __('Every day (at 4:00am)') }} + </label> + </div> + + <div class="cron-preset-radio-input"> + <input + id="every-week" + class="label-light" + type="radio" + v-model="cronInterval" + :name="inputNameAttribute" + :value="cronIntervalPresets.everyWeek" + @click="toggleCustomInput(false)" + /> + + <label + class="label-light" + for="every-week" + > + {{ __('Every week (Sundays at 4:00am)') }} + </label> + </div> + + <div class="cron-preset-radio-input"> + <input + id="every-month" + class="label-light" + type="radio" + v-model="cronInterval" + :name="inputNameAttribute" + :value="cronIntervalPresets.everyMonth" + @click="toggleCustomInput(false)" + /> + + <label + class="label-light" + for="every-month" + > + {{ __('Every month (on the 1st at 4:00am)') }} + </label> + </div> + + <div class="cron-interval-input-wrapper"> + <input + id="schedule_cron" + class="form-control inline cron-interval-input" + type="text" + :placeholder="__('Define a custom pattern with cron syntax')" + required="true" + v-model="cronInterval" + :name="inputNameAttribute" + :disabled="!isEditable" + /> + </div> + </div> +</template> diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue new file mode 100644 index 00000000000..77508e62cef --- /dev/null +++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue @@ -0,0 +1,67 @@ +<script> + import Vue from 'vue'; + import Cookies from 'js-cookie'; + import Translate from '../../../../../vue_shared/translate'; + import illustrationSvg from '../icons/intro_illustration.svg'; + + Vue.use(Translate); + + const cookieKey = 'pipeline_schedules_callout_dismissed'; + + export default { + name: 'PipelineSchedulesCallout', + data() { + return { + docsUrl: document.getElementById('pipeline-schedules-callout').dataset.docsUrl, + calloutDismissed: Cookies.get(cookieKey) === 'true', + }; + }, + created() { + this.illustrationSvg = illustrationSvg; + }, + methods: { + dismissCallout() { + this.calloutDismissed = true; + Cookies.set(cookieKey, this.calloutDismissed, { expires: 365 }); + }, + }, + }; +</script> +<template> + <div + v-if="!calloutDismissed" + class="pipeline-schedules-user-callout user-callout"> + <div class="bordered-box landing content-block"> + <button + id="dismiss-callout-btn" + class="btn btn-default close" + @click="dismissCallout"> + <i + aria-hidden="true" + class="fa fa-times"> + </i> + </button> + <div + class="svg-container" + v-html="illustrationSvg"> + </div> + <div class="user-callout-copy"> + <h4>{{ __('Scheduling Pipelines') }}</h4> + <p> + {{ __(`The pipelines schedule runs pipelines in the future, +repeatedly, for specific branches or tags. +Those scheduled pipelines will inherit limited project access based on their associated user.`) }} + </p> + <p> {{ __('Learn more in the') }} + <a + :href="docsUrl" + target="_blank" + rel="nofollow" + > + {{ s__('Learn more in the|pipeline schedules documentation') }}</a>. + <!-- oneline to prevent extra space before period --> + </p> + </div> + </div> + </div> +</template> diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/target_branch_dropdown.js b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/target_branch_dropdown.js new file mode 100644 index 00000000000..0c3926d76b5 --- /dev/null +++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/target_branch_dropdown.js @@ -0,0 +1,52 @@ +export default class TargetBranchDropdown { + constructor() { + this.$dropdown = $('.js-target-branch-dropdown'); + this.$dropdownToggle = this.$dropdown.find('.dropdown-toggle-text'); + this.$input = $('#schedule_ref'); + this.initDefaultBranch(); + this.initDropdown(); + } + + initDropdown() { + this.$dropdown.glDropdown({ + data: this.formatBranchesList(), + filterable: true, + selectable: true, + toggleLabel: item => item.name, + search: { + fields: ['name'], + }, + clicked: cfg => this.updateInputValue(cfg), + text: item => item.name, + }); + + this.setDropdownToggle(); + } + + formatBranchesList() { + return this.$dropdown.data('data') + .map(val => ({ name: val })); + } + + setDropdownToggle() { + const initialValue = this.$input.val(); + + this.$dropdownToggle.text(initialValue); + } + + initDefaultBranch() { + const initialValue = this.$input.val(); + const defaultBranch = this.$dropdown.data('defaultBranch'); + + if (!initialValue) { + this.$input.val(defaultBranch); + } + } + + updateInputValue({ selectedObj, e }) { + e.preventDefault(); + + this.$input.val(selectedObj.name); + gl.pipelineScheduleFieldErrors.updateFormValidityState(); + } +} 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 new file mode 100644 index 00000000000..95ed9c7dc21 --- /dev/null +++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js @@ -0,0 +1,66 @@ +/* eslint-disable class-methods-use-this */ + +const defaultTimezone = 'UTC'; + +export default class TimezoneDropdown { + constructor() { + this.$dropdown = $('.js-timezone-dropdown'); + this.$dropdownToggle = this.$dropdown.find('.dropdown-toggle-text'); + this.$input = $('#schedule_cron_timezone'); + this.timezoneData = this.$dropdown.data('data'); + this.initDefaultTimezone(); + this.initDropdown(); + } + + initDropdown() { + this.$dropdown.glDropdown({ + data: this.timezoneData, + filterable: true, + selectable: true, + toggleLabel: item => item.name, + search: { + fields: ['name'], + }, + clicked: cfg => this.updateInputValue(cfg), + text: item => this.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(); + + if (!initialValue) { + this.$input.val(defaultTimezone); + } + } + + setDropdownToggle() { + const initialValue = this.$input.val(); + + this.$dropdownToggle.text(initialValue); + } + + updateInputValue({ selectedObj, e }) { + e.preventDefault(); + this.$input.val(selectedObj.identifier); + gl.pipelineScheduleFieldErrors.updateFormValidityState(); + } +} |