Slightly refactor pipeline schedules form in preparation for additions
This commit is contained in:
parent
bf4129292d
commit
2da314212f
|
@ -1,148 +0,0 @@
|
|||
import Vue from 'vue';
|
||||
import Translate from '../../vue_shared/translate';
|
||||
|
||||
Vue.use(Translate);
|
||||
|
||||
const inputNameAttribute = 'schedule[cron]';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
initialCronInterval: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inputNameAttribute,
|
||||
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);
|
||||
},
|
||||
},
|
||||
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} `;
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.intervalIsPreset) {
|
||||
this.enableCustomInput = false;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
cronInterval() {
|
||||
// updates field validation state when model changes, as
|
||||
// glFieldError only updates on input.
|
||||
Vue.nextTick(() => {
|
||||
gl.pipelineScheduleFieldErrors.updateFormValidityState();
|
||||
});
|
||||
},
|
||||
},
|
||||
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>
|
||||
`,
|
||||
};
|
|
@ -0,0 +1,144 @@
|
|||
<script>
|
||||
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);
|
||||
},
|
||||
},
|
||||
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} `;
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.intervalIsPreset) {
|
||||
this.enableCustomInput = false;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
cronInterval() {
|
||||
// updates field validation state when model changes, as
|
||||
// glFieldError only updates on input.
|
||||
this.$nextTick(() => {
|
||||
gl.pipelineScheduleFieldErrors.updateFormValidityState();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</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>
|
|
@ -1,20 +1,41 @@
|
|||
import Vue from 'vue';
|
||||
import IntervalPatternInput from './components/interval_pattern_input';
|
||||
import Translate from '../vue_shared/translate';
|
||||
import intervalPatternInput from './components/interval_pattern_input.vue';
|
||||
import TimezoneDropdown from './components/timezone_dropdown';
|
||||
import TargetBranchDropdown from './components/target_branch_dropdown';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const IntervalPatternInputComponent = Vue.extend(IntervalPatternInput);
|
||||
Vue.use(Translate);
|
||||
|
||||
function initIntervalPatternInput() {
|
||||
const intervalPatternMount = document.getElementById('interval-pattern-input');
|
||||
const initialCronInterval = intervalPatternMount ? intervalPatternMount.dataset.initialInterval : '';
|
||||
|
||||
new IntervalPatternInputComponent({
|
||||
propsData: {
|
||||
initialCronInterval,
|
||||
return new Vue({
|
||||
el: intervalPatternMount,
|
||||
components: {
|
||||
intervalPatternInput,
|
||||
},
|
||||
}).$mount(intervalPatternMount);
|
||||
render(createElement) {
|
||||
return createElement('interval-pattern-input', {
|
||||
props: {
|
||||
initialCronInterval,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
/* Most of the form is written in haml, but for fields with more complex behaviors,
|
||||
* you should mount individual Vue components here. If at some point components need
|
||||
* to share state, it may make sense to refactor the whole form to Vue */
|
||||
|
||||
initIntervalPatternInput();
|
||||
|
||||
// Initialize non-Vue JS components in the form
|
||||
|
||||
const formElement = document.getElementById('new-pipeline-schedule-form');
|
||||
|
||||
gl.timezoneDropdown = new TimezoneDropdown();
|
||||
gl.targetBranchDropdown = new TargetBranchDropdown();
|
||||
gl.pipelineScheduleFieldErrors = new gl.GlFieldErrors(formElement);
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import Vue from 'vue';
|
||||
import IntervalPatternInput from '~/pipeline_schedules/components/interval_pattern_input';
|
||||
import Translate from '~/vue_shared/translate';
|
||||
import IntervalPatternInput from '~/pipeline_schedules/components/interval_pattern_input.vue';
|
||||
|
||||
Vue.use(Translate);
|
||||
|
||||
const IntervalPatternInputComponent = Vue.extend(IntervalPatternInput);
|
||||
const inputNameAttribute = 'schedule[cron]';
|
||||
|
|
Loading…
Reference in New Issue