github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/server/frontend/bv/src/pages/espace_perso/components/paiements/DetailsAide.vue (about)

     1  <template>
     2    <b-modal
     3      :title="title"
     4      :visible="show"
     5      @change="v => $emit('change', v)"
     6      hide-footer
     7      size="lg"
     8    >
     9      <b-form
    10        novalidate
    11        v-if="show && innerAide !== null"
    12        :validated="validated"
    13        ref="form"
    14      >
    15        <b-form-row>
    16          <b-col>
    17            <b-form-group
    18              label="Participant concerné"
    19              invalid-feedback="Une aide doit être liée à un participant."
    20            >
    21              <b-select
    22                required
    23                :options="optionsParticipants"
    24                v-model="innerAide.id_participant_crypted"
    25              >
    26              </b-select>
    27            </b-form-group>
    28          </b-col>
    29        </b-form-row>
    30        <b-form-row>
    31          <b-col>
    32            <b-form-group
    33              label="Organisme"
    34              invalid-feedback="Merci de préciser l'origine de l'aide."
    35            >
    36              <b-select
    37                required
    38                :options="optionsStructures"
    39                v-model="innerAide.id_structure_crypted"
    40              >
    41              </b-select>
    42            </b-form-group>
    43          </b-col>
    44          <b-col>
    45            <b-form-group
    46              label="Montant"
    47              invalid-feedback="Merci de préciser la valeur de l'aide."
    48            >
    49              <b-form-input
    50                placeholder="€"
    51                type="number"
    52                min="0"
    53                step="0.01"
    54                v-model.number="innerAide.valeur"
    55              ></b-form-input>
    56            </b-form-group>
    57          </b-col>
    58        </b-form-row>
    59        <b-form-row class="form-row ml-3 mb-2">
    60          <b-col class="align-self-center">
    61            <b-form-checkbox v-model="innerAide.par_jour">
    62              Montant par jour
    63            </b-form-checkbox>
    64          </b-col>
    65          <b-col>
    66            <transition name="fade" mode="in-out">
    67              <b-form-group
    68                label="Limite sur le nombre de jours"
    69                v-if="innerAide.par_jour"
    70              >
    71                <b-form-input
    72                  placeholder="jours"
    73                  required
    74                  type="number"
    75                  min="1"
    76                  v-model.number="innerAide.nb_jours_max"
    77                ></b-form-input>
    78              </b-form-group>
    79            </transition>
    80          </b-col>
    81        </b-form-row>
    82        <form-file
    83          v-if="mode == 'create'"
    84          title="Pièce justificative"
    85          invalidFeedback="Merci d'ajouter une pièce justificative."
    86          :showValidation="validated"
    87          hideBtnUpload
    88          ref="file"
    89        ></form-file>
    90        <btn
    91          block
    92          variant="success"
    93          class="mt-2"
    94          label="Valider"
    95          @click="valide"
    96        ></btn>
    97      </b-form>
    98    </b-modal>
    99  </template>
   100  
   101  <script lang="ts">
   102  import Vue from "vue";
   103  import Component from "vue-class-component";
   104  import FormFile from "../../../../shared/FormFile.vue";
   105  import Btn from "../../../../shared/Btn.vue";
   106  import { C } from "../../logic/controller";
   107  import {
   108    Aide,
   109    ChampsAideEditables,
   110    PublicDocument
   111  } from "@/shared/logic/types";
   112  import { Watch } from "vue-property-decorator";
   113  import { ValidEvent, scrollToError } from "../../../../shared/utils";
   114  
   115  export type ModeEdit = "create" | "edit";
   116  
   117  const DetailsAideProps = Vue.extend({
   118    props: {
   119      mode: String as () => ModeEdit,
   120      show: Boolean,
   121      aide: Object as () => ChampsAideEditables | null
   122    },
   123    model: {
   124      prop: "show",
   125      event: "change"
   126    }
   127  });
   128  
   129  interface Option {
   130    text: string;
   131  }
   132  
   133  function sortByText(a: Option, b: Option) {
   134    return a.text < b.text ? -1 : 1;
   135  }
   136  
   137  @Component({
   138    components: { FormFile, Btn }
   139  })
   140  export default class DetailsAide extends DetailsAideProps {
   141    innerAide = this.duplique();
   142  
   143    validated = false;
   144  
   145    $refs!: {
   146      file: FormFile;
   147      form: HTMLFormElement;
   148    };
   149  
   150    private duplique(): ChampsAideEditables | null {
   151      return JSON.parse(JSON.stringify(this.aide));
   152    }
   153  
   154    @Watch("aide")
   155    onChange() {
   156      this.innerAide = this.duplique();
   157    }
   158  
   159    get title() {
   160      if (this.mode == "create") {
   161        return "Ajouter une aide extérieure";
   162      }
   163      return "Modifier l'aide";
   164    }
   165  
   166    get optionsParticipants() {
   167      return C.data.participants
   168        .map(part => {
   169          const personne = C.getPersonne(part);
   170          const camp = C.getCamp(part);
   171          return {
   172            value: part.id_crypted,
   173            text:
   174              (personne ? personne.nom_prenom : "") +
   175              " - " +
   176              (camp ? camp.label : "")
   177          };
   178        })
   179        .sort(sortByText);
   180    }
   181  
   182    get optionsStructures() {
   183      if (C.data.finances == null) return [];
   184      return Object.values(C.data.finances.structure_aides || {})
   185        .map(s => {
   186          return { text: s.nom, value: s.id_crypted };
   187        })
   188        .sort(sortByText);
   189    }
   190  
   191    valide(event: ValidEvent) {
   192      this.validated = true;
   193      Vue.nextTick(async () => {
   194        if (this.innerAide == null) return;
   195        const fieldsValides = scrollToError(this.$refs.form);
   196        if (this.mode == "edit" && fieldsValides) {
   197          event.spinning = true;
   198          await C.data.updateAide(this.innerAide);
   199          this.close(event);
   200        } else if (this.mode == "create") {
   201          const doc = this.$refs.file.file;
   202          const docValide = this.$refs.file.isFileInvalid == null;
   203          if (fieldsValides && docValide && doc != null) {
   204            event.spinning = true;
   205            await C.data.ajouteAide(this.innerAide, doc);
   206            this.close(event);
   207          }
   208        }
   209      });
   210    }
   211  
   212    private close(event: ValidEvent) {
   213      event.spinning = false;
   214      this.$emit("change", false); // ask to close the dialog
   215    }
   216  }
   217  </script>
   218  
   219  <style scoped></style>