SpeciesFileGroup/taxonworks

View on GitHub
app/javascript/vue/components/soft_validations/panel.vue

Summary

Maintainability
Test Coverage
<template>
  <div
    v-if="validationSections.length"
    class="panel content soft-validation-box validation-warning"
  >
    <div class="header flex-separate">
      <h3>Soft Validation</h3>
    </div>
    <div class="body overflow-y-auto">
      <template
        v-for="(section, index) in validationSections"
        :key="index"
      >
        <div>
          <h3>
            <span v-if="section.title">{{ section.title }}</span>
            <button
              v-if="getFixPresent(section.list).length"
              type="button"
              class="button button-submit margin-small-left"
              @click="runFix(getFixPresent(section.list))"
            >
              <span>Fix all</span>
            </button>
          </h3>
          <ul
            v-for="list in section.list"
            class="no_bullets"
          >
            <li
              class="horizontal-left-content align-start"
              v-for="(error, index) in list.soft_validations"
              :key="index"
            >
              <tippy
                animation="scale"
                placement="bottom"
                size="small"
                inertia
                arrow
                :content="error.description"
              >
                <span data-icon="warning" />
              </tippy>
              <span>
                <button
                  v-if="error.fixable"
                  type="button"
                  class="button button-submit"
                  @click="
                    runFix([
                      {
                        global_id: list.instance.global_id,
                        only_methods: [error.soft_validation_method]
                      }
                    ])
                  "
                >
                  Fix
                </button>
                <span>
                  <span v-html="error.message" />
                  <template
                    v-for="(resolution, rIndex) in error.resolution"
                    :key="rIndex"
                  >
                    <tippy
                      class="d-inline-block"
                      animation="scale"
                      placement="bottom"
                      size="small"
                      inertia
                      arrow
                      content="Fixable here (may leave page)"
                    >
                      <a :href="resolution">
                        <span
                          class="small-icon icon-without-space"
                          data-icon="blue_wrench"
                        />
                      </a>
                    </tippy>
                  </template>
                </span>
              </span>
            </li>
          </ul>
          <hr v-if="index !== validationSections.length - 1" />
        </div>
      </template>
    </div>
  </div>
</template>

<script>
import { SoftValidation } from '@/routes/endpoints'
import { Tippy } from 'vue-tippy'

export default {
  components: { Tippy },

  props: {
    validations: {
      type: Object,
      required: true
    }
  },

  computed: {
    validationSections() {
      return Object.values(this.validations).filter((item) => item.list.length)
    }
  },

  methods: {
    runFix(fixItems) {
      const promises = fixItems.map((params) =>
        SoftValidation.fix(params.global_id, params)
      )

      Promise.all(promises).then((responses) => {
        const softValidations = responses.map((r) => r.body.soft_validations)
        const notFixed = []
          .concat(...softValidations)
          .filter((validation) => validation.fixed === 'fix_error')

        if (notFixed.length) {
          TW.workbench.alert.create(
            notFixed.map((f) => f.failure_message).join('; '),
            'error'
          )
        } else {
          location.reload()
        }
      })
    },

    getFixPresent(list) {
      return list
        .map((item) => ({
          global_id: item.instance.global_id,
          only_methods: item.soft_validations
            .filter((v) => v.fixable)
            .map((item) => item.soft_validation_method)
        }))
        .filter((item) => item.only_methods.length)
    }
  }
}
</script>
<style lang="scss" scope>
.soft-validation-box.validation-warning {
  border-left: 4px solid #ff8c00;
}
.soft-validation-box {
  background-color: #fff9f9;
  .body {
    padding: 12px;
  }
  .header {
    padding-left: 12px;
    padding-right: 12px;
  }
  ul {
    margin: 0px;
    padding: 0px;
  }
  li {
    margin-top: 12px;
  }
  li:first-letter {
    text-transform: capitalize;
  }
  hr {
    height: 1px;
    color: #f5f5f5;
    background: #f5f5f5;
    font-size: 0;
    margin: 15px;
    border: 0;
  }
}
</style>