From c48b08efee3bc3c30a82cdcbdb088073697264ac Mon Sep 17 00:00:00 2001
From: Angelina Filippova <linakirsanova@gmail.com>
Date: Fri, 3 Jan 2020 17:00:20 +0700
Subject: [PATCH] Improve processing multiple selects with array values

---
 src/store/modules/normalizers.js              | 22 +++++--
 src/store/modules/settings.js                 |  2 +-
 src/views/settings/components/Inputs.vue      |  8 +--
 .../inputComponents/BackendsLoggerInput.vue   | 49 ---------------
 .../inputComponents/MultipleSelect.vue        | 63 +++++++++++++++++++
 .../components/inputComponents/index.js       |  4 +-
 src/views/settings/index.vue                  |  8 +--
 7 files changed, 91 insertions(+), 65 deletions(-)
 delete mode 100644 src/views/settings/components/inputComponents/BackendsLoggerInput.vue
 create mode 100644 src/views/settings/components/inputComponents/MultipleSelect.vue

diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js
index 120c3874..d4dcbc1f 100644
--- a/src/store/modules/normalizers.js
+++ b/src/store/modules/normalizers.js
@@ -31,9 +31,14 @@ export const parseNonTuples = (key, value) => {
   if (key === ':backends') {
     const index = value.findIndex(el => typeof el === 'object' && el.tuple.includes(':ex_syslogger'))
     const updated = value.map((el, i) => i === index ? ':ex_syslogger' : el)
-    return { value: updated }
+    return updated
   }
-  return { value }
+  if (key === ':args') {
+    const index = value.findIndex(el => typeof el === 'object' && el.tuple.includes('implode'))
+    const updated = value.map((el, i) => i === index ? 'implode' : el)
+    return updated
+  }
+  return value
 }
 // REFACTOR
 export const parseTuples = (tuples, key) => {
@@ -64,9 +69,11 @@ export const parseTuples = (tuples, key) => {
       accum[item.tuple[0]] = item.tuple[1] === ':disabled' ? [item.tuple[1]] : item.tuple[1].tuple
     } else if (item.tuple[0] === ':proxy_url') {
       accum[item.tuple[0]] = parseProxyUrl(item.tuple[1])
-    } else if ((item.tuple[0] === ':sslopts' && item.tuple[1].length === 0) || // should be removed
+    } else if ((item.tuple[0] === ':sslopts' && item.tuple[1].length === 0) ||
       (item.tuple[0] === ':tlsopts' && item.tuple[1].length === 0)) {
       accum[item.tuple[0]] = {}
+    } else if (item.tuple[0] === ':args') {
+      accum[item.tuple[0]] = parseNonTuples(item.tuple[0], item.tuple[1])
     } else if (Array.isArray(item.tuple[1]) &&
       (typeof item.tuple[1][0] === 'object' && !Array.isArray(item.tuple[1][0])) && item.tuple[1][0]['tuple']) {
       accum[item.tuple[0]] = parseTuples(item.tuple[1], item.tuple[0])
@@ -193,7 +200,7 @@ export const wrapUpdatedSettings = (group, settings, currentState) => {
 
 const wrapValues = (settings, currentState) => {
   return Object.keys(settings).map(setting => {
-    const [type, value] = Array.isArray(settings[setting]) ? settings[setting] : ['', settings[setting]]
+    const [type, value] = settings[setting]
     if (type === 'keyword' || type.includes('keyword') || setting === ':replace') {
       return { 'tuple': [setting, wrapValues(value, currentState)] }
     } else if (type === 'atom' && value.length > 0) {
@@ -218,6 +225,13 @@ const wrapValues = (settings, currentState) => {
       return { 'tuple': [setting, { 'tuple': ip }] }
     } else if (setting === ':ssl_options') {
       return { 'tuple': [setting, wrapValues(value, currentState)] }
+    } else if (setting === ':args') {
+      const index = value.findIndex(el => el === 'implode')
+      const updatedArray = value.slice()
+      if (index !== -1) {
+        updatedArray[index] = { 'tuple': ['implode', '1'] }
+      }
+      return { 'tuple': [setting, updatedArray] }
     } else {
       return { 'tuple': [setting, value] }
     }
diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js
index f7d1df79..406bd46d 100644
--- a/src/store/modules/settings.js
+++ b/src/store/modules/settings.js
@@ -36,7 +36,7 @@ const settings = {
     SET_SETTINGS: (state, data) => {
       const newSettings = data.reduce((acc, { group, key, value }) => {
         const parsedValue = valueHasTuples(key, value)
-          ? parseNonTuples(key, value)
+          ? { value: parseNonTuples(key, value) }
           : parseTuples(value, key)
         acc[group][key] = { ...acc[group][key], ...parsedValue }
         return acc
diff --git a/src/views/settings/components/Inputs.vue b/src/views/settings/components/Inputs.vue
index c707b859..90d66e46 100644
--- a/src/views/settings/components/Inputs.vue
+++ b/src/views/settings/components/Inputs.vue
@@ -75,7 +75,7 @@
     <icons-input v-if="setting.key === ':icons'" :data="data[':icons']" :setting-group="settingGroup" :setting="setting"/>
     <proxy-url-input v-if="setting.key === ':proxy_url'" :data="data[setting.key]" :setting-group="settingGroup" :setting="setting"/>
     <!-- <ssl-options-input v-if="setting.key === ':ssl_options'" :setting-group="settingGroup" :setting-parent="settingParent" :setting="setting" :data="data" :nested="true" :custom-label-width="'100px'"/> -->
-    <backends-logger-input v-if="setting.key === ':backends'" :data="data" :setting-group="settingGroup" :setting="setting"/>
+    <multiple-select v-if="setting.key === ':backends' || setting.key === ':args'" :data="data" :setting-group="settingGroup" :setting="setting"/>
     <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"/>
     <!-------------------->
@@ -87,7 +87,7 @@
 import AceEditor from 'vue2-ace-editor'
 import 'brace/mode/elixir'
 import 'default-passive-events'
-import { AutoLinkerInput, BackendsLoggerInput, EditableKeywordInput, IconsInput, MascotsInput, ProxyUrlInput, PruneInput, RateLimitInput, SslOptionsInput } from './inputComponents'
+import { AutoLinkerInput, EditableKeywordInput, IconsInput, MascotsInput, MultipleSelect, ProxyUrlInput, PruneInput, RateLimitInput, SslOptionsInput } from './inputComponents'
 import { processNested } from '@/store/modules/normalizers'
 
 export default {
@@ -95,10 +95,10 @@ export default {
   components: {
     editor: AceEditor,
     AutoLinkerInput,
-    BackendsLoggerInput,
     EditableKeywordInput,
     IconsInput,
     MascotsInput,
+    MultipleSelect,
     ProxyUrlInput,
     PruneInput,
     RateLimitInput,
@@ -216,7 +216,7 @@ export default {
         { group, key: parentKey, input: setting.key, value: valueForState })
     },
     renderMultipleSelect(type) {
-      return Array.isArray(type) && this.setting.key !== ':backends' && (
+      return Array.isArray(type) && this.setting.key !== ':backends' && this.setting.key !== ':args' && (
         type.includes('module') ||
         (type.includes('list') && type.includes('string')) ||
         (type.includes('list') && type.includes('atom')) ||
diff --git a/src/views/settings/components/inputComponents/BackendsLoggerInput.vue b/src/views/settings/components/inputComponents/BackendsLoggerInput.vue
deleted file mode 100644
index da6af188..00000000
--- a/src/views/settings/components/inputComponents/BackendsLoggerInput.vue
+++ /dev/null
@@ -1,49 +0,0 @@
-<template>
-  <el-select
-    :value="data.value"
-    multiple
-    filterable
-    allow-create
-    @change="updateSetting($event, settingGroup.group, settingGroup.key, setting.key, setting.type)">
-    <el-option value=":console" label="console"/>
-    <el-option value=":ex_syslogger" label="ExSyslogger"/>
-    <el-option value="Quack.Logger" label="Quack.Logger"/>
-  </el-select>
-</template>
-
-<script>
-export default {
-  name: 'BackendsLoggerInput',
-  props: {
-    data: {
-      type: [Object, Array],
-      default: function() {
-        return {}
-      }
-    },
-    setting: {
-      type: Object,
-      default: function() {
-        return {}
-      }
-    },
-    settingGroup: {
-      type: Object,
-      default: function() {
-        return {}
-      }
-    }
-  },
-  methods: {
-    updateSetting(value, group, key, input, type) {
-      this.$store.dispatch('UpdateSettings', { group, key, input, value, type })
-      this.$store.dispatch('UpdateState', { group, key, input, value })
-    }
-  }
-}
-</script>
-
-<style rel='stylesheet/scss' lang='scss'>
-@import '../../styles/main';
-@include settings
-</style>
diff --git a/src/views/settings/components/inputComponents/MultipleSelect.vue b/src/views/settings/components/inputComponents/MultipleSelect.vue
new file mode 100644
index 00000000..bcb766fa
--- /dev/null
+++ b/src/views/settings/components/inputComponents/MultipleSelect.vue
@@ -0,0 +1,63 @@
+<template>
+  <div>
+    <el-select
+      v-if="setting.key === ':backends'"
+      :value="data.value"
+      multiple
+      filterable
+      allow-create
+      @change="updateSetting($event, settingGroup.group, settingGroup.key, setting.key, setting.type)">
+      <el-option value=":console" label="console"/>
+      <el-option value=":ex_syslogger" label="ExSyslogger"/>
+      <el-option value="Quack.Logger" label="Quack.Logger"/>
+    </el-select>
+    <el-select
+      v-if="setting.key === ':args'"
+      :value="data[setting.key]"
+      multiple
+      filterable
+      allow-create
+      @change="updateSetting($event, settingGroup.group, settingGroup.key, setting.key, setting.type)">
+      <el-option value="strip" label="strip"/>
+      <el-option value="auto-orient" label="auto-orient"/>
+      <el-option value="implode" label="implode"/>
+    </el-select>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'MultipleSelect',
+  props: {
+    data: {
+      type: [Object, Array],
+      default: function() {
+        return {}
+      }
+    },
+    setting: {
+      type: Object,
+      default: function() {
+        return {}
+      }
+    },
+    settingGroup: {
+      type: Object,
+      default: function() {
+        return {}
+      }
+    }
+  },
+  methods: {
+    updateSetting(value, group, key, input, type) {
+      this.$store.dispatch('UpdateSettings', { group, key, input, value, type })
+      this.$store.dispatch('UpdateState', { group, key, input, value })
+    }
+  }
+}
+</script>
+
+<style rel='stylesheet/scss' lang='scss'>
+@import '../../styles/main';
+@include settings
+</style>
diff --git a/src/views/settings/components/inputComponents/index.js b/src/views/settings/components/inputComponents/index.js
index 601f47d0..faf7c1f8 100644
--- a/src/views/settings/components/inputComponents/index.js
+++ b/src/views/settings/components/inputComponents/index.js
@@ -1,8 +1,8 @@
 export { default as AutoLinkerInput } from './AutoLinkerInput'
-export { default as BackendsLoggerInput } from './BackendsLoggerInput'
-export { default as MascotsInput } from './MascotsInput'
 export { default as EditableKeywordInput } from './EditableKeywordInput'
 export { default as IconsInput } from './IconsInput'
+export { default as MascotsInput } from './MascotsInput'
+export { default as MultipleSelect } from './MultipleSelect'
 export { default as ProxyUrlInput } from './ProxyUrlInput'
 export { default as PruneInput } from './PruneInput'
 export { default as RateLimitInput } from './RateLimitInput'
diff --git a/src/views/settings/index.vue b/src/views/settings/index.vue
index 91c73493..5be2da66 100644
--- a/src/views/settings/index.vue
+++ b/src/views/settings/index.vue
@@ -65,14 +65,12 @@
       <el-tab-pane :label="$t('settings.webPush')" lazy>
         <web-push/>
       </el-tab-pane>
-      <el-tab-pane :label="$t('settings.other')" lazy>
-        <other/>
-      </el-tab-pane>
-      <!--
       <el-tab-pane :label="$t('settings.upload')" lazy>
         <upload/>
       </el-tab-pane>
-       -->
+      <el-tab-pane :label="$t('settings.other')" lazy>
+        <other/>
+      </el-tab-pane>
     </el-tabs>
   </div>
 </template>
-- 
GitLab