HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/buyercall/buyercall/assets/vue/widgets/EmailTemplates/components/EditForm.vue
<template>
  <div class="height-set">
    <div class="spinner-main">
      <Loader :loading="loadingSelectedTemplate || imageCapturing"> </Loader>
    </div>
    <div class="row" v-if="!loadingSelectedTemplate">
      <div class="col-lg-12">
        <div class="card">
          <div class="card-body">
            <h4 class="card-title mb-4">Create New Template</h4>
            <b-form @submit.prevent="formSubmit">
              <div class="row">
                <div class="col-md-12">
                  <b-form-group class="mb-3" label="Title" label-for="title">
                    <b-form-input
                      id="title"
                      type="text"
                      placeholder="Title"
                      v-model="form.title"
                      name="title"
                      :class="{
                        'is-invalid': submitted && v$.form.title.$error,
                      }"
                    ></b-form-input>
                    <div
                      v-if="submitted && v$.form.title.$error"
                      class="invalid-feedback"
                    >
                      <span>This value is required.</span>
                    </div>
                  </b-form-group>
                </div>
              </div>
              <div class="row">
                <div class="col-md-12">
                  <b-form-group class="mb-3" label="Description" label-for="description">
                    <b-form-textarea
                      id="description"
                      rows="3"
                      placeholder="Enter description"
                      v-model="form.description"
                      name="title"
                      :class="{
                        'is-invalid': submitted && v$.form.description.$error,
                      }"
                    ></b-form-textarea>
                    <div
                      v-if="submitted && v$.form.description.$error"
                      class="invalid-feedback"
                    >
                      <span>This value is required.</span>
                    </div>
                  </b-form-group>
                </div>
              </div>
              <div class="row">
                <div class="col-md-12">
                  <b-form-group class="mb-3" label="Subject" label-for="subject">
                    <b-form-input
                      id="subject"
                      type="text"
                      placeholder="Subject"
                      v-model="form.subject"
                      name="subject"
                      :class="{
                        'is-invalid': submitted && v$.form.subject.$error,
                      }"
                    ></b-form-input>
                    <div
                      v-if="submitted && v$.form.subject.$error"
                      class="invalid-feedback"
                    >
                      <span>This value is required.</span>
                    </div>
                  </b-form-group>
                </div>
              </div>
              <div class="row">
                <div class="col-md-12">
                  <div class="d-flex">
                    <button
                      type="button"
                      class="btn btn-success ms-auto mb-2"
                      @click="showDynamicFieldModal = true"
                    >
                      Add Dynamic Field
                    </button>
                  </div>
                  <h5 class="font-size-14 mb-1">Choose type of editor</h5>
                  <b-form-group class="mb-3 radio-group">
                    <b-form-radio
                      v-model="form.isPlainEmail"
                      class="form-check-right"
                      :value="false"
                      plain
                      style="margin-right: 10px"
                      >Wysiwyg Editor</b-form-radio
                    >
                    <b-form-radio
                      v-model="form.isPlainEmail"
                      class="form-check-right"
                      :value="true"
                      plain
                      style="margin-right: 10px"
                      >Plain</b-form-radio
                    >
                  </b-form-group>
                  <b-form-group class="mb-3" label="Content" label-for="content">
                    <template v-if="form.isPlainEmail === true">
                      <textarea
                        v-model="form.plainEmailContent"
                        class="form-control"
                        placeholder="Your message..."
                        rows="3"
                      ></textarea>
                      <p
                        :class="{
                          'is-invalid': submitted && v$.form.plainEmailContent.$error,
                        }"
                      ></p>
                      <div
                        v-if="submitted && v$.form.plainEmailContent.$error"
                        class="invalid-feedback"
                      >
                        <span>This value is required.</span>
                      </div>
                    </template>
                    <template v-else>
                      <ckeditor
                        :editor="editor"
                        v-model="form.editorData"
                        :config="editorConfig"
                      ></ckeditor>
                      <p
                        :class="{
                          'is-invalid': submitted && v$.form.editorData.$error,
                        }"
                      ></p>
                      <div
                        v-if="submitted && v$.form.editorData.$error"
                        class="invalid-feedback"
                      >
                        <span>This value is required.</span>
                      </div>
                    </template>
                  </b-form-group>
                </div>
              </div>
              <div>
                <b-button variant="primary" type="submit">
                  <i
                    class="bx bx-loader bx-spin font-size-16 align-middle me-2"
                    v-if="loading"
                  ></i>
                  Save</b-button
                >
                <b-button
                  style="margin-left: 10px"
                  variant="light"
                  v-if="this.form.isPlainEmail === false"
                  @click="showPreview = !showPreview"
                  >Show Preview</b-button
                >
              </div>
            </b-form>
          </div>
        </div>
      </div>
      <b-modal
        v-model="showPreview"
        title="Preview Email template"
        hide-footer
        id="source-modal"
        size="xl"
      >
        <preview-email
          v-if="showPreview"
          :bodyText="getemalPreviewData()"
        ></preview-email>
      </b-modal>
      <b-modal
        v-model="showDynamicFieldModal"
        title="Add Dynamic Field"
        hide-footer
        id="workflow-modal"
      >
        <form @submit.prevent="handleSubmit">
          <div class="row">
            <div class="col-12">
              <label for="fields">Fields</label>
              <multiselect
                v-model="dfForm.field"
                :options="dynamicFieldoptions"
                :multiple="false"
                label="label"
                :class="{
                  'is-invalid': dfFormSubmitted && v$.dfForm.field.$error,
                }"
              ></multiselect>
              <div
                v-if="dfFormSubmitted && v$.dfForm.field.$error"
                class="invalid-feedback"
              >
                <span>This value is required.</span>
              </div>
            </div>
          </div>
          <div class="text-end mt-3">
            <b-button variant="light" @click="showDynamicFieldModal = false"
              >Close</b-button
            >
            <b-button type="submit" variant="success" class="ms-1">Add Field</b-button>
          </div>
        </form>
      </b-modal>
    </div>
    <div ref="capture" :style="{}" v-html="htmlData"></div>
    <!-- <template v-if="renderImageUrl">
      <img
        class="rounded-circle header-profile-user avatar-lg"
        alt="200x200"
        :src="renderImageUrl"
        data-holder-rendered="true"
      />
    </template> -->
  </div>
</template>
<script>
import Multiselect from "vue-multiselect";
//import { required, requiredIf } from "vuelidate/lib/validators";
import { useVuelidate } from "@vuelidate/core";
import {
  required,
  email,
  minLength,
  maxLength,
  sameAs,
  helpers,
  requiredIf,
} from "@vuelidate/validators";

import * as _ from "lodash";
import { formvalidationMessages } from "../../../utils/util";
// import Editor from 'ckeditor5-custom-build/build/ckeditor';
import CKEditor from "@ckeditor/ckeditor5-vue";
import ClassicEditor from "@ckeditor/ckeditor5-build-classic";

import PreviewEmail from "./PreviewEmail.vue";
import Loader from "../../../components/Loader/loader.vue";
import EmailTemplateService from "../../../service/emailTemplatesService";
import domtoimage from "dom-to-image-more";
import { templateFields } from "../constants";
import {
  BForm,
  BFormGroup,
  BFormInput,
  BFormTextarea,
  BFormRadioGroup,
  BFormRadio,
  BButton,
  BModal,
} from "bootstrap-vue-next";

export default {
  setup() {
    const v$ = useVuelidate({
      form: {
        title: { required },
        description: { required },
        subject: { required },
        plainEmailContent: { required },
        editorData: { required },
      },
      dfForm: {
        field: { required },
      },
    });

    return { v$ }; // Ensure to return an object with the 'v$' property
  },

  validations: {
    form: {
      title: { required },
      description: { required },
      subject: { required },
      editorData: {
        required: requiredIf(function () {
          if (this.form.isPlainEmail) {
            return false;
          }
          return true;
        }),
      },
      plainEmailContent: {
        required: requiredIf(function () {
          if (!this.form.isPlainEmail) {
            return false;
          }
          return true;
        }),
      },
    },
    dfForm: {
      field: { required },
    },
  },
  props: {
    loading: {
      type: Boolean,
      required: true,
    },
    AddUser: {
      type: Boolean,
      required: true,
    },
    selectedTemplateId: {},
  },
  mounted() {
    if (this.selectedTemplateId) {
      this.getTemplateById(this.selectedTemplateId);
    }
  },
  data() {
    return {
      htmlData: null,
      imageCapturing: false,
      testImage: null,
      loadingSelectedTemplate: false,
      editorConfig: {
        fontSize: {
          options: ["tiny", "default", "big", 9, 11, 13, 17, 19, 21],
        },
      },
      showPreview: false,
      dynamicFieldoptions: templateFields,
      showDynamicFieldModal: false,
      formvalidationMessages,
      form: {
        title: null,
        description: null,
        subject: null,
        editorData: "<p>Content of the editor.</p>",
        isPlainEmail: false,
        plainEmailContent: "",
      },
      previewImage: null,
      dfForm: {
        field: null,
      },
      submitted: false,
      dfFormSubmitted: false,
      editor: ClassicEditor,
    };
  },

  methods: {
    clearfield() {
      this.form.title = null;
      (this.form.description = null),
        (this.form.subject = null),
        (this.form.editorData = "<p>Content of the editor.</p>"),
        (this.form.isPlainEmail = false),
        (this.form.plainEmailContent = "");
    },
    async getTemplateById(id) {
      this.loadingSelectedTemplate = true;
      const {
        data: { data, message, success },
      } = await EmailTemplateService.getEmailtemplatebyid(id);
      if (!success) {
        this.emit("errorMessage", message);
      } else {
        this.form.title = data.title;
        this.form.description = data.description;
        this.form.subject = data.subject;
        this.form.editorData = data.isPlainEmail ? "" : data.content;
        this.form.plainEmailContent = !data.isPlainEmail ? "" : data.content;
        this.form.isPlainEmail = data.isPlainEmail;
      }
      this.loadingSelectedTemplate = false;
    },
    handleSubmit() {
      this.dfFormSubmitted = true;
      this.v$?.dfForm.$touch();
      if (this.v$?.dfForm.$invalid) {
        return;
      }
      this.showDynamicFieldModal = false;
      if (this.form.isPlainEmail) {
        this.form.plainEmailContent += this.dfForm.field.value;
      } else {
        const tasgAppendinline = ["</p>", "</span>", "</h1>"];
        const htmlTagsInContent = this.form.editorData.match(
          /<((?=!\-\-)!\-\-[\s\S]*\-\-|((?=\?)\?[\s\S]*\?|((?=\/)\/[^.\-\d][^\/\]'"[!#$%&()*+,;<=>?@^`{|}~ ]*|[^.\-\d][^\/\]'"[!#$%&()*+,;<=>?@^`{|}~ ]*(?:\s[^.\-\d][^\/\]'"[!#$%&()*+,;<=>?@^`{|}~ ]*(?:=(?:"[^"]*"|'[^']*'|[^'"<\s]*))?)*)\s?\/?))>/g
        );
        const lastElem = htmlTagsInContent[htmlTagsInContent.length - 1];
        const tagAppendElement = _.find(tasgAppendinline, (e) => e === lastElem);
        if (!this.dfForm.field.blockLevel && tagAppendElement) {
          let data = this.form.editorData;
          data = data.substr(0, data.length - tagAppendElement.length);
          data += this.dfForm.field.value + tagAppendElement;
          this.form.editorData = data;
        } else {
          this.form.editorData += this.dfForm.field.value;
        }
      }
      this.dfForm.field = null;
      this.dfFormSubmitted = false;
    },
    formSubmit() {
      this.submitted = true;
      this.v$?.form.$touch();
      if (this.v$.form.$invalid) {
        return;
      }
      this.imageCapturing = true;
      this.htmlData = this.form.editorData;
    },
    getemalPreviewData() {
      if (this.form.editorData.length === 0) {
        return "";
      }
      let content = this.form.editorData;
      _.forEach(this.dynamicFieldoptions, (e) => {
        content = content.replace(e.value, e.dafaultPreviewData);
      });
      return content;
    },
  },
  computed: {
    renderImageUrl() {
      if (this.previewImage == null) {
        return null;
      }
      const image =
        typeof this.previewImage === "object"
          ? URL.createObjectURL(this.previewImage)
          : this.previewImage;
      return image;
    },
  },
  components: {
    Multiselect,
    PreviewEmail,
    Loader,
    BForm,
    BFormGroup,
    BFormInput,
    BFormTextarea,
    BFormRadioGroup,
    BFormRadio,
    BButton,
    BModal,
    ckeditor: CKEditor.component,
  },
  watch: {
    AddUser: {
      immediate: true,
      handler(newVal) {
        if (newVal) {
          this.clearfield();
        }
      },
    },
    htmlData(v) {
      if (v) {
        const capture = this.$refs.capture;
        domtoimage.toBlob(capture).then((blob) => {
          this.imageCapturing = false;
          this.htmlData = null;
          this.previewImage = new File([blob], "my_image.png", {
            type: "image/png",
            lastModified: new Date().getTime(),
          });
          this.$emit("formSubmit", {
            postData: this.form,
            file: this.previewImage,
          });
          // const formData = new FormData();
          // formData.append(
          //   'data',
          //   JSON.stringify({
          //     ...this.form,
          //   }),
          // );
          // formData.append('file', this.previewImage);
          // this.$emit('formSubmit', formData);
        });
      }
    },
  },
};
</script>