petra-tool / frontend / src / components / Label.vue
Label.vue
Raw
<template>
  <v-dialog
    v-model="dialog"
    persistent
    max-width="1200"
    overlay-color="white"
    content-class="rounded-xl"
    scrollable
  >
    <template v-slot:activator="{ on, attrs }">
      <v-chip
        class="mb-1 body-2"
        dark
        :color="hashColor()"
        label
        :outlined="labelFilter.name !== label.name && !!labelFilter.name"
        @click="filterBoard"
        close-icon="mdi-pencil-outline"
        :close="tasks.length === 0"
        @click:close="dialog = true"
        :disabled="finished"
        style="min-width: 230px"
      >
        <v-icon left small v-if="labelFilter.name === label.name || !labelFilter.name">mdi-check-circle</v-icon>
        <v-icon left small v-else>mdi-checkbox-blank-circle-outline</v-icon>
        {{
          `${(label.name.length > 30) ? label.name.substring(0, 30) + '...' : label.name} ${tasks.length > 0 ? '&nbsp;(' + tasks.length + ')' : ''}`
        }}
      </v-chip>
    </template>

    <v-card>
      <v-card-title class="accent white--text pt-10 pb-4 text-h5 pl-9">
        Edit Labels
      </v-card-title>
      <v-card-text>
        <v-container fluid>
          <v-form ref="form" v-model="form.valid" lazy-validation>
            <v-row no-gutters>
              <v-col cols="12" class="text--primary body-2 my-5">
                You can edit and delete your labels until a task is assigned to it.
              </v-col>
            </v-row>

            <v-row no-gutters>
              <v-col cols="12">
                <div class="text-h5 text--primary mb-3">Label</div>
                <v-text-field
                  label="Edit the Label Name..."
                  v-model="form.name"
                  outlined
                  :required="!label.finish"
                  :disabled="label.finish"
                  counter maxlength="64"
                  :rules="[value => !!value || 'Label is required.']"
                ></v-text-field>
              </v-col>
            </v-row>
          </v-form>

          <v-row no-gutters>
            <v-col cols="12">
              <v-card class="red" dark>
                <v-card-text>

                  <div class="text-h5 white--text">Danger Zone</div>
                  <div class="white--text body-2 mb-3">
                    In the "Danger Zone" you can delete a label that is not relevant anymore. Please be aware that this action cannot be reversed.
                  </div>
                  <v-btn outlined dark @click="dialogDelete = true" min-width="150">Delete Label</v-btn>

                  <v-dialog
                    v-model="dialogDelete"
                    max-width="500px"
                  >
                    <dialog-alert v-on:on-cancel="dialogDelete = false" v-on:on-continue="removeLabel">
                      <template v-slot:title>Delete Label</template>
                      <template v-slot:text>
                        Are you sure? This can't be undone!
                      </template>
                    </dialog-alert>
                  </v-dialog>
                </v-card-text>
              </v-card>

            </v-col>
          </v-row>
        </v-container>

      </v-card-text>
      <v-card-actions class="ma-7">
        <v-btn
          text
          @click="onClose"
        >
          Cancel
        </v-btn>
        <v-spacer></v-spacer>
        <v-btn
          color="primary"
          depressed
          min-width="150"
          :loading="loading"
          @click="onSubmit"
        >
          Save
        </v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

<script>
import DialogAlert from "@/components/DialogAlert";

export default {
  name: "Label",
  components: {DialogAlert},
  props: ['label', 'tasks', 'labelFilter', 'finished'],
  data: () => ({
    dialog: false,
    loading: false,
    dialogDelete: false,
    loadingDelete: false,

    form: {
      valid: true,
      name: '',
    },
  }),
  computed: {
    // ...mapGetters('site', ['getLabelFilter']),
  },
  methods: {
    onSubmit() {
      if (this.$refs.form.validate()) {
        this.loading = true
        this.$http.put('/board/label', {
          id: this.label.id,
          name: this.form.name,
        }).then(() => {
          this.$store.dispatch('site/updateLabel', {
            id: this.label.id,
            cycle_id: this.label.cycle_id,
            name: this.form.name,
          })
          this.$snackbar.showMessage({
            content: 'Renaming label successful!'
          })
          this.dialog = false
        }).catch(() => {
          this.$snackbar.showMessage({
            content: 'Something went wrong, please try again!', color: 'warning'
          })
        }).finally(() => (this.loading = false))
      }
    },
    onClose() {
      this.dialog = false
      this.$refs.form.resetValidation()
      this.fillForm()
    },
    removeLabel() {
      this.loadingDelete = true
      this.$http.delete('/board/label', {
        data: {
          id: this.label.id,
        }
      }).then(() => {
        this.$store.dispatch('site/deleteLabel', {
          id: this.label.id,
        })
        this.$snackbar.showMessage({
          content: 'Label deleted successfully!'
        })
      }).catch(() => {
        this.$snackbar.showMessage({
          content: 'Something went wrong, please try again!', color: 'warning'
        })
      })
      this.loadingDelete = false
    },
    fillForm() {
      this.form.name = this.label.name
    },
    filterBoard() {
      if (this.tasks.length !== 0) {
        // toggle filter
        if (this.labelFilter.name === this.label.name) {
          // remove filter
          this.$store.dispatch('site/removeFilter')
        } else {
          // set filter
          this.$store.dispatch('site/filterBoardByLabel', this.label)
        }
      } else {
        this.dialog = true;
      }
    },
    hashColor() {
      switch (this.label.id % 4) {
        case 0:
          return 'secondary'
        case 1:
          return 'error'
        case 2:
          return 'info'
        case 3:
          return 'primary'
      }
    }
  },
  created() {
    this.fillForm()
  }
}
</script>

<style scoped>

</style>