Skip to content
Snippets Groups Projects
SettingsGroup.vue 6.89 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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)