Skip to content
Snippets Groups Projects
SettingsGroup.vue 6.89 KiB
Newer Older
Georg Krause's avatar
Georg Krause committed
  <form
    :id="group.id"
    class="ui form component-settings-group"
    @submit.prevent="save"
  >
    <div class="ui divider" />
Georg Krause's avatar
Georg Krause committed
    <h3 class="ui header">
      {{ group.label }}
    </h3>
    <div
      v-if="errors.length > 0"
      role="alert"
      class="ui negative message"
    >
      <h4 class="header">
        <translate translate-context="Content/*/Error message.Title">
          Error while saving settings
        </translate>
      </h4>
      <ul class="list">
Georg Krause's avatar
Georg Krause committed
        <li
          v-for="(error, key) in errors"
          :key="key"
        >
          {{ error }}
        </li>
Georg Krause's avatar
Georg Krause committed
    <div
      v-if="result"
      class="ui positive message"
    >
      <translate translate-context="Content/Settings/Paragraph">
        Settings updated successfully.
      </translate>
Georg Krause's avatar
Georg Krause committed
    <p v-if="group.help">
      {{ group.help }}
    </p>
    <div
      v-for="(setting, key) in settings"
      :key="key"
      class="ui field"
    >
      <template v-if="setting.field.widget.class !== 'CheckboxInput'">
        <label :for="setting.identifier">{{ setting.verbose_name }}</label>
Georg Krause's avatar
Georg Krause committed
        <p v-if="setting.help_text">
          {{ setting.help_text }}
        </p>
Georg Krause's avatar
Georg Krause committed
      <content-form
        v-if="setting.fieldType === 'markdown'"
        v-model="values[setting.identifier]"
        v-bind="setting.fieldParams"
      />
      <signup-form-builder
        v-else-if="setting.fieldType === 'formBuilder'"
        :value="values[setting.identifier]"
        :signup-approval-enabled="values.moderation__signup_approval_enabled"
Georg Krause's avatar
Georg Krause committed
        @input="set(setting.identifier, $event)"
      />
Georg Krause's avatar
Georg Krause committed
        v-else-if="setting.field.widget.class === 'PasswordInput'"
        :id="setting.identifier"
Georg Krause's avatar
Georg Krause committed
        v-model="values[setting.identifier]"
        type="password"
        class="ui input"
Georg Krause's avatar
Georg Krause committed
      >
Georg Krause's avatar
Georg Krause committed
        v-else-if="setting.field.widget.class === 'TextInput'"
        :id="setting.identifier"
Georg Krause's avatar
Georg Krause committed
        v-model="values[setting.identifier]"
        type="text"
        class="ui input"
Georg Krause's avatar
Georg Krause committed
      >
Georg Krause's avatar
Georg Krause committed
        v-else-if="setting.field.class === 'IntegerField'"
        :id="setting.identifier"
Georg Krause's avatar
Georg Krause committed
        v-model.number="values[setting.identifier]"
        type="number"
        class="ui input"
Georg Krause's avatar
Georg Krause committed
      >
Georg Krause's avatar
Georg Krause committed
        v-else-if="setting.field.widget.class === 'Textarea'"
        :id="setting.identifier"
Georg Krause's avatar
Georg Krause committed
        v-model="values[setting.identifier]"
        type="text"
        class="ui input"
Georg Krause's avatar
Georg Krause committed
      />
      <div
        v-else-if="setting.field.widget.class === 'CheckboxInput'"
        class="ui toggle checkbox"
      >
        <input
          :id="setting.identifier"
          v-model="values[setting.identifier]"
Georg Krause's avatar
Georg Krause committed
          :name="setting.identifier"
          type="checkbox"
        >
        <label :for="setting.identifier">{{ setting.verbose_name }}</label>
Georg Krause's avatar
Georg Krause committed
        <p v-if="setting.help_text">
          {{ setting.help_text }}
        </p>
      <select
        v-else-if="setting.field.class === 'MultipleChoiceField'"
Georg Krause's avatar
Georg Krause committed
        :id="setting.identifier"
        v-model="values[setting.identifier]"
        multiple
Georg Krause's avatar
Georg Krause committed
        class="ui search selection dropdown"
      >
        <option
          v-for="(v, index) in setting.additional_data.choices"
          :key="index"
          :value="v[0]"
        >
          {{ v[1] }}
        </option>
Eliot Berriot's avatar
Eliot Berriot committed
      <div v-else-if="setting.field.widget.class === 'ImageWidget'">
Georg Krause's avatar
Georg Krause committed
        <input
          :id="setting.identifier"
          :ref="setting.identifier"
          type="file"
        >
Eliot Berriot's avatar
Eliot Berriot committed
        <div v-if="values[setting.identifier]">
Georg Krause's avatar
Georg Krause committed
          <div class="ui hidden divider" />
          <h3 class="ui header">
            <translate translate-context="Content/Settings/Title/Noun">
              Current image
            </translate>
          </h3>
          <img
            v-if="values[setting.identifier]"
            class="ui image"
            alt=""
            :src="$store.getters['instance/absoluteUrl'](values[setting.identifier])"
          >
Eliot Berriot's avatar
Eliot Berriot committed
        </div>
      </div>
    </div>
    <button
      type="submit"
Georg Krause's avatar
Georg Krause committed
      :class="['ui', {'loading': isLoading}, 'right', 'floated', 'success', 'button']"
    >
      <translate translate-context="Content/*/Button.Label/Verb">
        Save
      </translate>
    </button>
  </form>
</template>

<script>
import axios from 'axios'

import lodash from '@/lodash'

  components: {
Ciaran Ainsworth's avatar
Ciaran Ainsworth committed
    SignupFormBuilder: () => import(/* webpackChunkName: "signup-form-builder" */ '@/components/admin/SignupFormBuilder.vue')
Georg Krause's avatar
Georg Krause committed
  },
  props: {
    group: { type: Object, required: true },
    settingsData: { type: Array, required: true }
  data () {
    return {
      values: {},
      result: null,
      errors: [],
      isLoading: false
    }
  },
Georg Krause's avatar
Georg Krause committed
  computed: {
    settings () {
      const byIdentifier = {}
      this.settingsData.forEach(e => {
        byIdentifier[e.identifier] = e
      })
      return this.group.settings.map(e => {
        return { ...byIdentifier[e.name], fieldType: e.fieldType, fieldParams: e.fieldParams || {} }
      })
    },
    fileSettings () {
      return this.settings.filter((s) => {
        return s.field.widget.class === 'ImageWidget'
      })
    }
  },
Georg Krause's avatar
Georg Krause committed
    const self = this
    this.settings.forEach(e => {
      self.values[e.identifier] = e.value
    })
  },
  methods: {
    save () {
Georg Krause's avatar
Georg Krause committed
      const self = this
      this.isLoading = true
      self.errors = []
      self.result = null
Eliot Berriot's avatar
Eliot Berriot committed
      let postData = self.values
      let contentType = 'application/json'
Georg Krause's avatar
Georg Krause committed
      const fileSettingsIDs = this.fileSettings.map((s) => { return s.identifier })
Eliot Berriot's avatar
Eliot Berriot committed
      if (fileSettingsIDs.length > 0) {
        contentType = 'multipart/form-data'
        postData = new FormData()
        this.settings.forEach((s) => {
          if (fileSettingsIDs.indexOf(s.identifier) > -1) {
Georg Krause's avatar
Georg Krause committed
            const input = self.$refs[s.identifier][0]
            const files = input.files
Eliot Berriot's avatar
Eliot Berriot committed
            console.log('ref', input, files)
            if (files && files.length > 0) {
              postData.append(s.identifier, files[0])
            }
          } else {
            postData.append(s.identifier, self.values[s.identifier])
          }
        })
      }
      axios.post('instance/admin/settings/bulk/', postData, {
        headers: {
Georg Krause's avatar
Georg Krause committed
          'Content-Type': contentType
        }
Eliot Berriot's avatar
Eliot Berriot committed
      }).then((response) => {
        self.result = true
Eliot Berriot's avatar
Eliot Berriot committed
        response.data.forEach((s) => {
          self.values[s.identifier] = s.value
        })
        self.isLoading = false
        self.$store.dispatch('instance/fetchSettings')
      }, error => {
        self.isLoading = false
        self.errors = error.backendErrors
      })
    },
    set (key, value) {
      // otherwise reactivity doesn't trigger :/
      this.values = lodash.cloneDeep(this.values)
      this.$set(this.values, key, value)