diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index 8be6220d1fe3aa234305e8c3ccec8f3e65e912f8..ba4bea81d2dd6b3d88582d480675f34f73c9ce07 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -81,14 +81,14 @@ export const parseTuples = (tuples, key) => { return [...acc, { [mascot.tuple[0]]: { ...mascot.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}] }, []) } else if ( - item.tuple[0] === ':groups' || - item.tuple[0] === ':replace' || - item.tuple[0] === ':retries' || - item.tuple[0] === ':crontab' - ) { + item.tuple[0] === ':groups' || item.tuple[0] === ':replace' || item.tuple[0] === ':retries') { accum[item.tuple[0]] = item.tuple[1].reduce((acc, group) => { return [...acc, { [group.tuple[0]]: { value: group.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}] }, []) + } else if (item.tuple[0] === ':crontab') { + accum[item.tuple[0]] = item.tuple[1].reduce((acc, group) => { + return { ...acc, [group.tuple[1]]: group.tuple[0] } + }, {}) } else if (item.tuple[0] === ':match_actor') { accum[item.tuple[0]] = Object.keys(item.tuple[1]).reduce((acc, regex) => { return [...acc, { [regex]: { value: item.tuple[1][regex], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}] diff --git a/src/views/settings/components/Inputs.vue b/src/views/settings/components/Inputs.vue index d99871b2e0705c8b74f1e8db1f6807d67ed39b98..300f09c7b39a708f0503c06480d360657afc8f31 100644 --- a/src/views/settings/components/Inputs.vue +++ b/src/views/settings/components/Inputs.vue @@ -84,11 +84,12 @@ </el-input> <!-- special inputs --> <auto-linker-input v-if="settingGroup.group === ':auto_linker'" :data="data" :setting-group="settingGroup" :setting="setting"/> - <mascots-input v-if="setting.key === ':mascots'" :data="keywordData" :setting-group="settingGroup" :setting="setting"/> + <crontab-input v-if="setting.key === ':crontab'" :data="data[setting.key]" :setting-group="settingGroup" :setting="setting"/> <editable-keyword-input v-if="editableKeyword(setting.key, setting.type)" :data="keywordData" :setting-group="settingGroup" :setting="setting"/> <icons-input v-if="setting.key === ':icons'" :data="iconsData" :setting-group="settingGroup" :setting="setting"/> - <proxy-url-input v-if="setting.key === ':proxy_url'" :data="data[setting.key]" :setting-group="settingGroup" :setting="setting" :parents="settingParent"/> + <mascots-input v-if="setting.key === ':mascots'" :data="keywordData" :setting-group="settingGroup" :setting="setting"/> <multiple-select v-if="setting.key === ':backends' || setting.key === ':args'" :data="data" :setting-group="settingGroup" :setting="setting"/> + <proxy-url-input v-if="setting.key === ':proxy_url'" :data="data[setting.key]" :setting-group="settingGroup" :setting="setting" :parents="settingParent"/> <prune-input v-if="setting.key === ':prune'" :data="data[setting.key]" :setting-group="settingGroup" :setting="setting"/> <rate-limit-input v-if="settingGroup.key === ':rate_limit'" :data="data" :setting-group="settingGroup" :setting="setting"/> <!--------------------> @@ -106,7 +107,7 @@ <script> import i18n from '@/lang' -import { AutoLinkerInput, EditableKeywordInput, IconsInput, MascotsInput, MultipleSelect, ProxyUrlInput, PruneInput, RateLimitInput } from './inputComponents' +import { AutoLinkerInput, CrontabInput, EditableKeywordInput, IconsInput, MascotsInput, MultipleSelect, ProxyUrlInput, PruneInput, RateLimitInput } from './inputComponents' import { processNested } from '@/store/modules/normalizers' import _ from 'lodash' import marked from 'marked' @@ -115,6 +116,7 @@ export default { name: 'Inputs', components: { AutoLinkerInput, + CrontabInput, EditableKeywordInput, IconsInput, MascotsInput, @@ -223,11 +225,7 @@ export default { } }, keywordData() { - if (this.setting.key === ':crontab') { - return this.data[this.setting.key] || [] - } else { - return Array.isArray(this.data) ? this.data : [] - } + return Array.isArray(this.data) ? this.data : [] }, rewritePolicyValue() { return typeof this.data[this.setting.key] === 'string' ? [this.data[this.setting.key]] : this.data[this.setting.key] @@ -244,8 +242,7 @@ export default { return key === ':replace' || type === 'map' || (Array.isArray(type) && type.includes('keyword') && type.includes('integer')) || - (Array.isArray(type) && type.includes('keyword') && type.findIndex(el => el.includes('list') && el.includes('string')) !== -1) || - (Array.isArray(type) && type.includes('list') && type.includes('tuple')) + (Array.isArray(type) && type.includes('keyword') && type.findIndex(el => el.includes('list') && el.includes('string')) !== -1) }, getFormattedDescription(desc) { return marked(desc) diff --git a/src/views/settings/components/inputComponents/CrontabInput.vue b/src/views/settings/components/inputComponents/CrontabInput.vue new file mode 100644 index 0000000000000000000000000000000000000000..f3f16d26aef333e16800d743c0315a113c116305 --- /dev/null +++ b/src/views/settings/components/inputComponents/CrontabInput.vue @@ -0,0 +1,86 @@ +<template> + <el-form :label-width="labelWidth" :label-position="isMobile ? 'top' : 'right'" class="crontab"> + <el-form-item v-for="worker in workers" :key="worker" :label="worker" class="crontab-container"> + <el-input + :value="data[worker]" + :placeholder="getSuggestion(worker) || null" + class="input setting-input" + @input="update($event, worker)"/> + </el-form-item> + </el-form> +</template> + +<script> +export default { + name: 'CrontabInput', + props: { + data: { + type: Object, + default: function() { + return {} + } + }, + setting: { + type: Object, + default: function() { + return {} + } + }, + settingGroup: { + type: Object, + default: function() { + return {} + } + } + }, + computed: { + isDesktop() { + return this.$store.state.app.device === 'desktop' + }, + isMobile() { + return this.$store.state.app.device === 'mobile' + }, + isTablet() { + return this.$store.state.app.device === 'tablet' + }, + labelWidth() { + if (this.isMobile) { + return '100%' + } else { + return '380px' + } + }, + workers() { + return this.setting.suggestions.map(worker => worker[1]) + } + }, + methods: { + getSuggestion(worker) { + return this.setting.suggestions.find(suggestion => suggestion[1] === worker)[0] + }, + update(value, worker) { + const currentValue = this.$store.state.settings.settings[this.settingGroup.group][this.settingGroup.key][this.setting.key] + const updatedValue = { ...currentValue, [worker]: value } + const updatedValueWithType = Object.keys(currentValue).reduce((acc, key) => { + if (key === worker) { + return { ...acc, [key]: ['reversed_tuple', value] } + } else { + return { ...acc, [key]: ['reversed_tuple', currentValue[key]] } + } + }, {}) + + this.$store.dispatch('UpdateSettings', + { group: this.settingGroup.group, key: this.settingGroup.key, input: this.setting.key, value: updatedValueWithType, type: this.setting.type } + ) + this.$store.dispatch('UpdateState', + { group: this.settingGroup.group, key: this.settingGroup.key, input: this.setting.key, value: updatedValue } + ) + } + } +} +</script> + +<style rel='stylesheet/scss' lang='scss'> +@import '../../styles/main'; +@include settings +</style> diff --git a/src/views/settings/components/inputComponents/EditableKeywordInput.vue b/src/views/settings/components/inputComponents/EditableKeywordInput.vue index a6ecde4dab32c724950a72ba65ea2b8c023313b9..fe5b9c7b24ef962b7efa6d736855f0be55417fdb 100644 --- a/src/views/settings/components/inputComponents/EditableKeywordInput.vue +++ b/src/views/settings/components/inputComponents/EditableKeywordInput.vue @@ -8,14 +8,6 @@ </div> <el-button :size="isDesktop ? 'medium' : 'mini'" icon="el-icon-plus" circle @click="addRowToEditableKeyword"/> </div> - <div v-if="setting.key === ':crontab'"> - <div v-for="element in data" :key="getId(element)" class="setting-input"> - <el-input :value="getValue(element)" placeholder="worker" class="crontab-value-input" @input="parseEditableKeyword($event, 'value', element)"/> : - <el-input :value="getKey(element)" placeholder="crontab format" class="crontab-name-input" @input="parseEditableKeyword($event, 'key', element)"/> - <el-button :size="isDesktop ? 'medium' : 'mini'" class="icon-minus-button" icon="el-icon-minus" circle @click="deleteEditableKeywordRow(element)"/> - </div> - <el-button :size="isDesktop ? 'medium' : 'mini'" icon="el-icon-plus" circle @click="addRowToEditableKeyword"/> - </div> <div v-else-if="editableKeywordWithInteger"> <div v-for="element in data" :key="getId(element)" class="setting-input"> <el-input :value="getKey(element)" placeholder="key" class="name-input" @input="parseEditableKeyword($event, 'key', element)"/> : @@ -109,19 +101,13 @@ export default { this.$store.dispatch('UpdateState', { group, key, input, value }) }, wrapUpdatedSettings(value, input, type) { - if (type === 'map') { - return value.reduce((acc, element) => { + return type === 'map' + ? value.reduce((acc, element) => { return { ...acc, [Object.keys(element)[0]]: Object.values(element)[0].value } }, {}) - } else if (input === ':crontab') { - return value.reduce((acc, element) => { - return { ...acc, [Object.values(element)[0].value]: ['reversed_tuple', Object.keys(element)[0]] } - }, {}) - } else { - return value.reduce((acc, element) => { + : value.reduce((acc, element) => { return { ...acc, [Object.keys(element)[0]]: ['list', Object.values(element)[0].value] } }, {}) - } } } } diff --git a/src/views/settings/components/inputComponents/index.js b/src/views/settings/components/inputComponents/index.js index 389b304efeee186f2fc438ddd41aebb633917bcc..788d1f994332205130c22954b1bd6931017d1842 100644 --- a/src/views/settings/components/inputComponents/index.js +++ b/src/views/settings/components/inputComponents/index.js @@ -1,5 +1,6 @@ export { default as AutoLinkerInput } from './AutoLinkerInput' export { default as EditableKeywordInput } from './EditableKeywordInput' +export { default as CrontabInput } from './CrontabInput' export { default as IconsInput } from './IconsInput' export { default as MascotsInput } from './MascotsInput' export { default as MultipleSelect } from './MultipleSelect' diff --git a/src/views/settings/styles/main.scss b/src/views/settings/styles/main.scss index fd8e69d219e198b2c7e3337d637b49a541bbf02f..562308b5d0ba03a6dba215dd489ef48a7c6938c9 100644 --- a/src/views/settings/styles/main.scss +++ b/src/views/settings/styles/main.scss @@ -14,15 +14,6 @@ font-family: monospace; padding: 0 3px 0 3px; } - .crontab-name-input { - width: 30%; - margin-left: 8px; - margin-right: 10px - } - .crontab-value-input { - width: 70%; - margin-right: 8px - } .delete-setting-button { margin-left: 5px; } @@ -334,7 +325,6 @@ margin-right: 10px } - @media only screen and (min-width: 1824px) { .submit-button-container { max-width: 1637px; @@ -345,6 +335,12 @@ } @media only screen and (max-width:480px) { + .crontab { + width: 100%; + label { + width: 100%; + } + } .delete-setting-button { margin: 4px 0 0 5px; height: 28px; @@ -388,6 +384,10 @@ margin: 0; padding: 0 15px 10px 0; } + .el-form-item.crontab-container:first-child { + margin: 0; + padding: 0 ; + } .el-form-item:first-child .mascot-form-item { padding: 0; }