v4.1.9: Начальная производственная версия

- Полный backend на Hono + TypeScript
- SQLite база данных с 38 записями
- 3 пользователя: admin, aknaproff, kasutaja
- Модальное окно reportModal (4 шага)
- Docker конфигурация для Synology ARM
- Все миграции (0001-0017)
- Frontend: vanilla HTML/JS (original.html)
This commit is contained in:
Deploy Bot
2025-12-31 12:00:00 +02:00
parent afea76b053
commit 4898f5ec7f
381 changed files with 9105 additions and 65477 deletions

View File

@@ -1,208 +0,0 @@
<template>
<section class="mt-3">
<div class="custom-control custom-checkbox">
<input type="checkbox"
class="custom-control-input"
id="is_enabled_acelle_mail"
v-model="acelleMail.is_enable"
value="1">
<label class="custom-control-label" for="is_enabled_acelle_mail">
{{trans('messages.enable')}}
</label>
</div>
<template
v-if="acelleMail.is_enable">
<div class="text-left text-muted text-center">
<small>
<i class="fa fa-info-circle"></i>
{{trans('messages.not_in_downloaded_code')}}
</small>
<br/>
</div>
<div class="form-group row">
<label for="api_token" class="col-sm-3 col-form-label">
{{trans('messages.api_token')}}:
<span class="error">*</span>
<i class="fa fa-info-circle"
data-html="true"
data-toggle="tooltip"
:title="trans('messages.api_token_n_list_tooltip', {name:acelle_mail_name})">
</i>
</label>
<div class="col-sm-9">
<div class="input-group">
<input type="text" class="form-control"
id="api_token"
:placeholder="trans('messages.api_token')"
name="acelleMail.api_token"
:required="acelleMail.is_enable"
v-model="acelleMail.api_token">
<div class="input-group-append">
<button type="button" class="btn btn-primary"
@click="getAcelleListIds"
:disabled="loading">
{{trans('messages.get_list')}}
<i class="fas fa-spinner fa-pulse fa-spin ml-1" v-if="loading"></i>
</button>
</div>
</div>
<small class="form-text text-danger"
v-if="error_msg">
{{error_msg}}
</small>
</div>
</div>
</template>
<template v-if="!_.isEmpty(campaign_list)">
<div class="form-group row">
<label for="site_key" class="col-sm-3 col-form-label">
{{acelle_mail_name}} {{trans('messages.list_id')}}:
<span class="error">*</span>
</label>
<div class="col-sm-9">
<select class="form-control"
:required="acelleMail.is_enable"
name="acelleMail.list_id"
v-model="acelleMail.list_id"
@change="getListFields">
<option value="" v-text="trans('messages.please_select')"></option>
<template
v-for="campaign in campaign_list">
<option
:value="campaign.uid"
v-text="campaign.name">
</option>
</template>
</select>
<small class="form-text text-danger"
v-if="field_error_msg">
{{field_error_msg}}
</small>
</div>
</div>
</template>
<template
v-if="!_.isEmpty(acelleMail.campaign_fields)">
<div class="form-group row"
v-for="(campaign_field, index) in acelleMail.campaign_fields">
<label class="col-sm-3 col-form-label">
{{campaign_field.label}}
<span class="error" v-if="campaign_field.required">*</span>
<p class="mt-0 p-0">
<small>
<code>
({{campaign_field.type}})
</code>
</small>
</p>
</label>
<div class="col-sm-9">
<select class="form-control"
:required="campaign_field.required"
:name="campaign_field.key"
v-model="campaign_field.param_field_name">
<option value="" v-text="trans('messages.please_select')"></option>
<template
v-for="element in selected_elements">
<option
:value="element.name"
v-if="!_.includes(['heading', 'hr', 'html_text', 'file_upload', 'signature', 'iframe', 'youtube', 'pdf', 'countdown'], element.type)"
v-text="element.label">
</option>
</template>
</select>
</div>
</div>
</template>
</section>
</template>
<script>
export default {
props: ['acelleMail', 'selected_elements'],
data() {
return {
acelle_mail_name: APP.ACELLE_MAIL_NAME,
campaign_list: [],
error_msg: '',
field_error_msg: '',
loading: false,
}
},
created() {
const self = this;
if (!_.isEmpty(self.acelleMail.api_token)) {
self.getAcelleListIds();
self.getListFields();
}
},
methods:{
getAcelleListIds() {
const self = this;
if (self.acelleMail.api_token) {
self.loading = true;
axios
.get('/get-acelle-list-ids',{
params: {
token: self.acelleMail.api_token
}
})
.then(function(response) {
self.loading = false;
if (response.data.success) {
self.campaign_list = response.data.list;
self.error_msg = _.isEmpty(response.data.list) ? self.trans('messages.no_acelle_list_please_create') : '';
} else {
self.error_msg = response.data.msg;
}
})
.catch(function(error) {
console.log(error);
});
} else{
self.error_msg = self.trans('messages.api_token_required');
}
},
getListFields() {
const self = this;
if (self.acelleMail.api_token && self.acelleMail.list_id) {
self.field_error_msg = self.trans('messages.retriving_fields');
axios
.get('/get-acelle-list-info',{
params: {
token: self.acelleMail.api_token,
list_id: self.acelleMail.list_id,
}
})
.then(function(response) {
if (response.data.success) {
self.field_error_msg = '';
self.filterExistingFields(response.data.fields);
} else {
self.field_error_msg = response.data.msg;
}
})
.catch(function(error) {
console.log(error);
});
}
},
filterExistingFields(fields) {
const self = this;
if (self.acelleMail.campaign_fields) {
fields.forEach(function(field){
self.acelleMail.campaign_fields.forEach(function(campField){
if(
(field.key == campField.key) &&
!_.isUndefined(campField.param_field_name))
{
field['param_field_name'] = campField.param_field_name;
return false;
}
});
});
}
self.acelleMail.campaign_fields = fields;
}
}
}
</script>

View File

@@ -1,34 +0,0 @@
<template>
<div class="mt-3">
<p>
{{trans('messages.additional_js_css_help_text')}}
</p>
<br>
<div class="form-group row">
<label class="col-sm-2">
{{trans('messages.javascript')}}
<i class="fa fa-info-circle" data-html="true" data-toggle="tooltip" :title="trans('messages.additional_js_help')"></i>
</label>
<div class="col-sm-10">
<textarea class="form-control" rows="4" :placeholder="trans('messages.additional_js')" v-model="additionalData.js">
</textarea>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2">
{{trans('messages.css')}}
<i class="fa fa-info-circle" data-html="true" data-toggle="tooltip" :title="trans('messages.additional_css_help')"></i>
</label>
<div class="col-sm-10">
<textarea class="form-control" rows="4" :placeholder="trans('messages.additional_css')"
v-model="additionalData.css">
</textarea>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['additionalData'],
}
</script>

View File

@@ -1,52 +0,0 @@
<template>
<!-- Modal -->
<div class="modal fade" id="AskUserChoice" tabindex="-1" role="dialog" aria-labelledby="AskUserChoiceModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h6 class="modal-title" id="AskUserChoiceModalLabel">
<span v-html="trans('messages.what_do_u_want_next')"></span>
</h6>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-4">
<button type="button" class="btn btn-primary btn-sm"@click="getUserChoice('edit')">
<i class="fa fa-edit"></i>
{{trans('messages.continue_editing')}}
</button>
</div>
<div class="col-md-4">
<button type="button" class="btn btn-info btn-sm"@click="getUserChoice('preview')">
<i class="fa fa-eye"></i>
{{trans('messages.preview_the_form')}}
</button>
</div>
<div class="col-md-4">
<button type="button" class="btn btn-success btn-sm" @click="getUserChoice('home')">
<i class="fas fa-home"></i>
{{trans('messages.go_to_home')}}
</button>
</div>
</div>
</div>
<div class="modal-footer"></div>
</div>
</div>
</div>
<!-- /modal -->
</template>
<script>
export default {
methods: {
getUserChoice(choice){
this.$eventBus.$emit('callRedirectUser', choice);
}
}
}
</script>

View File

@@ -1,248 +0,0 @@
<template>
<div class="container-fluid mt-3 mb-85">
<div class="text-left text-muted pl-3">
<i class="fas fa-info-circle mr-1"></i>
<small>{{trans('messages.not_in_downloaded_code')}}</small><br/>
</div>
<template v-for="(conditionalField, index) in conditionalFields">
<div v-if="index != 0">
<h4 class="text-center">
<strong>
{{trans('messages.or').toUpperCase()}}
</strong>
</h4>
</div>
<div class="card m-3 card-outline card-success">
<div class="card-body">
<div class="row">
<div class="col-md-5">
<div class="input-group">
<select class="form-control" v-model="conditionalField.action">
<option :value="''">
{{trans('messages.show_hide')}}
</option>
<option :value="'show'">
{{trans('messages.show')}}
</option>
<option :value="'hide'">
{{trans('messages.hide')}}
</option>
</select>
<select class="form-control" v-model="conditionalField.element">
<option :value="''">
{{trans('messages.choose_element')}}
</option>
<option v-for="(element, index) in selectedElements"
:key="index"
:value="element.name"
v-if="!_.includes(['hr', 'page_break'], element.type)">
{{element.label}}
({{element.name}})
</option>
</select>
</div>
</div>
<div class="col-md-6">
<template v-for="(conditions, conditionIndex) in conditionalField.conditions">
<div class="row">
<div class="col-md-5">
<div class="input-group mb-2">
<div class="input-group-prepend">
<span class="input-group-text" v-if="conditionIndex == 0">
{{trans('messages.when')}}
</span>
<select v-if="conditionIndex != 0"
class="form-control input-group-text" v-model="conditions.logical_operator">
<option value="AND">
{{trans('messages.and')}}
</option>
<option value="OR">
{{trans('messages.or')}}
</option>
</select>
</div>
<select class="form-control" v-model="conditions.condition"
@change="toggleConditionValueField(conditions.condition)">
<option :value="''">
{{trans('messages.condition')}}
</option>
<option v-for="(element, index) in selectedElements"
:key="index"
:value="element.name"
v-if="!_.includes(['heading', 'hr', 'html_text', 'file_upload', 'text_editor', 'signature', 'page_break', 'iframe', 'youtube', 'pdf', 'countdown'], element.type)">
{{element.label}}
</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="input-group mb-2" v-if="_.includes(['text', 'textarea', 'range', 'calendar', 'rating'], conditions.element_type)">
<div class="input-group-prepend">
<select class="form-control input-group-text" v-model="conditions.operator">
<option value="==">
{{trans('messages.equal_to')}}
</option>
<option value="!=">
{{trans('messages.not_equal_to')}}
</option>
<option value="empty">
{{trans('messages.empty')}}
</option>
<option value="not_empty">
{{trans('messages.not_empty')}}
</option>
</select>
</div>
<input type="text" class="form-control"
:placeholder="trans('messages.write_conditional_value')"
v-model="conditions.value" :disabled="_.includes(['empty', 'not_empty'], conditions.operator)">
</div>
<div class="input-group mb-2" v-if="_.includes(['dropdown', 'radio', 'checkbox'], conditions.element_type)">
<div class="input-group-prepend">
<select class="form-control input-group-text" v-model="conditions.operator">
<option value="==">
{{trans('messages.equal_to')}}
</option>
<option value="!=">
{{trans('messages.not_equal_to')}}
</option>
<option value="empty" v-if="!_.includes(['radio', 'checkbox'], conditions.element_type)">
{{trans('messages.empty')}}
</option>
<option value="not_empty" v-if="!_.includes(['radio', 'checkbox'], conditions.element_type)">
{{trans('messages.not_empty')}}
</option>
</select>
</div>
<select class="form-control" v-model="conditions.value" :disabled="_.includes(['empty', 'not_empty'], conditions.operator)">
<option :value="''">
{{trans('messages.choose_value')}}
</option>
<option v-for="(option, index) in optionsForConditionalValue(selectedElements[conditions.element_index])"
:value="option"
:key="index"
>
{{option}}
</option>
</select>
</div>
<div class="input-group mb-2" v-if="_.includes(['terms_and_condition'], conditions.element_type)">
<div class="input-group-prepend">
<select class="form-control input-group-text" v-model="conditions.operator">
<option value="==">
{{trans('messages.equal_to')}}
</option>
</select>
</div>
<select class="form-control" v-model="conditions.value">
<option :value="''">
{{trans('messages.choose_value')}}
</option>
<option value="true">
{{trans('messages.checked')}}
</option>
<option value="false">
{{trans('messages.unchecked')}}
</option>
</select>
</div>
<div class="input-group mb-2" v-if="_.includes(['switch'], conditions.element_type)">
<div class="input-group-prepend">
<select class="form-control input-group-text" v-model="conditions.operator">
<option value="==">
{{trans('messages.equal_to')}}
</option>
<option value="!=">
{{trans('messages.not_equal_to')}}
</option>
</select>
</div>
<select class="form-control" v-model="conditions.value">
<option :value="''">
{{trans('messages.choose_value')}}
</option>
<option value="1">
{{trans('messages.on')}}
</option>
<option value="0">
{{trans('messages.off')}}
</option>
</select>
</div>
</div>
<div class="col-md-1">
<button type="button" class="btn btn-primary btn-sm" @click="addCondition(index)" v-if="conditionIndex == 0" data-toggle="tooltip" data-placement="top" :title="trans('messages.add_condition')">
<i class="fas fa-plus-circle"></i>
</button>
<button type="button" class="btn btn-danger btn-sm" @click="removeCondition(index,conditionIndex)" v-if="conditionIndex != 0">
<i class="fas fa-trash-alt"></i>
</button>
</div>
</div>
</template>
</div>
<div class="col-md-1">
<button type="button" class="btn btn-danger btn-sm" @click="removeConditionalField(index)">
<i class="fas fa-trash-alt"></i>
</button>
</div>
</div>
</div>
</div>
</template>
<button type="button" class="btn btn-info float-right mt-3" @click="addMoreConditionalField" data-toggle="tooltip" data-placement="top" :title="trans('messages.add_conditional_field')">
<i class="fas fa-plus-circle"></i>
{{trans('messages.add')}}
</button>
</div>
</template>
<script>
export default {
props: ['conditionalFields', 'selectedElements'],
methods:{
addCondition(index) {
var condition_field = {'condition':'', 'value':"", 'element_type' : 'text', 'element_index' : '', 'operator' : '==', 'logical_operator' : 'AND'};
this.conditionalFields[index].conditions.push(condition_field);
},
addMoreConditionalField() {
var conditional_field = {'action':'', 'element':'', 'conditions':[{'condition':'', 'value':"", 'element_type' : 'text', 'element_index' : '', 'operator' : '==', 'logical_operator' : 'AND'}]};
this.conditionalFields.push(conditional_field);
},
removeCondition(index, conditionalIndex) {
if (conditionalIndex != 0) {
this.conditionalFields[index].conditions.splice(conditionalIndex, 1);
}
},
removeConditionalField(index) {
this.conditionalFields.splice(index, 1);
},
toggleConditionValueField(choosenCondition) {
var schema = this.selectedElements;
_.forEach(this.conditionalFields, function(conditionalField){
_.forEach(conditionalField.conditions, function(conditionalElement) {
if (conditionalElement.condition === choosenCondition) {
var index = schema.findIndex(element => element.name === choosenCondition);
conditionalElement.element_type = _.isUndefined(schema[index]) ? 'text' : schema[index].type;
conditionalElement.element_index = index;
}
});
});
},
optionsForConditionalValue(element) {
if(!_.isUndefined(element)) {
let options = element.options;
return (options || "").split("\n");
}
return "";
}
}
}
</script>

View File

@@ -1,617 +0,0 @@
<template>
<div>
<form id="create_form">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form_builder_tab" role="tab" aria-controls="form" aria-selected="true">
<i class="fas fa-align-justify"></i> {{ trans('messages.form') }}
</a>
</li>
<li class="nav-item" role="presentation" id="tour_step_4">
<a class="nav-link" id="field_conditions-tab" data-toggle="tab" href="#field_conditions_tab" role="tab" aria-controls="field_conditions" aria-selected="false">
<i class="fas fa-wrench"></i> {{trans('messages.field_conditions')}}
</a>
</li>
<li class="nav-item" role="presentation" id="tour_step_5">
<a class="nav-link" id="email-tab" data-toggle="tab" href="#email_settings_tab" role="tab" aria-controls="email" aria-selected="false">
<i class="fas fa-envelope"></i> {{trans('messages.email')}}
</a>
</li>
<li class="nav-item" role="presentation" id="tour_step_6">
<a class="nav-link" id="form-settings-tab" data-toggle="tab" href="#form_settings_tab" role="tab" aria-controls="form-settings" aria-selected="false">
<i class="fas fa-cogs"></i> {{trans('messages.settings')}}
</a>
</li>
<li class="nav-item" role="presentation" id="tour_step_7">
<a class="nav-link" id="mailchimp-tab" data-toggle="tab" href="#mailchimp_tab" role="tab" aria-controls="mailchimp" aria-selected="false">
<i class="fab fa-mailchimp fa-lg"></i> {{trans('messages.mailchimp')}}
</a>
</li>
<li class="nav-item" role="presentation" id="acelle_mail_tour"
v-if="is_acelle_mail_enabled">
<a class="nav-link" id="acelle-mail-tab" data-toggle="tab" href="#acelle_mail_tab" role="tab">
<i class="fas fa-mail-bulk"></i>
{{acelle_mail_name}}
</a>
</li>
<li class="nav-item" role="presentation" id="webhook_tour">
<a class="nav-link" id="webhook-tab" data-toggle="tab" href="#webhook_tab" role="tab">
<i class="far fa-paper-plane"></i>
{{trans('messages.webhook')}}
</a>
</li>
<li class="nav-item" role="presentation" id="tour_step_8">
<a class="nav-link" id="js-css-tab" data-toggle="tab" href="#custom_js_css_tab" role="tab" aria-controls="js-css" aria-selected="false">
<i class="fas fa-file-code"></i> {{trans('messages.additional_js_css')}}
</a>
</li>
<li class="nav-item" role="presentation">
<button type="button" class="btn btn-xs bg-gradient-danger app_tour_play_btn" @click="getAppTour">
<i class="far fa-play-circle"></i>
{{trans('messages.app_tour')}}
</button>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="form_builder_tab" role="tabpanel" aria-labelledby="form-tab">
<form-tab :selected_elements="selected_elements" :settings="settings" :form="form" :placeholder_img="placeholderImg" :form_custom_attributes="form_custom_attributes"></form-tab>
</div>
<div class="tab-pane fade" id="field_conditions_tab" role="tabpanel" aria-labelledby="field_conditions-tab">
<condtionalFields
:conditional-fields="conditional_fields"
:selected-elements="selected_elements"
></condtionalFields>
</div>
<div class="tab-pane fade" id="email_settings_tab" role="tabpanel" aria-labelledby="email-tab">
<email-tab
:emailConfig="emailConfig"
:selected_elements="selected_elements"
:settings="settings">
</email-tab>
</div>
<div class="tab-pane fade" id="form_settings_tab" role="tabpanel" aria-labelledby="form-settings-tab">
<settings-tab
:settings="settings"
:selected_elements="selected_elements">
</settings-tab>
</div>
<div class="tab-pane fade" id="mailchimp_tab" role="tabpanel" aria-labelledby="mailchimp-tab">
<mailchimp
:details="mailchimp_details"
:selected_elements="selected_elements">
</mailchimp>
</div>
<div class="tab-pane fade" id="acelle_mail_tab" role="tabpanel" aria-labelledby="acelle-mail-tab"
v-if="is_acelle_mail_enabled">
<acelle-mail
:acelle-mail="acelle_mail_info"
:selected_elements="selected_elements">
</acelle-mail>
</div>
<div class="tab-pane fade" id="webhook_tab" role="tabpanel" aria-labelledby="webhook-tab">
<webhook
:webhook-info="webhook_info"/>
</div>
<div class="tab-pane fade" id="custom_js_css_tab" role="tabpanel" aria-labelledby="js-css-tab">
<additional-js-css :additional-data="additionalData">
</additional-js-css>
</div>
</div>
<!-- submit button -->
<div v-if="selected_elements.length">
<hr class="mt-5">
<div id="tour_step_9">
<button type="submit" class="btn btn-success btn-lg float-right ladda-form-save-btn mb-2" name="submit_type" value="0">
{{trans('messages.save_as_form')}}
</button>
<button type="submit" class="btn btn-secondary btn-lg float-right ladda-template-save-btn mb-2 mr-1" name="submit_type" value="1" v-if="disabled_save_temp_btn">
{{trans('messages.save_as_template')}}
</button>
</div>
</div>
<AskUserChoice id="userChoiceModal">
</AskUserChoice>
</form>
</div>
</template>
<script>
import formTab from "./FormTab";
import emailTab from "./EmailTab";
import settingsTab from "./SettingsTab";
import additionalJsCss from "./AdditionalJsCss";
import mailchimp from "./Mailchimp";
import condtionalFields from "./ConditionalField";
import AskUserChoice from "./AskUserChoiceAfterSave";
import AcelleMail from "./AcelleMail";
import Webhook from "./Webhook/Webhook";
export default {
props: ['formData', 'placeholderImg', 'saveTemplate'],
components: {
formTab,
emailTab,
settingsTab,
mailchimp,
additionalJsCss,
condtionalFields,
AskUserChoice,
AcelleMail,
Webhook
},
data() {
return {
selected_elements: [],
form_parsed: [],
form:[],
emailConfig: {},
settings:{},
dashboard:'',
additionalData: {},
mailchimp_details: {},
conditional_fields:[],
form_scheduling: {
closed_msg:'The form has been closed now!',
start_date_time:'',
end_date_time:'',
is_enabled: false
},
form_submision_ref: {
is_enabled: false,
prefix: '',
suffix: '',
start_no: '1',
min_digit: '4'
},
form_theme: 'default',
responseData:[],
is_enabled_draft_submit: 0,
form_custom_attributes : [],
disabled_save_temp_btn:null,
password_protection:{
is_enabled:false,
password: ''
},
pdf_design:{
header: `<h1 style="margin-top: 0px; margin-bottom: 0.5rem; font-family: &quot;Source Sans Pro&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, &quot;Helvetica Neue&quot;, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;; line-height: 1.2; color: rgb(0, 0, 0); font-size: 2.5rem; text-align: center;"><span style="color: rgb(33, 37, 41); font-size: 12.8px; text-align: left; background-color: rgb(244, 246, 249);"><span style="font-size: 24px;"><span style="font-weight: bolder;">{form_name}</span></span><sub style="font-size: 9.6px;"><span style="font-size: 12px;">{submission_date}</span></sub></span></h1>`
},
spread_to_col:{
enable: false,
column: 2
},
acelle_mail_info: {},
is_acelle_mail_enabled: APP.ACELLE_MAIL_ENABLED,
acelle_mail_name: APP.ACELLE_MAIL_NAME,
webhook_info: {},
popover_help_text:{
enable: false,
content: ''
}
};
},
created() {
this.form_parsed = JSON.parse(this.formData);
this.form.name = this.form_parsed.name;
this.form.slug = this.form_parsed.slug;
this.form.description = this.form_parsed.description;
this.form.is_template = this.form_parsed.is_template;
this.disabled_save_temp_btn = JSON.parse(this.saveTemplate);
if (this.form_parsed.schema === null) {
this.emailConfig = this.getData('email_config');
this.settings = this.getData('settings');
this.additionalData = {js:'', css:''};
this.conditional_fields = this.getData('conditional_fields');
} else {
this.selected_elements = this.form_parsed.schema.form;
this.emailConfig = this.form_parsed.schema.emailConfig;
this.settings = this.form_parsed.schema.settings;
this.additionalData = _.isNull(this.form_parsed.schema.additional_js_css) ? {js:'', css:''} : this.form_parsed.schema.additional_js_css;
this.mailchimp_details = _.isNull(this.form_parsed.mailchimp_details) ? this.getData('mailchimp') : this.form_parsed.mailchimp_details;
this.acelle_mail_info = _.isEmpty(this.form_parsed.acelle_mail_info) ? this.getData('acelle_mail') : this.form_parsed.acelle_mail_info;
this.conditional_fields = _.isUndefined(this.form_parsed.schema.conditional_fields) ? this.getData('conditional_fields') : this.form_parsed.schema.conditional_fields;
this.form_custom_attributes = _.isUndefined(this.form_parsed.schema.form_attributes) ? this.form_custom_attributes : this.form_parsed.schema.form_attributes;
}
this.webhook_info = this.form_parsed?.webhook_info || this.getData('webhook_info');
this.getNewlyAddedPropertyForExistingForm();
this.$eventBus.$on('callRedirectUser', (data) => {
$("#userChoiceModal").modal("hide");
setTimeout(() => {
this.redirectUsersAccordingToResponse(data);
}, 1000);
});
},
beforeDestroy() {
this.$eventBus.$off('callRedirectUser');
},
mounted(){
const self = this;
$('form#create_form').validate({
ignore: ".note-editor *",
submitHandler: function(form, e) {
var field_names = [];
if (self.selected_elements.length > 0) {
for (let index = 0; index < self.selected_elements.length; index++) {
self.selected_elements[index].extras.showConfigurator = false;
if (_.isEmpty(self.selected_elements[index].name)) {
toastr.error(self.trans('messages.field_dont_have_name_property', {
input: self.selected_elements[index].label,
}));
return false;
} else if (/\s/.test(self.selected_elements[index].name)) {
toastr.error(self.trans('messages.field_contain_space', {
input: self.selected_elements[index].label,
}));
return false;
} else if (_.includes(field_names, self.selected_elements[index].name)) {
toastr.error(self.trans('messages.field_contain_duplicate_field_name', {
input: self.selected_elements[index].label,
}));
field_names = [];
return false;
}else if (!_.includes(field_names, self.selected_elements[index].name)) {
field_names.push(self.selected_elements[index].name);
}
}
}
let data = _.pick(self.form, ['name', 'description', 'slug']);
data.form = self.selected_elements;
data.email_config = self.emailConfig;
data.settings = self.settings;
data.js_css = self.additionalData;
data.mailchimp_details = self.mailchimp_details;
data.acelle_mail_info = self.acelle_mail_info;
data.conditional_fields = self.conditional_fields;
data.is_template = $("input[name='submit_type']").val();
data.form_attributes = self.form_custom_attributes;
data.contains_page_break = _.some(self.selected_elements, {type: "page_break"});
data.webhook_info = self.webhook_info;
//get ladda btn based on submit type
if (data.is_template === '1') {
var ladda = Ladda.create(document.querySelector('.ladda-template-save-btn'));
} else {
var ladda = Ladda.create(document.querySelector('.ladda-form-save-btn'));
}
if ($('form#create_form').valid()) {
//disable both btn and start ladda
$("button.ladda-form-save-btn, button.ladda-template-save-btn").attr('disabled', 'disabled');
ladda.start();
axios
.put('/forms/'+self.form_parsed.id, data)
.then(function(response) {
//remove disable from both btn and stop ladda
$("button.ladda-form-save-btn, button.ladda-template-save-btn").removeAttr("disabled");
ladda.stop();
if (response.data.success == true) {
self.responseData = response.data;
$("#userChoiceModal").modal("show");
} else {
toastr.error(response.data.msg);
}
})
.catch(function(error) {
console.log(error);
});
}
}
});
//if mpfg_tour not finished call getAppTour
if (_.isNull(localStorage.getItem("mpfg_tour"))) {
localStorage.setItem("mpfg_tour", 'finished');
this.getAppTour();
}
},
methods: {
getData(type) {
if (type == 'email_config') {
var email = {
email: {
enable: '',
from: '',
to: '',
reply_to_email: '',
cc:'',
bcc:'',
subject: '',
body:'',
attach_pdf: false
},
auto_response: {
from:'',
to:'',
subject: '',
body: '',
is_enable: false,
attach_pdf: false
},
smtp: {
host:'',
port:'',
from_address:'',
from_name:'',
encryption:'',
username:'',
password:'',
use_system_smtp:1
}
};
return email;
} else if (type == 'settings') {
var setting = {
recaptcha:{
is_enable:0,
site_key:'',
secret_key:''
},
color:{
label:'#000000',
error_msg:'#a94442',
required_asterisk_color:'#a94442',
background:'#ffffff',
image_path:'',
page_color:'#f4f6f9'
},
notification:{
post_submit_action:'same_page',
failed_msg:'Something went wrong, please try again.',
success_msg:'Your submission has been received.',
redirect_url:'',
position: 'toast-top-right'
},
submit:{
text:'Submit',
loading_text:'Submitting...',
btn_alignment:'float-right',
btn_size:'',
btn_color:'btn-primary',
btn_style: 'default',
btn_icon: 'none',
icon_position:'left'
},
form_data:{
col_visible:[],
btn_enabled:[
'view', 'delete'
]
},
background:{
bg_type:'bg_color'
},
form_scheduling:this.form_scheduling,
form_submision_ref: this.form_submision_ref,
theme: this.form_theme,
is_enabled_draft_submit: this.is_enabled_draft_submit,
layout: 'classic',
password_protection: this.password_protection,
pdf_design: this.pdf_design,
is_qr_code_enabled: false,
qr_code_data_format: 'string',
is_ref_num_bar_code_enabled: false,
is_ref_num_qr_code_enabled: false
};
return setting;
} else if(type == 'mailchimp'){
return {
is_enable: false,
api_key: '',
list_id: '',
email_field: '',
name_field: ''
};
} else if(type == 'acelle_mail'){
return {
is_enable: false,
api_token: '',
list_id: '',
campaign_fields: []
};
} else if (type == 'conditional_fields') {
var conditional_fields = [
{
'action':'',
'element':'',
'conditions': [
{
'condition':'',
'value':"",
'element_type' : 'text',
'element_index' : '',
'operator' : '==',
'logical_operator' : 'AND'
}
]
}
];
return conditional_fields;
} else if (type == 'webhook_info') {
return {
is_enable: false,
url: '',
secret_key: ''
};
}
},
getNewlyAddedPropertyForExistingForm() {
const self = this;
_.forEach(self.selected_elements, function(element) {
if (_.isUndefined(element.conditional_class)) {
element.conditional_class = '';
}
if (_.isUndefined(element.col)) {
element.col = 'col-md-12';
}
if (_.isUndefined(element.popover_help_text)) {
element['popover_help_text'] = _.clone(self.popover_help_text);
}
//if spread to col option is undefined for element set to default
if (
_.includes(['radio', 'checkbox'], element.type) &&
_.isUndefined(element.spread_to_col)
) {
element.spread_to_col = self.spread_to_col;
}
if (
_.includes(['text'], element.type) &&
_.includes(['text', 'email', 'number'], element.subtype) &&
_.isUndefined(element.allowed_input)
) {
element.allowed_input = {
values:'',
error_msg: 'This value is not allowed.'
};
}
});
if (_.isUndefined(self.settings.form_scheduling)) {
self.settings.form_scheduling = self.form_scheduling;
}
if (_.isUndefined(self.settings.form_submision_ref)) {
self.settings.form_submision_ref = self.form_submision_ref;
}
if (_.isUndefined(self.settings.theme)) {
self.settings.theme = self.form_theme;
}
if (_.isUndefined(self.settings.is_qr_code_enabled)) {
Vue.set(self.settings, 'is_qr_code_enabled', false);
}
if (
_.isUndefined(self.settings.is_ref_num_bar_code_enabled) ||
_.isUndefined(self.settings.is_ref_num_qr_code_enabled)
) {
Vue.set(self.settings, 'is_ref_num_bar_code_enabled', false);
Vue.set(self.settings, 'is_ref_num_qr_code_enabled', false);
}
if (_.isUndefined(self.settings.qr_code_data_format)) {
Vue.set(self.settings, 'qr_code_data_format', 'string');
}
if (_.isUndefined(self.settings.is_enabled_draft_submit)) {
self.settings.is_enabled_draft_submit = self.is_enabled_draft_submit;
}
if (_.isUndefined(self.settings.notification.position)) {
self.settings.notification.position = 'toast-top-right';
}
if (_.isUndefined(self.settings.submit.btn_style)) {
Vue.set(self.settings.submit, 'btn_style', 'default');
}
if (_.isUndefined(self.settings.submit.btn_icon)) {
Vue.set(self.settings.submit, 'btn_icon', 'none');
}
if (_.isUndefined(self.settings.submit.icon_position)) {
Vue.set(self.settings.submit, 'icon_position', 'left');
}
if (_.isUndefined(self.settings.color.page_color)) {
Vue.set(self.settings.color, 'page_color', '#f4f6f9');
}
if (_.isUndefined(self.settings.password_protection)) {
self.settings.password_protection = self.password_protection;
}
if (_.isUndefined(self.settings.pdf_design)) {
self.settings.pdf_design = self.pdf_design;
}
},
redirectUsersAccordingToResponse(choice) {
if (choice == 'home') {
window.location = this.responseData.redirect;
} else if (choice == 'preview') {
window.open(this.responseData.preview, this.responseData.form_name);
}
},
getAppTour() {
if (!$('#appTab a[href="#form-generator"]').hasClass('active')) {
$('#appTab a[href="#form-generator"]').tab('show');
}
const self = this;
var intro = introJs();
intro.setOptions({
steps: [
{
intro : self.trans('messages.welcome_tour_msg')
},
{
element: document.querySelectorAll('#tour_step_1')[0],
intro: self.trans('messages.tour_step_1_intro'),
position: 'right',
scrollTo: 'tooltip'
},
{
element: '#tour_step_2',
intro: self.trans('messages.tour_step_2_intro'),
position: 'right',
scrollTo: 'tooltip'
},
{
element: '#tour_step_3',
intro: self.trans('messages.tour_step_3_intro'),
position: 'bottom',
scrollTo: 'tooltip'
},
{
element: '#tour_step_4',
intro: self.trans('messages.tour_step_4_intro'),
scrollTo: 'tooltip'
},
{
element: '#tour_step_5',
intro: self.trans('messages.tour_step_5_intro'),
scrollTo: 'tooltip'
},
{
element: '#tour_step_6',
intro: self.trans('messages.tour_step_6_intro'),
scrollTo: 'tooltip'
},
{
element: '#tour_step_7',
intro: self.trans('messages.tour_step_7_intro'),
scrollTo: 'tooltip'
},
{
element: '#tour_step_8',
intro: self.trans('messages.tour_step_8_intro'),
scrollTo: 'tooltip'
},
{
element: '#tour_step_9',
intro: self.trans('messages.tour_step_9_intro'),
scrollTo: 'tooltip'
}
]
});
intro.start();
}
}
}
</script>

View File

@@ -1,212 +0,0 @@
<template>
<!-- modal -->
<div class="modal fade" id="elementDetailsModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalCenterTitle">
{{trans('messages.element_details')}}
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<b>{{trans('messages.input')}}:</b><br>
<div v-html="getTooltips('text')"></div><hr>
<b>{{trans('messages.textarea')}}:</b><br>
<div v-html="getTooltips('textarea')"></div><hr>
<b>{{trans('messages.dropdown')}}:</b><br>
<div v-html="getTooltips('dropdown')"></div><hr>
<b>{{trans('messages.radio')}}:</b><br>
<div v-html="getTooltips('radio')"></div><hr>
<b>{{trans('messages.checkbox')}}:</b><br>
<div v-html="getTooltips('checkbox')"></div><hr>
<b>{{trans('messages.heading_paragrahp')}}:</b><br>
<div v-html="getTooltips('heading')"></div><hr>
<b>{{trans('messages.range')}}:</b><br>
<div v-html="getTooltips('range')"></div><hr>
<b>{{trans('messages.datetime')}}:</b><br>
<div v-html="getTooltips('calendar')"></div><hr>
<b>{{trans('messages.file_upload')}}:</b><br>
<div v-html="getTooltips('file_upload')"></div><hr>
<b>{{trans('messages.text_editor')}}:</b><br>
<div v-html="getTooltips('text_editor')"></div> <hr>
<b>{{trans('messages.terms_condition')}}:</b><br>
<div v-html="getTooltips('terms_and_condition')"></div><hr>
<b>{{trans('messages.horizontal_line')}}:</b><br>
<div v-html="getTooltips('hr')"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">
{{trans('messages.close')}}
</button>
</div>
</div>
</div>
</div>
<!-- /modal -->
</template>
<script>
export default {
methods:{
getTooltips(element_type) {
var validation_rules = validationRules;
var rules = [];
var title = '';
_.forEach(validation_rules, function(validation) {
if (_.includes(validation.applies_to, element_type)) {
rules.push(validation.display);
}
});
if (element_type == 'text') {
title = `
<span class="text-success">
<i>Usage:</i>
</span> To enter short information. <br>
<span class="text-success">
<i>Example:</i>
</span> Name, Email, Phone.<br>
<span class="text-success">
<i>Contains:</i>
</span> Is required,
`+ rules.join(', ');
} else if (element_type == 'textarea') {
title = `
<span class="text-success">
<i>Usage:</i>
</span> To enter long information.<br>
<span class="text-success">
<i>Example:</i>
</span> Address, About me, Description.<br>
<span class="text-success">
<i>Contains:</i>
</span> Is required,
`+ rules.join(', ');
} else if (element_type == 'dropdown') {
title = `
<span class="text-success">
<i>Usage:</i>
</span> To select Single or Multiple pre-defined values. <br>
<span class="text-success">
<i>Example:</i>
</span> Hobbies, Model <br>
<span class="text-success">
<i>Contains:</i>
</span> Is required, `+ rules.join(', ');
} else if (element_type == 'radio') {
title = `
<span class="text-success">
<i>Usage:</i>
</span> To select ONE of a limited number of choices <br>
<span class="text-success">
<i>Example:</i>
</span> Gender, True-False <br>
<span class="text-success">
<i>Contains:</i>
</span> Is required.`;
} else if (element_type == 'checkbox') {
title = `
<span class="text-success">
<i>Usage:</i>
</span> select ZERO or MORE options of a limited number of choices <br>
<span class="text-success">
<i>Example:</i>
</span> Hobbies, Qualification <br>
<span class="text-success">
<i>Contains:</i>
</span>Is required, `+ rules.join(', ');
} else if(element_type == 'heading') {
title = `
<span class="text-success">
<i>Usage:</i>
</span> For heading or any type of texts with H1 to H6 & Paragraph tags with your defined color. <br>
<span class="text-success">
<i>Example:</i>
</span> Description & other informations.`;
} else if(element_type == 'range') {
title = `
<span class="text-success">
<i>Usage:</i>
</span> To Select Minimum-maximum range value.<br>
<span class="text-success">
<i>Example:</i>
</span>
Price range`;
} else if(element_type == 'calendar') {
title = `
<span class="text-success">
<i>Usage:</i>
</span> To pick a date and/or time, with your defined format.<br>
<span class="text-success">
<i>Example:</i>
</span> Appointment date <br>
<span class="text-success">
<i>Contains:</i>
</span> Is required.`;
} else if(element_type == 'file_upload') {
title = `
<span class="text-success">
<i>Usage:</i>
</span> To upload file(s) and/or images.<br>
<span class="text-success">
<i>Example:</i>
</span> Documents, Photo <br>
<span class="text-success">
<i>Contains:</i>
</span> Is required.`;
} else if(element_type == 'text_editor') {
title = `
<span class="text-success">
<i>Usage:</i>
</span> To enter long information with the many options to format<br>
<span class="text-success">
<i>Example:</i>
</span>
Description, blogs <br>
<span class="text-success">
<i>Contains:</i>
</span> Is required.`;
} else if (element_type == 'terms_and_condition') {
title = `
<span class="text-success">
<i>Usage:</i>
</span> Rules by which one must agree to abide in order to use a service<br>
<span class="text-success">
<i>Example:</i>
</span>
Privacy Policy<br>
<span class="text-success">
<i>Contains:</i>
</span> Is required.`;
} else if (element_type == 'hr') {
title = `
<span class="text-success">
<i>Usage:</i>
</span> This tag defines a thematic break in an HTML page.<br>
<span class="text-success">
<i>Example:</i>
</span>
a shift of topic<br>
`;
}
return title;
}
}
}
</script>

View File

@@ -1,594 +0,0 @@
<template>
<div class="row mt-3">
<div class="col-md-12">
<div class="accordion" id="accordionEmail">
<div class="card">
<div class="card-header bg-success" id="headingEmailSettings">
<h2 class="mb-0">
<button class="btn btn-link text-white" type="button" data-toggle="collapse"
data-target="#collapseEmail"
aria-expanded="true"
aria-controls="collapseEmail">
{{trans('messages.new_submission_email')}}:
</button>
</h2>
</div>
<div id="collapseEmail"
class="collapse show"
aria-labelledby="headingEmailSettings"
data-parent="#accordionEmail">
<div class="card-body">
<div class="custom-control custom-checkbox">
<input type="checkbox"
class="custom-control-input"
id="enable_submission_email"
v-model="emailConfig.email.enable"
@change="emailToggle()"
value="1">
<label class="custom-control-label" for="enable_submission_email">
{{trans('messages.enable')}}
</label>
</div>
<div v-if="emailConfig.email.enable">
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.from')}}<span class="error">*</span>
</label>
<div class="col-sm-10">
<input type="email"
class="form-control"
:required="emailConfig.email.enable"
:placeholder="trans('messages.from_email')"
name="emailConfig.email.from"
v-model="emailConfig.email.from">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.to')}}<span class="error">*</span></label>
<div class="col-sm-10">
<input type="text"
class="form-control"
:required="emailConfig.email.enable"
name="emailConfig.email.to"
:placeholder="trans('messages.multiple_email_help_text')"
v-model="emailConfig.email.to">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.reply_to_email')}}
</label>
<div class="col-sm-10">
<select class="form-control"
name="reply_to_email"
v-model="emailConfig.email.reply_to_email">
<option value="" v-text="trans('messages.please_select')"></option>
<template
v-for="element in selected_elements">
<option
:value="element.name"
v-if="_.includes(['email'], element.subtype)"
v-text="element.label">
</option>
</template>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.cc')}}
</label>
<div class="col-sm-10">
<input type="text"
class="form-control"
:placeholder="trans('messages.multiple_email_help_text')"
v-model="emailConfig.email.cc">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.bcc')}}
</label>
<div class="col-sm-10">
<input type="text"
class="form-control"
:placeholder="trans('messages.multiple_email_help_text')"
v-model="emailConfig.email.bcc">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.subject')}}
<span class="error">*</span>
</label>
<div class="col-sm-10">
<input type="text"
class="form-control"
:required="emailConfig.email.enable"
name="emailConfig.email.subject"
:placeholder="trans('messages.email_subject')"
v-model="emailConfig.email.subject">
<small class="form-text text-muted">
{{trans('messages.click_to_add_tags')}}:
<button type="button"
class="btn btn-primary btn-sm xs mr-2 mt-2"
v-for="(element, index) in selected_elements"
v-if="!_.includes(['heading','hr', 'html_text', 'signature', 'file_upload', 'page_break', 'iframe', 'youtube', 'pdf', 'countdown'], element.type)"
@click="appendTag(index, 'email_subject')">{{element.label}}</button>
<button type="button"
class="btn btn-primary btn-sm xs mr-2 mt-2"
@click="appendTag(1, 'submission_ref_for_email_subject')">
{{trans('messages.submission_numbering')}}
<i class="fas fa-info-circle" data-toggle="tooltip" data-html="true" :title="trans('messages.works_if_enabled_in_settings')"></i>
</button>
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.body')}}:
<span class="error">*</span></label>
<div class="col-sm-10">
<textarea class="submission_email_body"
rows="5"
:required="emailConfig.email.enable"
name="emailConfig.email.body"
:placeholder="trans('messages.email_body')"
v-model="emailConfig.email.body"></textarea>
<small class="form-text text-muted">
{{trans('messages.click_to_add_tags')}}:
<button type="button"
class="btn btn-primary btn-sm xs mr-2 mt-2"
v-for="(element, index) in selected_elements"
v-if="!_.includes(['heading','hr', 'html_text', 'signature', 'file_upload', 'page_break', 'iframe', 'youtube', 'pdf', 'countdown'], element.type)"
@click="appendTag(index, 'email_body')">{{element.label}}</button>
<button type="button"
class="btn btn-primary btn-sm xs mr-2 mt-2"
@click="appendTag(1, 'submission_ref_for_email_body')">
{{trans('messages.submission_numbering')}}
<i class="fas fa-info-circle" data-toggle="tooltip" data-html="true" :title="trans('messages.works_if_enabled_in_settings')"></i>
</button>
<button type="button"
class="btn btn-primary btn-sm xs mr-2 mt-2"
@click="appendTag(1, 'ref_num_qr_code_for_email_body')">
{{trans('messages.qr_code_for_ref_num')}}
<i class="fas fa-info-circle" data-toggle="tooltip" data-html="true" :title="trans('messages.works_if_enabled_in_settings')"></i>
</button>
<button type="button"
class="btn btn-primary btn-sm xs mr-2 mt-2"
@click="appendTag(1, 'ref_num_bar_code_for_email_body')">
{{trans('messages.bar_code_for_ref_num')}}
<i class="fas fa-info-circle" data-toggle="tooltip" data-html="true" :title="trans('messages.works_if_enabled_in_settings')"></i>
</button>
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.pdf')}}
</label>
<div class="col-sm-10">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="email_attach_pdf" value="1" name="attach_pdf" v-model="emailConfig.email.attach_pdf">
<label class="custom-control-label" for="email_attach_pdf">
{{trans('messages.attach_pdf')}}
</label>
<i class="fas fa-info-circle text-info" data-toggle="tooltip" data-html="true" :title="trans('messages.pdf_of_submitted_data_will_be_attached_to_mail')"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header bg-success" id="headingEmailResponse">
<h2 class="mb-0">
<button class="btn btn-link text-white" type="button" data-toggle="collapse" data-target="#collapseEmailResponse" aria-expanded="true" aria-controls="collapseEmailResponse">
{{trans('messages.auto_response_settings')}}:
</button>
</h2>
</div>
<div id="collapseEmailResponse" class="collapse" aria-labelledby="headingEmailResponse" data-parent="#accordionEmail">
<div class="card-body">
<div class="custom-control custom-checkbox">
<input type="checkbox"
class="custom-control-input"
id="enable_auto_response"
@change="replyToggle()"
v-model="emailConfig.auto_response.is_enable"
value="1">
<label class="custom-control-label" for="enable_auto_response">
{{trans('messages.enable_auto_response')}}
</label>
</div>
<div v-show="emailConfig.auto_response.is_enable">
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.from')}}
<span class="error">*</span>
</label>
<div class="col-sm-10">
<input type="email"
:required="emailConfig.auto_response.is_enable"
class="form-control"
:placeholder="trans('messages.from_email')"
name="emailConfig.auto_response.from"
v-model="emailConfig.auto_response.from">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.to')}}
<span class="error">*</span>
</label>
<div class="col-sm-10">
<select class="form-control"
:required="emailConfig.auto_response.is_enable"
name="emailConfig.auto_response.to"
v-model="emailConfig.auto_response.to">
<option :value="element.name"
v-if="_.includes(['text', 'email'], element.type)"
v-for="element in selected_elements">{{element.label}}</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.subject')}}
<span class="error">*</span>
</label>
<div class="col-sm-10">
<input type="text"
:required="emailConfig.auto_response.is_enable"
name="emailConfig.auto_response.is_enable"
class="form-control"
:placeholder="trans('messages.email_subject')"
v-model="emailConfig.auto_response.subject">
<small class="form-text text-muted">
{{trans('messages.click_to_add_tags')}}:
<button type="button"
class="btn btn-primary btn-sm xs mr-2 mt-2"
v-for="(element, index) in selected_elements"
v-if="!_.includes(['heading','hr', 'html_text', 'signature', 'file_upload', 'page_break', 'iframe', 'youtube', 'pdf', 'countdown'], element.type)"
@click="appendTag(index, 'response_subject')">{{element.label}}</button>
<button type="button"
class="btn btn-primary btn-sm xs mr-2 mt-2"
@click="appendTag(1, 'submission_ref_for_response_subject')">
{{trans('messages.submission_numbering')}}
<i class="fas fa-info-circle" data-toggle="tooltip" data-html="true" :title="trans('messages.works_if_enabled_in_settings')"></i>
</button>
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.body')}}
<span class="error">*</span>
</label>
<div class="col-sm-10">
<textarea
class="autoresponse_email_body"
rows="5"
name="emailConfig.auto_response.body"
:required="emailConfig.auto_response.is_enable"
v-model="emailConfig.auto_response.body"></textarea>
<small class="form-text text-muted">
{{trans('messages.click_to_add_tags')}}:
<button type="button"
class="btn btn-primary btn-sm xs mr-2 mt-2"
v-for="(element, index) in selected_elements"
v-if="!_.includes(['heading','hr', 'html_text', 'signature', 'file_upload', 'page_break', 'iframe', 'youtube', 'pdf', 'countdown'], element.type)"
@click="appendTag(index, 'response_body')">{{element.label}}</button>
<button type="button"
class="btn btn-primary btn-sm xs mr-2 mt-2"
@click="appendTag(1, 'submission_ref_for_response_body')">
{{trans('messages.submission_numbering')}}
<i class="fas fa-info-circle" data-toggle="tooltip" data-html="true" :title="trans('messages.works_if_enabled_in_settings')"></i>
</button>
<button type="button"
class="btn btn-primary btn-sm xs mr-2 mt-2"
@click="appendTag(1, 'ref_num_qr_code_for_response_body')">
{{trans('messages.qr_code_for_ref_num')}}
<i class="fas fa-info-circle" data-toggle="tooltip" data-html="true" :title="trans('messages.works_if_enabled_in_settings')"></i>
</button>
<button type="button"
class="btn btn-primary btn-sm xs mr-2 mt-2"
@click="appendTag(1, 'ref_num_bar_code_for_response_body')">
{{trans('messages.bar_code_for_ref_num')}}
<i class="fas fa-info-circle" data-toggle="tooltip" data-html="true" :title="trans('messages.works_if_enabled_in_settings')"></i>
</button>
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.pdf')}}
</label>
<div class="col-sm-10">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="auto_response_attach_pdf" value="1" name="auto_response_attach_pdf" v-model="emailConfig.auto_response.attach_pdf">
<label class="custom-control-label" for="auto_response_attach_pdf">
{{trans('messages.attach_pdf')}}
</label>
<i class="fas fa-info-circle text-info" data-toggle="tooltip" data-html="true" :title="trans('messages.pdf_of_submitted_data_will_be_attached_to_mail')"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header bg-success" id="headingSMTP">
<h2 class="mb-0">
<button class="btn btn-link text-white" type="button" data-toggle="collapse" data-target="#collapseSMTP" aria-expanded="true" aria-controls="collapseSMTP">
{{trans('messages.smtp_settings')}}:
</button>
</h2>
</div>
<div id="collapseSMTP" class="collapse" aria-labelledby="headingSMTP" data-parent="#accordionEmail">
<div class="card-body">
<div class="custom-control custom-checkbox">
<input type="checkbox"
class="custom-control-input"
id="use_system_smtp"
v-model="emailConfig.smtp.use_system_smtp"
value="1">
<label class="custom-control-label" for="use_system_smtp">
{{trans('messages.use_settings_smtp')}}
</label>
</div>
<div v-show="!emailConfig.smtp.use_system_smtp">
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.host')}}<span class="error">*</span>
</label>
<div class="col-sm-10">
<input type="text"
name="emailConfig.smtp.host"
:required="!emailConfig.smtp.use_system_smtp"
class="form-control"
v-model="emailConfig.smtp.host">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.port')}}
<span class="error">*</span>
</label>
<div class="col-sm-10">
<input type="text"
:required="!emailConfig.smtp.use_system_smtp"
class="form-control"
name="emailConfig.smtp.port"
v-model="emailConfig.smtp.port">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.from_address')}}<span class="error">*</span>
</label>
<div class="col-sm-10">
<input type="email"
:required="!emailConfig.smtp.use_system_smtp"
class="form-control"
name="emailConfig.smtp.from_address"
v-model="emailConfig.smtp.from_address">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.from_name')}}
<span class="error">*</span>
</label>
<div class="col-sm-10">
<input type="text"
:required="!emailConfig.smtp.use_system_smtp"
class="form-control"
name="emailConfig.smtp.from_name"
v-model="emailConfig.smtp.from_name">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.encryption')}}
</label>
<div class="col-sm-10">
<input type="text"
class="form-control"
v-model="emailConfig.smtp.encryption">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{{trans('messages.username')}}<span class="error">*</span>
</label>
<div class="col-sm-10">
<input type="text"
:required="!emailConfig.smtp.use_system_smtp"
class="form-control"
name="emailConfig.smtp.username"
v-model="emailConfig.smtp.username">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">{{trans('messages.password')}}<span class="error">*</span>
</label>
<div class="col-sm-10">
<input type="text"
class="form-control"
:required="!emailConfig.smtp.use_system_smtp"
name="emailConfig.smtp.password"
v-model="emailConfig.smtp.password">
</div>
</div>
<testSmtpDetails :details="emailConfig.smtp"></testSmtpDetails>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import testSmtpDetails from "./TestSmtpDetails";
export default {
props:{
emailConfig: Object,
selected_elements: Array,
settings: Object,
},
components: {
testSmtpDetails
},
created(){
this.emailToggle();
this.replyToggle();
if (_.isUndefined(this.emailConfig.email.reply_to_email)) {
this.emailConfig.email['reply_to_email'] = '';
}
},
computed: {
tags: function () {
return this.selected_elements;
}
},
methods: {
appendTag: function(index, to){
if(to == 'email_subject'){
this.emailConfig.email.subject += ' __' + this.selected_elements[index].name + '__';
} else if(to == 'email_body'){
var content = ' __' + this.selected_elements[index].name + '__';
this.emailConfig.email.body += content;
$('.submission_email_body').summernote('pasteHTML', content);
} else if(to == 'response_subject'){
this.emailConfig.auto_response.subject += ' __' + this.selected_elements[index].name + '__';
} else if(to == 'response_body'){
var content = ' __' + this.selected_elements[index].name + '__';
this.emailConfig.auto_response.body += content;
$('.autoresponse_email_body').summernote('pasteHTML', content);
} else if (to == 'submission_ref_for_email_body') {
var content = ' __' + 'submission_ref' + '__';
this.emailConfig.email.body += content;
$('.submission_email_body').summernote('pasteHTML', content);
} else if(to == 'submission_ref_for_response_body'){
var content = ' __' + 'submission_ref' + '__';
this.emailConfig.auto_response.body += content;
$('.autoresponse_email_body').summernote('pasteHTML', content)
} else if(to == 'submission_ref_for_email_subject'){
this.emailConfig.email.subject += ' __' + 'submission_ref' + '__';
} else if(to == 'submission_ref_for_response_subject'){
this.emailConfig.auto_response.subject += ' __' + 'submission_ref' + '__';
} else if(to == 'ref_num_bar_code_for_response_body'){
let content = ' __' + 'submission_ref_bar_code' + '__';
this.emailConfig.auto_response.body += content;
$('.autoresponse_email_body').summernote('pasteHTML', content);
} else if(to == 'ref_num_qr_code_for_response_body'){
let content = ' __' + 'submission_ref_qr_code' + '__';
this.emailConfig.auto_response.body += content;
$('.autoresponse_email_body').summernote('pasteHTML', content);
} else if(to == 'ref_num_bar_code_for_email_body'){
let content = ' __' + 'submission_ref_bar_code' + '__';
this.emailConfig.email.body += content;
$('.submission_email_body').summernote('pasteHTML', content);
} else if(to == 'ref_num_qr_code_for_email_body'){
let content = ' __' + 'submission_ref_qr_code' + '__';
this.emailConfig.email.body += content;
$('.submission_email_body').summernote('pasteHTML', content);
}
},
emailToggle(){
const self = this;
if(this.emailConfig.email.enable){
setTimeout(function(){
$('.submission_email_body').summernote({
height: 200,
placeholder: self.trans('messages.email_body'),
callbacks: {
onChange: function(contents, editable) {
self.emailConfig.email.body = contents;
}
}
});
}, 200);
}
},
replyToggle(){
const self = this;
if(this.emailConfig.auto_response.is_enable){
setTimeout(function(){
$('.autoresponse_email_body').summernote({
placeholder: self.trans('messages.email_body'),
height: 200,
callbacks: {
onChange: function(contents, editable) {
self.emailConfig.auto_response.body = contents;
}
}
});
}, 200);
}
}
}
}
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -1,806 +0,0 @@
<template>
<div class="form-group" v-if="element.type == 'text'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)">
<label :for="element.name">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<span :style="{'color': settings.color.label}">
{{ element.label }}
</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
<i class="fas fa-info-circle cursor-pointer modal_trigger"
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable"
:data-target="`#${element.name}_modal`"></i>
</label>
<div class="input-group">
<div class="input-group-prepend" v-if="element.prefix_icon && element.prefix_icon !== 'none'">
<span class="input-group-text">
<i :class="'fas ' + element.prefix_icon"></i>
</span>
</div>
<input :type="element.subtype" class="form-control"
:name="element.name"
:placeholder="element.placeholder"
:class="[element.size, element.custom_class, element.conditional_class]"
:required="element.required && applyValidations"
v-bind="getDynamicallyGeneratedAttributeObj(element.validations, element.custom_attributes)"
:id="element.name"
:value="_.get(submitted_data, element.name, '')"
:data-msg-required="element.required_error_msg"
@change="$emit('apply_conditions')">
<div class="input-group-append" v-if="element.suffix_icon && element.suffix_icon !== 'none'">
<span class="input-group-text">
<i :class="'fas ' + element.suffix_icon"></i>
</span>
</div>
</div>
<small class="form-text text-muted" v-if="element.help_text">
{{ element.help_text }}
</small>
<popover-help-text-modal
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable && element.popover_help_text.content"
:element="element"
></popover-help-text-modal>
</div>
<div v-else-if="element.type == 'range'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class, 'mb-4 mt-3']"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)">
<label :for="element.name">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<span :style="{'color': settings.color.label}">
{{ element.label }}
</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
<i class="fas fa-info-circle cursor-pointer modal_trigger"
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable"
:data-target="`#${element.name}_modal`"></i>
</label>
<div class="row">
<div class="col-sm-1">{{ element.min }}</div>
<div class="col-sm-10">
<input type="range" :name="element.name" :required="element.required && applyValidations"
:id="element.name" :min="element.min" :max="element.max" :step="element.step"
:data-orientation="element.data_orientation"
:value="_.get(submitted_data, element.name, '')"
:class="[element.conditional_class]"
v-bind="getCustomAttributes(element.custom_attributes)"
:data-msg-required="element.required_error_msg"
>
</div>
<div class="col-sm-1">{{ element.max }}</div>
</div>
<b>
<output :class="element.name" style="display: block;text-align:center;" :for="element.name">
{{ _.get(submitted_data, element.name, '') }}
</output>
</b>
<small class="form-text text-muted" v-if="element.help_text">
{{ element.help_text }}
</small>
<popover-help-text-modal
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable && element.popover_help_text.content"
:element="element"
></popover-help-text-modal>
</div>
<div class="form-group" v-else-if="element.type == 'calendar'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover()"
@mouseleave="onMouseLeave(element)">
<label :for="element.name">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<span :style="{'color': settings.color.label}">
{{ element.label }}
</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
<i class="fas fa-info-circle cursor-pointer modal_trigger"
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable"
:data-target="`#${element.name}_modal`"></i>
</label>
<div class="input-group date" :id="element.name" data-target-input="nearest">
<div class="input-group-prepend"
:data-target="'#' + element.name"
data-toggle="datetimepicker"
v-if="element.prefix_icon && element.prefix_icon !== 'none'">
<span class="input-group-text">
<i :class="'fas ' + element.prefix_icon"></i>
</span>
</div>
<input type="text"
class="form-control datetimepicker-input"
:data-target="'#' + element.name"
data-toggle="datetimepicker"
:name="element.name"
:id="element.name"
readonly
:class="[element.size, element.custom_class, element.conditional_class]"
:required="element.required && applyValidations"
v-bind="getCustomAttributes(element.custom_attributes)"
:data-msg-required="element.required_error_msg"
:disabled="actionBy === 'user'"
/>
<div class="input-group-append"
:data-target="'#' + element.name"
data-toggle="datetimepicker"
v-if="element.suffix_icon && element.suffix_icon !== 'none'">
<div class="input-group-text">
<i :class="'fas ' + element.suffix_icon"></i>
</div>
</div>
</div>
<small class="form-text text-muted" v-if="element.help_text">
{{ element.help_text }}
</small>
<popover-help-text-modal
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable && element.popover_help_text.content"
:element="element"
></popover-help-text-modal>
</div>
<div class="form-group" v-else-if="element.type == 'textarea'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)">
<label :for="element.name">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<span :style="{'color': settings.color.label}">
{{ element.label }}
</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
<i class="fas fa-info-circle cursor-pointer modal_trigger"
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable"
:data-target="`#${element.name}_modal`"></i>
</label>
<div class="input-group">
<div class="input-group-prepend" v-if="element.prefix_icon && element.prefix_icon !== 'none'">
<span class="input-group-text">
<i :class="'fas ' + element.prefix_icon"></i>
</span>
</div>
<textarea class="form-control"
:value="_.get(submitted_data, element.name, '')"
:rows="element.rows"
:name="element.name"
:id="element.name"
:cols="element.columns"
:placeholder="element.placeholder"
:class="[element.custom_class, element.conditional_class]"
:required="element.required && applyValidations"
v-bind="getDynamicallyGeneratedAttributeObj(element.validations, element.custom_attributes)"
@change="$emit('apply_conditions')"
:data-msg-required="element.required_error_msg"
></textarea>
<div class="input-group-append" v-if="element.suffix_icon && element.suffix_icon !== 'none'">
<span class="input-group-text">
<i :class="'fas ' + element.suffix_icon"></i>
</span>
</div>
</div>
<small class="form-text text-muted" v-if="element.help_text">
{{ element.help_text }}
</small>
<popover-help-text-modal
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable && element.popover_help_text.content"
:element="element"
></popover-help-text-modal>
</div>
<div class="form-group"
v-else-if="element.type == 'radio' || element.type == 'checkbox'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)">
<label :for="element.name">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<span :style="{'color': settings.color.label}">{{ element.label }}</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
<i class="fas fa-info-circle cursor-pointer modal_trigger"
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable"
:data-target="`#${element.name}_modal`"></i>
</label>
<div class="row">
<div :class="[spreadColumnForElement(element)]"
v-for="(option, index) in element.options.split('\n')">
<div class="custom-control" :class="[element.type == 'radio' ? 'custom-radio' : 'custom-checkbox']">
<input class="custom-control-input"
:type="element.type"
:value="option"
v-bind="getDynamicallyGeneratedAttributeObj(element.validations, element.custom_attributes)"
:required="element.required && applyValidations"
:name="(element.type == 'checkbox' ? element.name + '[]' : element.name)"
:id="element.name +'_'+ index"
@change="$emit('apply_conditions')"
:checked="_.includes(_.get(submitted_data, element.name, ''), option)"
:class="[element.conditional_class]"
:data-msg-required="element.required_error_msg"
>
<label class="custom-control-label" :for="element.name +'_'+ index">
{{ option }}
</label>
</div>
</div>
</div>
<small class="form-text text-muted" v-if="element.help_text">
{{ element.help_text }}
</small>
<popover-help-text-modal
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable && element.popover_help_text.content"
:element="element"
></popover-help-text-modal>
</div>
<div class="form-group" v-else-if="element.type == 'dropdown'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)">
<label :for="element.name">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<span :style="{'color': settings.color.label}">{{ element.label }}</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
<i class="fas fa-info-circle cursor-pointer modal_trigger"
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable"
:data-target="`#${element.name}_modal`"></i>
</label>
<div class="input-group">
<div class="input-group-prepend" v-if="element.prefix_icon && element.prefix_icon !== 'none'">
<span class="input-group-text">
<i :class="'fas ' + element.prefix_icon"></i>
</span>
</div>
<select class="custom-select" :class="[element.size, element.custom_class, element.conditional_class]"
:required="element.required && applyValidations"
v-bind="getDynamicallyGeneratedAttributeObj(element.validations, element.custom_attributes)"
:id="element.name" :multiple="element.multiselect"
:name="(element.multiselect == true ? element.name + '[]' : element.name)"
@change="$emit('apply_conditions')"
:data-msg-required="element.required_error_msg"
>
<option v-for="option in element.options.split('\n')"
:selected="_.includes(_.get(submitted_data, element.name, ''), option)"
>
{{ option }}
</option>
</select>
<div class="input-group-append" v-if="element.suffix_icon && element.suffix_icon !== 'none'">
<span class="input-group-text">
<i :class="'fas ' + element.suffix_icon"></i>
</span>
</div>
</div>
<small class="form-text text-muted" v-if="element.help_text">
{{ element.help_text }}
</small>
<popover-help-text-modal
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable && element.popover_help_text.content"
:element="element"
></popover-help-text-modal>
</div>
<div v-else-if="element.type == 'heading'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<div
v-html="'<' + element.tag + ' style=color:' + element.text_color + '>' + element.content + '</' + element.tag + '>'"
:class="[element.custom_class]">
</div>
</div>
<div v-else-if="element.type == 'file_upload'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)" class="mb-3">
<label :for="element.name">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<span :style="{'color': settings.color.label}">{{ element.label }}</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
<i class="fas fa-info-circle cursor-pointer modal_trigger"
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable"
:data-target="`#${element.name}_modal`"></i>
</label>
<div class="dropzone" :class="[element.custom_class]" :id="element.name"
v-bind="getCustomAttributes(element.custom_attributes)">
</div>
<input type="hidden" :name="element.name + '[]'" :id="element.name"
:value="_.get(submitted_data, element.name, '')" :required="element.required && applyValidations"
:class="element.conditional_class" :data-msg-required="element.required_error_msg">
<small class="form-text text-muted" v-if="element.help_text">
{{ element.help_text }}
</small>
<popover-help-text-modal
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable && element.popover_help_text.content"
:element="element"
></popover-help-text-modal>
</div>
<div v-else-if="element.type == 'text_editor'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)">
<label :for="element.name">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<span :style="{'color': settings.color.label}">{{ element.label }}</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
<i class="fas fa-info-circle cursor-pointer modal_trigger"
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable"
:data-target="`#${element.name}_modal`"></i>
</label>
<textarea :id="element.name" :name="element.name"
:required="element.required && applyValidations" class="form-control summer_note"
:class="[element.conditional_class]"
:value="_.get(submitted_data, element.name, '')"
v-bind="getCustomAttributes(element.custom_attributes)"
:data-msg-required="element.required_error_msg"
>
</textarea>
<small class="form-text text-muted" v-if="element.help_text">
{{ element.help_text }}
</small>
<popover-help-text-modal
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable && element.popover_help_text.content"
:element="element"
></popover-help-text-modal>
</div>
<div v-else-if="element.type == 'terms_and_condition'" class="pt-3 mb-3"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)">
<i class="fas fa-sort handle pointer font_icon_size" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" :name="element.name" id="terms_and_condition"
:required="element.required && applyValidations"
:class="[element.custom_class, element.conditional_class]" @change="$emit('apply_conditions')"
:checked="_.includes(['on'], _.get(submitted_data, element.name, ''))"
v-bind="getCustomAttributes(element.custom_attributes)"
:data-msg-required="element.required_error_msg"
>
<label class="custom-control-label" for="terms_and_condition">
<a :href="element.link" target="_blank" v-if="element.link">
{{ element.label }}
</a>
<span v-else>{{ element.label }}</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
<i class="fas fa-info-circle cursor-pointer modal_trigger"
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable"
:data-target="`#${element.name}_modal`"></i>
</label>
</div>
<popover-help-text-modal
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable && element.popover_help_text.content"
:element="element"
></popover-help-text-modal>
</div>
<div v-else-if="element.type == 'hr'" :class="[element.extras.showConfigurator ? 'active_element' : '']"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)">
<i class="fas fa-sort handle pointer font_icon_size" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<hr :style="{'margin-top' : element.padding_top + 'px', 'margin-bottom' : element.padding_bottom + 'px', 'border-top' : element.border_size + 'px ' + element.border_type + element.border_color, 'margin-left' : element.horizontal_space + 'px', 'margin-right' : element.horizontal_space + 'px'}">
</div>
<div v-else-if="element.type == 'html_text'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<span v-html="element.html_text" :class="element.custom_class"></span>
</div>
<div class="form-group" v-else-if="element.type == 'rating'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)">
<label :for="element.name">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<span :style="{'color': settings.color.label}">{{ element.label }}</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
<i class="fas fa-info-circle cursor-pointer modal_trigger"
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable"
:data-target="`#${element.name}_modal`"></i>
</label>
<input :id="element.name" :name="element.name"
class="star_rating" :data-stars="element.stars_to_display"
:data-min="element.min_rating" :data-max="element.max_rating"
:data-step="element.increment" :dir="element.direction"
:data-size="element.size"
type="hidden"
:required="element.required && applyValidations"
:data-msg-required="element.required_error_msg"
:class="element.conditional_class"
:value="_.get(submitted_data, element.name, '')"
>
<popover-help-text-modal
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable && element.popover_help_text.content"
:element="element"
></popover-help-text-modal>
</div>
<div v-else-if="element.type == 'switch'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover()" @mouseleave="onMouseLeave(element)">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<div class="form-group">
<span class="switch" :class="element.size">
<input type="checkbox" class="switch" :name="element.name" :id="element.name"
:required="element.required && applyValidations" @change="$emit('apply_conditions')"
:class="element.conditional_class"
:checked="_.includes(['on'], _.get(submitted_data, element.name, ''))"
v-bind="getCustomAttributes(element.custom_attributes)"
:data-msg-required="element.required_error_msg"
>
<label :for="element.name">
<span :style="{'color': settings.color.label}" class="ml-2">
{{ element.label }}
</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
<i class="fas fa-info-circle cursor-pointer modal_trigger"
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable"
:data-target="`#${element.name}_modal`"></i>
</label>
</span>
<small class="form-text text-muted" v-if="element.help_text">
{{ element.help_text }}
</small>
</div>
<popover-help-text-modal
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable && element.popover_help_text.content"
:element="element"
></popover-help-text-modal>
</div>
<div v-else-if="element.type == 'signature'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover" @mouseleave="onMouseLeave(element)">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<label :for="element.name">
<span :style="{'color': settings.color.label}" class="ml-2">
{{ element.label }}
</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
<i class="fas fa-info-circle cursor-pointer modal_trigger"
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable"
:data-target="`#${element.name}_modal`"></i>
</label>
<div class="form-group">
<canvas :id="element.name" width="300" height="200" class="signature-pad"
v-bind="getCustomAttributes(element.custom_attributes)">
</canvas>
<input type="hidden" :name="element.name" :id="'output_'+element.name"
:value="_.get(submitted_data, element.name, '')" :required="element.required && applyValidations"
:class="[element.conditional_class, 'signature']"
:data-msg-required="element.required_error_msg">
</div>
<div class="form-text">
<span :id="'clear_' + element.name" class="pointer mr-4" :title="trans('messages.clear_signature_pad')"
:data-name="element.name">
<i class="far fa-times-circle"></i>
{{ trans('messages.clear') }}
</span>
<span :id="'undo_' + element.name" class="pointer" :title="trans('messages.undo')"
:data-name="element.name">
<i class="fas fa-undo"></i>
{{ trans('messages.undo') }}
</span>
<small class="form-text text-muted" v-if="element.help_text">
{{ element.help_text }}
</small>
</div>
<popover-help-text-modal
v-if="!_.isUndefined(element.popover_help_text) && element.popover_help_text.enable && element.popover_help_text.content"
:element="element"
></popover-help-text-modal>
</div>
<!-- page break -->
<div v-else-if="_.includes(['page_break'], element.type) && !applyValidations"
:class="[element.extras.showConfigurator ? 'active_element' : '']"
@mouseover="onMouseHover" @mouseleave="onMouseLeave(element)">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<div class="divider divider-secondary divider-dashed">
<div class="divider-text">
{{ trans('messages.page_break') }}
</div>
</div>
</div>
<!-- /page break -->
<!-- youtube -->
<div v-else-if="element.type == 'youtube'"
class="mt-25 mb-25"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover" @mouseleave="onMouseLeave(element)">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<label :for="element.name">
<span :style="{'color': settings.color.label}" class="ml-2">
{{ element.label }}
</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
</label>
<div class="col-md-12">
<iframe :src="getYtEmbedUrl(element.iframe_url)"
:id="element.name"
:name="element.label" :title="element.label"
:class="[element.custom_class, element.conditional_class]"
:width="`${element.width}%`"
:height="`${element.height}`"
frameborder="0"
style="max-width: 100%;"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
</div>
</div>
<!-- /youtube -->
<!-- iframe -->
<div v-else-if="element.type == 'iframe'"
class="mt-25 mb-25"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
@mouseover="onMouseHover" @mouseleave="onMouseLeave(element)">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<label :for="element.name">
<span :style="{'color': settings.color.label}" class="ml-2">
{{ element.label }}
</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
</label>
<div :class="['col-md-12']">
<iframe :src="element.iframe_url"
:id="element.name"
:name="element.label" :title="element.label"
:class="[element.custom_class, element.conditional_class]"
:width="`${element.width}%`"
:height="`${element.height}`"
frameborder="0"
style="max-width: 100%;">
</iframe>
</div>
</div>
<!-- /iframe -->
<!-- pdf -->
<div v-else-if="element.type == 'pdf'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class]"
class="col-md-12" @mouseover="onMouseHover" @mouseleave="onMouseLeave(element)">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<label :for="element.name">
<span :style="{'color': settings.color.label}" class="ml-2">
{{ element.label }}
</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
</label>
<div class="text-center col-md-12">
<iframe
v-if="!_.isEmpty(element.pdf)"
:src="`${MEDIA_URL}/${element.pdf}`"
:id="element.name"
:name="element.label" :title="element.label"
:class="[element.custom_class, element.conditional_class]"
:width="`${element.width}%`"
:height="`${element.height}`"
frameborder="0"
style="max-width: 100%;"
>
</iframe>
<img v-if="_.isEmpty(element.pdf)" class="img-fluid" :src="PDF_PLACEHOLDER">
</div>
</div>
<!-- /pdf -->
<!-- countdown -->
<div v-else-if="element.type == 'countdown'"
:class="[element.extras.showConfigurator ? 'active_element' : '', element.conditional_class, 'row']"
@mouseover="onMouseHover" @mouseleave="onMouseLeave(element)">
<i class="fas fa-sort handle pointer font_icon_size float-left mr-3" :class="[display_handler]"
:title="trans('messages.drag_element_using_icon')"></i>
<label :for="element.name">
<span :style="{'color': settings.color.label}" class="ml-2">
{{ element.label }}
</span>
<span :style="{'color': settings.color.required_asterisk_color}" v-if="element.required">*</span>
</label>
<div class="col-md-12">
<div :class="[element.custom_class, element.conditional_class]">
<span :id="element.name" class="max-width-100">
</span>
</div>
</div>
</div>
<!-- /countdown -->
</template>
<script>
import PopoverHelpTextModal from './Shared/PopoverHelpText.vue';
export default {
props: {
element: Object,
settings: Object,
applyValidations: {
type: Boolean,
default: true //If passed false then validation will not be applied to field. Used while creating forms
},
submitted_data: Object,
action: String | null,
actionBy: String | null
},
components: {
PopoverHelpTextModal
},
data() {
return {
display_handler: 'hide',
PDF_PLACEHOLDER: APP.PDF_PLACEHOLDER,
MEDIA_URL: APP.APP_MEDIA_URL
}
},
mounted() {
this.$eventBus.$emit('callApplyConditions');
},
created() {
const self = this;
var field = self.element;
var notification_position = self.settings.notification.position;
//if spread to col option is undefined for element set to default
if (
_.includes(['radio', 'checkbox'], self.element.type) &&
_.isUndefined(self.element.spread_to_col)
) {
self.element.spread_to_col = {
enable: (!_.isUndefined(self.element.inline) && self.element.inline) ? true : false,
column: 2
};
}
$(function () {
$(".modal_trigger").on("click", function () {
let modal_id = $(this).attr('data-target');
$(modal_id).modal('toggle');
});
//input range
if (field.type == 'range') {
initialize_rangeslider(field.name);
//on change of range silder call applyConditions through event
$('#' + field.name).on('change', function () {
self.$eventBus.$emit('callApplyConditions');
});
}
//datetime picker
if (field.type == 'calendar') {
initialize_datetimepicker(field.name, _.get(self.submitted_data, field.name, ''), field.start_date, field.end_date, field.format, field.time_format, field.disabled_days, field.enable_time_picker, field.time_picker_inline);
//on change of dateTimePicker call applyConditions through event
$('#' + field.name).on('change.datetimepicker', function () {
self.$eventBus.$emit('callApplyConditions');
});
}
if (field.type == 'file_upload') {
initialize_dropzone(field.name, field.upload_text, field.no_of_files, field.file_size_limit, field.allowed_file_type);
}
if (field.type == 'text_editor') {
initialize_text_editor(field.name, field.placeholder, field.editor_height);
}
if (field.type == 'rating') {
initialize_star_rating(field.name);
//on change of star rating call applyConditions through event
$('#' + field.name).on('rating:change', function (event, value) {
self.$eventBus.$emit('callApplyConditions');
});
}
if (field.type == 'signature') {
initialize_signature_pad(field.name);
}
if (field.type == 'countdown') {
initialize_countdowntimer(field);
}
initializeToastrSettingsForForm(notification_position);
});
},
methods: {
getDynamicallyGeneratedAttributeObj(validations, attributes) {
var rules = [];
if (this.applyValidations) {
_.forEach(validations, function (validation) {
var rule = 'data-rule-' + validation.rule;
var error_msg = 'data-msg-' + validation.rule;
var is_rule_required = validation.value ? validation.value : true;
rules.push({[rule]: is_rule_required, [error_msg]: validation.error_msg});
});
}
let custom_attr = this.getCustomAttributes(attributes);
let validation_rules = Object.assign({}, ...rules);
return {...validation_rules, ...custom_attr};
},
onMouseHover() {
if (!this.applyValidations) {
this.display_handler = '';
}
},
onMouseLeave(element) {
if (!this.applyValidations) {
this.display_handler = 'hide';
}
},
/**
* get col size for
* checkbox & radio
**/
spreadColumnForElement(element) {
let total_columns = 12;
let spread = (parseInt(element.spread_to_col.column) <= 4 ? parseInt(element.spread_to_col.column) : 4) || 2;
let default_column = 12;
if (element.spread_to_col.enable) {
default_column = _.floor(total_columns / spread);
}
return `col-md-${default_column}`;
},
getYtEmbedUrl(url) {
if (url.search("watch") != -1) {
let YT_ID = url.replace("https://www.youtube.com/watch?v=", "");
return `https://www.youtube.com/embed/${YT_ID}`;
} else if (url.search("youtu.be") != -1) {
let YT_ID = url.replace("https://youtu.be/", "");
return `https://www.youtube.com/embed/${YT_ID}`;
} else if (url.search("embed") != -1) {
let YT_ID = url.replace("https://www.youtube.com/embed/", "");
return `https://www.youtube.com/embed/${YT_ID}`;
}
},
}
}
</script>
<style scoped>
.active_element {
padding: 15px;
cursor: pointer;
-webkit-box-shadow: 0px 0px 0px 2px #0293e2;
box-shadow: 0px 0px 0px 2px #0293e2;
border-radius: 10px;
}
.hide {
display: none;
}
.show {
display: block;
}
</style>

View File

@@ -1,774 +0,0 @@
<template>
<div class="row mt-3">
<div class="col-md-2" id="tour_step_1">
<div class="element-sidebar">
<div class="card">
<div class="card-header">
<p class="card-title">{{trans('messages.elements')}}</p>
</div>
<div class="collapse show" id="basicElements">
<div class="card-body pr-1 pl-1 elements_sidebar_height">
<draggable class="dragArea list-group"
:list="basic_elements"
:group="{ name: 'element', pull: 'clone', put: false }"
:clone="cloneElement"
:sort="false"
@change="change"
>
<div class="list-group-item"
v-for="element in basic_elements"
:key="element.type"
>
<button type="button"
class="btn btn-primary btn-block"
:class="[(_.includes(['card_form'], settings.layout) && _.includes(['page_break'], element.type)) ? '' : 'hvr-grow']"
:title="element.tooltip"
:disabled="_.includes(['card_form'], settings.layout) && _.includes(['page_break'], element.type)">
<i class="mt-1 mb-1" :class="'float-left fas fa-' + element.display_icon"></i>
{{ element.label }}
<i
v-if="_.includes(['card_form'], settings.layout) && _.includes(['page_break'], element.type)"
class="fas fa-info-circle float-right mt-1 mb-1"
data-toggle="tooltip"
:title="trans('messages.page_break_disabled')"></i>
</button>
</div>
</draggable>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-7" :style="{'background-color': settings.color.page_color, 'padding':`10px`}">
<div class="card scrollableCard" :style="{'background': getBackgroundStyle(), 'background-image':`${backgroundImg}`}" style="height: 100%;" id="tour_step_2">
<div class="text-center mt-2" v-if="selected_elements.length == 0">
<h5>{{trans('messages.pls_add_element')}}</h5>
</div>
<draggable
class="dragArea card-body"
:list="selected_elements"
group="element"
handle=".handle"
@change="change"
:animation="200"
>
<transition-group
name="custom-classes-transition"
enter-active-class="animated zoomIn"
leave-active-class="animated fadeOut"
tag="div"
class="row"
:class="[(selected_elements.length < 3) ? 'transition-card-body' : '']">
<div
v-for="(element, index) in selected_elements"
:key="element.id"
:class="element.col"
@click="toggleConfigurator(index, true)"
>
<fieldGenerator
:element="element"
:settings="settings"
:applyValidations="applyValidations"
action=""
></fieldGenerator>
<div class="element-config-action-btn float-right"
v-show="element.extras.showConfigurator">
<p>
<button type="button"
v-if="!_.includes(['page_break'], element.type)"
class="btn btn-xs btn-secondary"
:title="trans('messages.properties')"
@click="openElementConfigurator()">
<i class="fas fa-cog"></i>
</button>
</p>
<p>
<button type="button"
class="btn btn-xs btn-danger"
:title="trans('messages.remove')"
@click="deleteElement(index)">
<i class="far fa-trash-alt"></i>
</button>
</p>
</div>
</div>
</transition-group>
</draggable>
</div>
</div>
<div class="col-md-3" id="tour_step_3">
<div class="element-sidebar">
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link" id="formDetails-tab" data-toggle="tab" href="#formDetails" role="tab" :class="isConfiguratorOpen ? '' : 'active'" aria-controls="formDetails" aria-selected="true">
{{ trans('messages.form') }}
</a>
</li>
<li class="nav-item">
<a class="nav-link" id="configuration-tab" :class="isConfiguratorOpen ? 'active' : ''" data-toggle="tab" href="#configuration" role="tab" aria-controls="configuration" aria-selected="false">
{{ trans('messages.element_configuration') }}
</a>
</li>
</ul>
<div class="tab-content" id="tab_content" role="tabpanel">
<div class="tab-pane fade" :class="isConfiguratorOpen ? '' : 'active show'" id="formDetails" role="tabpanel" aria-labelledby="formDetails-tab">
<div class="card mt-1 configurator_form_height">
<div class="card-body">
<div class="row">
<div class="col-md-12 mb-2">
<label>
{{ trans('messages.form_name') }}
<span class="error">*</span>
</label>
<input type="text" class="form-control"
v-model="form.name" required @change="generateFormSlug(form.name)">
</div>
</div>
<div class="row">
<div class="col-md-12 mb-2">
<label for="form_slug">
{{ trans('messages.form_slug') }}
<span class="error">*</span>
</label>
<input type="text" class="form-control"
v-model="form_slug" required readonly>
</div>
</div>
<div class="row mb-1">
<div class="col-md-12">
<label>
{{ trans('messages.form_description') }}
</label>
<input type="text" class="form-control" v-model="form.description">
</div>
</div>
<form-layout
:selected_elements="selected_elements"
:settings="settings">
</form-layout>
<div class="row">
<!-- form custom attribute -->
<div class="col-md-12" v-if="form_custom_attributes.length">
<hr>
<label>{{trans('messages.custom_attributes')}}</label>
</div>
<div class="row form_custom_attr_field" v-for="(form_custom_attribute, index) in form_custom_attributes">
<div class="col-md-10">
<div class="input-group">
<input type="text" class="form-control" v-model="form_custom_attribute.key" :placeholder="trans('messages.key')">
<input type="text" class="form-control" v-model="form_custom_attribute.value" :placeholder="trans('messages.value')">
</div>
</div>
<div class="col-md-2">
<button type="button" class="btn btn-danger btn-sm" @click="removeAttribute(index)">
<i class="fas fa-trash-alt"></i>
</button>
</div>
</div>
<button type="button" class="btn btn-sm btn-info" @click="addMoreAttribute" style="margin: 28px;">
<i class="fas fa-plus-circle"></i>
{{trans('messages.add_form_custom_attribute')}}
</button>
</div>
</div>
</div>
</div>
<div class="tab-pane fade mb-2" :class="isConfiguratorOpen ? 'active show' : ''" id="configuration" role="tabpanel" aria-labelledby="configuration-tab">
<template v-for="(element, index) in selected_elements"
v-if="element.extras.showConfigurator && isConfiguratorOpen">
<fieldConfigurator
v-if="!_.includes(['page_break'], element.type)"
:key="element.id"
:element="element"
:index="index"
:selected_elements="selected_elements"
v-on:toggleConfigurator="toggleConfiguratorEvent"
v-on:deleteElement="deleteElement"
></fieldConfigurator>
<div
v-if="_.includes(['page_break'], element.type)"
class="mt-1 ml-3">
{{ trans('messages.no_config_option') }}
</div>
</template>
<div v-if="!isConfiguratorOpen">
<div class="mt-1 ml-3">
{{ trans('messages.pls_add_element_to_configure') }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import draggable from "../../../node_modules/vuedraggable";
import fieldGenerator from "./FieldGenerator";
import fieldConfigurator from "./FieldConfigurator";
import ElementDetails from "./ElementDetails";
import FormLayout from "./Shared/Layout";
let idGlobal = 0;
export default {
props:{
selected_elements: Array,
settings:Object,
form:Array,
placeholder_img:String,
form_custom_attributes: Array
},
components: {
draggable,
fieldGenerator,
fieldConfigurator,
ElementDetails,
FormLayout
},
data(){
const self = this;
return {
applyValidations: false,
basic_elements: [
{ type: 'text',
subtype:'text',
label: self.trans('messages.input'),
help_text: '',
display_icon: 'grip-lines',
prefix_icon: 'none',
suffix_icon: 'none',
placeholder:'',
size:'',
custom_class:'',
conditional_class:'',
col:'col-md-12',
custom_attributes:[],
tooltip: self.trans('messages.text_tooltip'),
popover_help_text:{
enable: false,
content: ''
},
allowed_input:{
values:'',
error_msg: 'This value is not allowed.'
}
},
{ type: 'textarea',
label: self.trans('messages.textarea'),
help_text: '',
display_icon: 'list',
prefix_icon: 'none',
suffix_icon: 'none',
rows: 3,
columns:'',
placeholder:'',
custom_class:'',
conditional_class:'',
col:'col-md-12',
custom_attributes:[],
tooltip: self.trans('messages.textarea_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{ type: 'dropdown',
label: self.trans('messages.dropdown'),
help_text: '',
display_icon: 'caret-square-down',
prefix_icon: 'none',
suffix_icon: 'none',
options:'Option-1\nOption-2',
size:'',
custom_class:'',
conditional_class:'',
multiselect:false,
col:'col-md-12',
custom_attributes:[],
tooltip: self.trans('messages.dropdown_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{ type: 'radio',
label: self.trans('messages.radio'),
help_text: '',
spread_to_col: {
enable: false,
column: 2
},
display_icon: 'dot-circle',
options:'Option-1\nOption-2',
conditional_class:'',
col:'col-md-12',
custom_attributes:[],
tooltip: self.trans('messages.radio_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{ type: 'checkbox',
label: self.trans('messages.checkbox'),
help_text: '',
spread_to_col: {
enable: false,
column: 2
},
display_icon: 'check-circle',
options:'Option-1\nOption-2',
conditional_class:'',
col:'col-md-12',
custom_attributes:[],
tooltip: self.trans('messages.checkbox_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{ type: 'heading',
label: self.trans('messages.heading_paragrahp'),
tag: 'h1',
text_color: '#212529',
content: 'Click to change it',
display_icon: 'heading',
col:'col-md-12',
tooltip: self.trans('messages.heading_paragrahp_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{ type: 'range',
label: self.trans('messages.range'),
help_text: '',
display_icon: 'arrows-alt-h',
min:1,
max:10,
step:1,
data_orientation:'horizontal',
conditional_class:'',
col:'col-md-12',
custom_attributes:[],
tooltip: self.trans('messages.range_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{ type: 'calendar',
label: self.trans('messages.datetime'),
help_text: '',
size:'',
display_icon: 'calendar-alt',
prefix_icon: 'none',
suffix_icon: 'none',
custom_class:'',
start_date:'none',
end_date:'none',
format:'MM-DD-YYYY',
disabled_days:[],
enable_time_picker:false,
time_format:'12',
time_picker_inline:false,
conditional_class:'',
col:'col-md-12',
custom_attributes:[],
tooltip: self.trans('messages.datetime_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{
type: 'file_upload',
label: self.trans('messages.file_upload'),
help_text:'',
display_icon: 'upload',
upload_text: self.trans('messages.drop_a_file_here'),
no_of_files:'1',
send_as_email_attachment: false,
file_size_limit: 5,
file_type:'all',
allowed_file_type:'',
custom_class:'',
conditional_class:'',
col:'col-md-12',
custom_attributes:[],
tooltip: self.trans('messages.file_upload_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{
type: 'text_editor',
label: self.trans('messages.text_editor'),
placeholder: self.trans('messages.jot_down_here'),
help_text:'',
display_icon: 'keyboard',
editor_height: 150,
conditional_class:'',
col:'col-md-12',
custom_attributes:[],
tooltip: self.trans('messages.text_editor_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{
type: 'terms_and_condition',
label: self.trans('messages.terms_condition'),
link: '',
display_icon: 'file-signature',
custom_class: '',
conditional_class:'',
col:'col-md-12',
custom_attributes:[],
tooltip: self.trans('messages.terms_condition_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{
type: 'rating',
label: self.trans('messages.rating'),
display_icon: 'star',
conditional_class:'',
stars_to_display:5,
min_rating:0,
max_rating:5,
increment:0.5,
direction:'ltr',
size:'md',
col:'col-md-12',
custom_attributes:[],
tooltip: self.trans('messages.rating_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{
type: 'switch',
label: self.trans('messages.switch'),
display_icon: 'toggle-off',
conditional_class: '',
help_text:'',
size:'switch',
col:'col-md-12',
custom_attributes:[],
tooltip: self.trans('messages.switch_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{
type: 'hr',
label: self.trans('messages.horizontal_line'),
padding_top:1,
padding_bottom:1,
border_size:1,
horizontal_space: 0,
border_type:'solid',
border_color:'#0a0a0a',
display_icon: 'window-minimize',
col:'col-md-12',
tooltip: self.trans('messages.hr_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{
type: 'html_text',
label: self.trans('messages.html_text'),
html_text:'Write Something..',
display_icon: 'code',
custom_class: '',
col:'col-md-12',
tooltip: self.trans('messages.html_text_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{
type: 'signature',
label: self.trans('messages.signature'),
display_icon: 'signature',
col: 'col-md-12',
html_text:'',
custom_class:'',
custom_attributes:[],
tooltip: self.trans('messages.signature_tooltip'),
popover_help_text:{
enable: false,
content: ''
}
},
{
type: 'page_break',
label: self.trans('messages.page_break'),
label_align: 'top',
display_icon: 'cut',
col:'col-md-12',
tooltip: '',
popover_help_text:{
enable: false,
content: ''
}
},
{ type: 'youtube',
label: self.trans('messages.youtube'),
display_icon: 'video',
custom_class:'',
conditional_class:'',
col:'col-md-12',
tooltip: '',
iframe_url:'',
width: 100,
height: 350,
popover_help_text:{
enable: false,
content: ''
}
},
{ type: 'iframe',
label: self.trans('messages.iframe_embed'),
display_icon: 'crop-alt',
custom_class:'',
conditional_class:'',
col:'col-md-12',
iframe_url:'https://www.lipsum.com',
iframe_align: 'left',
css: '',
width: 100,
height: 400,
popover_help_text:{
enable: false,
content: ''
}
},
{ type: 'pdf',
label: self.trans('messages.pdf_embedder'),
display_icon: 'file-pdf',
custom_class:'',
conditional_class:'',
col:'col-md-12',
tooltip: '',
pdf:'',
width: 100,
height: 350,
popover_help_text:{
enable: false,
content: ''
}
},
{ type: 'countdown',
label: self.trans('messages.countdown'),
display_icon: 'hourglass-start',
custom_class: '',
conditional_class: '',
col: 'col-md-12',
tooltip: '',
seconds: 0,
minutes: 0,
hours: 1,
labels_format : true,
size: 'lg',
border_color: '#F0068E',
font_color: '#FFFFFF',
bg_color: '#000000',
time_separator: ':',
display_format: 'HMS',
popover_help_text:{
enable: false,
content: ''
}
}
],
isConfiguratorOpen: false,
form_slug: ''
}
},
computed:{
backgroundImg() {
if (this.selected_elements.length == 0) {
return 'url(' + this.placeholder_img +')';
} else {
return '';
}
}
},
created() {
if (this.selected_elements.length > 0) {
var ids = [];
_.forEach(this.selected_elements, function(element) {
ids.push(element.id);
});
var id = _.max(ids);
idGlobal = ++id;
}
this.form_slug = this.form.slug;
},
methods: {
addMoreAttribute() {
var custom_attribute = {'key':'', 'value':''};
this.form_custom_attributes.push(custom_attribute);
},
removeAttribute(index) {
this.form_custom_attributes.splice(index, 1);
},
getBackgroundStyle() {
if (this.settings.background.bg_type !== 'bg_image') {
return this.settings.color.background;
} else {
return '';
}
},
change: function(evt) {
window.console.log(evt);
if(evt.added != undefined){
//find index of an added element
var index = this.selected_elements.indexOf(evt.added.element);
this.toggleConfigurator(index, true);
//add field for col visibility in datatable
if (!_.includes(['terms_and_condition', 'heading', 'hr', 'html_text', 'page_break', 'youtube', 'iframe', 'pdf', 'countdown'], evt.added.element.type)) {
this.settings.form_data.col_visible.push(evt.added.element.name);
}
}
},
cloneElement(element_details) {
var details_cloned = _.clone(element_details);
var data = {
id: idGlobal++,
name: 'field_' + idGlobal,
extras: {showConfigurator: false}
};
_.unset(details_cloned, 'id');
_.unset(details_cloned, 'name');
_.unset(details_cloned, 'display_icon');
_.unset(details_cloned, 'tooltip');
var output = _.merge(data, details_cloned);
output['required'] = false;
output['required_error_msg'] = 'This field is required';
output['validations'] = [];
return output;
},
toggleConfigurator(index, show) {
//Check if any previously open, then close it
const self = this;
if(show == true){
_.forEach(this.selected_elements, function(value, key) {
self.selected_elements[key].extras.showConfigurator = false;
});
}
this.selected_elements[index].extras.showConfigurator = show;
},
toggleConfiguratorEvent(values){
this.toggleConfigurator(values.index, values.show);
this.openElementConfigurator();
},
openElementConfigurator() {
this.isConfiguratorOpen = !this.isConfiguratorOpen
},
deleteElement(index) {
const self = this;
Swal.fire({
title: self.trans("messages.are_you_sure"),
text: self.trans("messages.you_wont_be_able_to_revert"),
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: self.trans("messages.yes_remove_it"),
}).then((result) => {
if (result.isConfirmed) {
let element = self.selected_elements[index];
let deletedElementIndex = self.settings.form_data.col_visible.indexOf(element.name);
self.selected_elements.splice(index, 1);
self.isConfiguratorOpen = false;
if (deletedElementIndex != '-1') {
self.settings.form_data.col_visible.splice(index, 1);
}
}
});
},
generateFormSlug(name) {
const self = this;
axios
.get('/generate-form-slug', {
params:{
name: name,
}
})
.then(function(response) {
self.form.slug = response.data;
self.form_slug = self.form.slug;
}).catch(function(error) {
console.log(error);
});
}
}
}
</script>
<style scoped>
.scrollableCard{
display: flex;
flex-direction: column;
height: 200vh;
min-height: 392px;
padding-right: 25px;
padding-left: 15px;
}
#tab_content {
border-right: 1px solid #d2e3f5;
border-left: 1px solid #d2e3f5;
border-bottom: 1px solid #d2e3f5;
}
.card-title{
font-size: 1rem !important;
}
.list-group-item{
border: 0px !important;
padding-left: 0.25rem !important;
padding-right: 0.25rem !important;
}
.element-sidebar{
position: -webkit-sticky;
position: sticky;
top: 0rem;
height: 58vh;
}
.elements_sidebar_height{
overflow-y: auto;
max-height: 58vh;
}
.configurator_form_height {
overflow-y: auto;
max-height: 58vh;
}
#formDetails {
height : 58vh;
}
.transition-card-body{
min-height: 392px;
}
</style>

View File

@@ -1,104 +0,0 @@
<template>
<div class="mt-3">
<div class="custom-control custom-checkbox">
<input type="checkbox"
class="custom-control-input"
id="mailchimp_is_enable"
v-model="details.is_enable"
value="1">
<label class="custom-control-label" for="mailchimp_is_enable">
{{trans('messages.enable')}}
</label>
</div>
<div v-if="details.is_enable">
<div class="text-left text-muted">
<small>{{trans('messages.not_in_downloaded_code')}}</small><br/>
</div>
<div class="form-group row">
<label for="site_key" class="col-sm-3 col-form-label">{{trans('messages.mailchimp_api_key')}}:
<span class="error">*</span></label>
<div class="col-sm-9">
<input type="text" class="form-control"
id="mailchimp_api_key"
:placeholder="trans('messages.mailchimp_api_key')"
name="details.api_key"
:required="details.is_enable"
v-model="details.api_key">
<small class="form-text text-muted" v-html="trans('messages.mailchimp_api_key_help')"></small>
</div>
</div>
<div class="form-group row">
<label for="site_key" class="col-sm-3 col-form-label">{{trans('messages.mailchimp_list_id')}}:
<span class="error">*</span></label>
<div class="col-sm-9">
<input type="text" class="form-control"
id="mailchimp_list_id"
:placeholder="trans('messages.mailchimp_list_id')"
name="details.list_id"
:required="details.is_enable"
v-model="details.list_id">
<small class="form-text text-muted" v-html="trans('messages.mailchimp_list_id_help')"></small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.mailchimp_subscription_status')}}
<span class="error">*</span>
</label>
<div class="col-sm-9">
<select class="form-control"
:required="details.is_enable"
name="details.status"
v-model="details.status">
<option value="subscribe_pending">{{trans('messages.mailchimp_subscribe_confirm')}}</option>
<option value="subscribe">{{trans('messages.mailchimp_subscribe')}}</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.email')}}
<span class="error">*</span>
</label>
<div class="col-sm-9">
<select class="form-control"
:required="details.is_enable"
name="details.email_field"
v-model="details.email_field">
<option :value="element.name"
v-if="_.includes(['text', 'email'], element.type)"
v-for="element in selected_elements">{{element.label}}</option>
</select>
<small class="form-text text-muted">{{trans('messages.mailchimp_email_help')}}</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.name')}}
</label>
<div class="col-sm-9">
<select class="form-control"
name="details.name_field"
v-model="details.name_field">
<option :value="element.name"
v-if="_.includes(['text', 'email'], element.type)"
v-for="element in selected_elements">{{element.label}}</option>
</select>
<small class="form-text text-muted">{{trans('messages.mailchimp_name_help')}}</small>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['details', 'selected_elements'],
}
</script>

View File

@@ -1,925 +0,0 @@
<template>
<div class="mt-3">
<!-- reCAPTCHA settings -->
<h5 class="text-primary">
{{trans('messages.google_recaptcha_settings')}}:
</h5>
<div class="form-group">
<div class="col-sm offset-3 col-sm-9">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" value="1" id="enable_recaptcha" name="enable_recaptcha" v-model="settings.recaptcha.is_enable">
<label class="custom-control-label" for="enable_recaptcha">
{{trans('messages.add_google_recaptcha')}}
</label>
</div>
</div> <br>
<div class="form-group row" v-if="settings.recaptcha.is_enable">
<label for="site_key" class="col-sm-3 col-form-label">
{{trans('messages.site_key')}}
<span class="error">*</span></label>
<div class="col-sm-9">
<input type="text" class="form-control" id="site_key" :placeholder="trans('messages.enter_site_key')"
name="settings.recaptcha.site_key"
:required="settings.recaptcha.is_enable"
v-model="settings.recaptcha.site_key">
</div>
</div>
<div class="form-group row" v-if="settings.recaptcha.is_enable">
<label for="secret_key" class="col-sm-3 col-form-label">
{{trans('messages.secret_key')}}<span class="error">*</span></label>
<div class="col-sm-9">
<input type="text" name="settings.recaptcha.secret_key" class="form-control" id="secret_key" :placeholder="trans('messages.enter_secret_key')" v-model="settings.recaptcha.secret_key"
:required="settings.recaptcha.is_enable">
<small id="help_text" class="form-text text-muted">
{{trans('messages.secret_key_help_text')}}
<a href="https://www.google.com/recaptcha/admin" target="_blank">{{trans('messages.click_here')}}</a> {{trans('messages.to_create')}}
</small>
</div>
</div>
</div>
<!-- Design settings -->
<h5 class="text-primary">{{trans('messages.design_settings')}}:</h5>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.theme')}}
</label>
<div class="col-sm-9">
<select class="custom-select" aria-describedby="theme" v-model="settings.theme">
<option v-for="(theme, index) in themes" :value="theme.key" :key="index">
{{theme.value}}
</option>
</select>
<small id="theme" class="form-text text-muted">
{{trans('messages.to_see_effect_preview_form')}}
</small>
</div>
</div>
<div class="form-group row">
<label for="label_color" class="col-sm-3 col-form-label">
{{trans('messages.label_color')}}
</label>
<div class="input-group col-sm-9">
<input type="text" class="form-control form-control-lg" name="label_color" id="label_color" v-model="settings.color.label">
<div class="input-group-append">
<span class="input-group-text">
<input type="color" v-model="settings.color.label">
</span>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="error_msg_color">
{{trans('messages.error_msg_color')}}
</label>
<div class="input-group col-sm-9">
<input type="text" class="form-control form-control-lg" name="error_msg_color" id="error_msg_color" v-model="settings.color.error_msg">
<div class="input-group-append">
<span class="input-group-text">
<input type="color" v-model="settings.color.error_msg">
</span>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="required_asterisk_color">
{{trans('messages.required_asterisk_color')}}
</label>
<div class="input-group col-sm-9">
<input type="text" class="form-control form-control-lg" name="required_asterisk_color" id="required_asterisk_color" v-model="settings.color.required_asterisk_color">
<div class="input-group-append">
<span class="input-group-text">
<input type="color" v-model="settings.color.required_asterisk_color">
</span>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label" for="page_color">
{{trans('messages.page_color')}}
</label>
<div class="input-group col-sm-9">
<input type="text" class="form-control form-control-lg" name="page_color" id="page_color" v-model="settings.color.page_color">
<div class="input-group-append">
<span class="input-group-text">
<input type="color" v-model="settings.color.page_color">
</span>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.form_background_setting')}}
</label>
<div class="col-sm-9">
<div class="custom-control custom-radio custom-control-inline">
<input class="custom-control-input" name="settings.bg_settings" type="radio" id="bg_color" :value="'bg_color'" v-model="settings.background.bg_type">
<label class="custom-control-label" for="bg_color">
{{trans('messages.form_background_color')}}
</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input class="custom-control-input" name="settings.bg_settings" type="radio" id="bg_image" :value="'bg_image'" v-model="settings.background.bg_type">
<label class="custom-control-label" for="bg_image">
{{trans('messages.form_background_image')}}
</label>
</div>
</div>
</div>
<div class="form-group row" v-show="settings.background.bg_type === 'bg_color'">
<label class="col-sm-3 col col-form-label" for="background_color">
{{trans('messages.form_background_color')}}
</label>
<div class="input-group col-sm-9">
<input type="text" name="background_color" id="background_color" class="form-control form-control-lg" v-model="settings.color.background">
<div class="input-group-append">
<span class="input-group-text">
<input type="color" v-model="settings.color.background">
</span>
</div>
</div>
</div>
<div class="form-group row" v-show="settings.background.bg_type === 'bg_image'">
<label class="col-sm-3 col col-form-label" for="background_color">
{{trans('messages.form_background_image')}}
</label>
<div class="col-sm-9 dropzone" id="fileUpload"></div>
</div>
<!-- notification settings -->
<h5 class="text-primary">
{{trans('messages.notification_setting')}}:
</h5>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.action_after_submit')}}
</label>
<div class="col-sm-9">
<div class="custom-control custom-radio custom-control-inline">
<input class="custom-control-input" type="radio" id="notification_same_page" :value="same_page" name="post_submit_action" v-model="settings.notification.post_submit_action" checked>
<label class="custom-control-label" for="notification_same_page">
{{trans('messages.show_notification_in_same_page')}}
</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input class="custom-control-input" name="post_submit_action" type="radio" id="notification_redirect" :value="redirect" v-model="settings.notification.post_submit_action">
<label class="custom-control-label" for="notification_redirect">
{{trans('messages.redirect_to_thank_you_page')}}
</label>
</div>
</div>
</div>
<div class="form-group row" v-show="settings.notification.post_submit_action === same_page">
<label for="success_msg" class="col-sm-3 col-form-label">
{{trans('messages.email_success_notification')}}
</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="success_msg" :placeholder="trans('messages.enter_msg')" name="success_msg" v-model="settings.notification.success_msg">
</div>
</div>
<div class="form-group row" v-show="settings.notification.post_submit_action === same_page">
<label for="failed_msg" class="col-sm-3 col-form-label">
{{trans('messages.email_failed_notification')}}
</label>
<div class="col-sm-9">
<input type="text" class="form-control"
id="failed_msg" :placeholder="trans('messages.enter_msg')"
name="failed_msg" v-model="settings.notification.failed_msg">
</div>
</div>
<div class="form-group row" v-show="settings.notification.post_submit_action === same_page">
<label for="position" class="col-sm-3 col-form-label">
{{trans('messages.display_position')}}
</label>
<div class="col-sm-9">
<select name="position" class="form-control" v-model="settings.notification.position">
<option value="toast-top-right">
{{trans('messages.top_right')}}
</option>
<option value="toast-bottom-right">
{{trans('messages.bottom_right')}}
</option>
<option value="toast-bottom-left">
{{trans('messages.bottom_left')}}
</option>
<option value="toast-top-left">
{{trans('messages.top_left')}}
</option>
<option value="toast-top-center">
{{trans('messages.top_center')}}
</option>
<option value="toast-bottom-center">
{{trans('messages.bottom_center')}}
</option>
</select>
</div>
</div>
<div class="form-group row" v-show="settings.notification.post_submit_action === same_page">
<label for="enable_qr_code" class="col-sm-3 col-form-label">
{{trans('messages.qr_code_for_submitted_data')}}
</label>
<div class="col-sm-9">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input"
id="enable_qr_code"
v-model="settings.is_qr_code_enabled">
<label class="custom-control-label" for="enable_qr_code">
{{trans('messages.enable')}}
<i class="fas fa-info-circle"
data-toggle="tooltip"
:title="trans('messages.qr_code_tooltip')"></i>
</label>
</div>
<small class="form-text text-muted"
v-html="trans('messages.qr_code_limit_help_text')">
</small>
</div>
</div>
<div class="form-group row"
v-if="_.includes(['same_page'], settings.notification.post_submit_action) && settings.is_qr_code_enabled">
<label for="data_format" class="col-sm-3 col-form-label">
{{trans('messages.qr_code_for_submitted_data')}} ({{trans('messages.data_format')}})
</label>
<div class="col-sm-9">
<div class="custom-control custom-radio custom-control-inline">
<input class="custom-control-input" type="radio" id="key_value_format" value="string" name="data_format" v-model="settings.qr_code_data_format">
<label class="custom-control-label" for="key_value_format">
{{trans('messages.key_value_format')}}
</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input class="custom-control-input" name="data_format" type="radio" id="json_format" value="json" v-model="settings.qr_code_data_format">
<label class="custom-control-label" for="json_format">
{{trans('messages.json_format')}}
</label>
</div>
</div>
</div>
<!-- ref num qr code -->
<div class="form-group row" v-show="settings.notification.post_submit_action === same_page">
<label for="enable_qr_code_for_ref_num" class="col-sm-3 col-form-label">
{{trans('messages.qr_code_for_ref_num')}}
</label>
<div class="col-sm-9">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input"
id="enable_qr_code_for_ref_num"
v-model="settings.is_ref_num_qr_code_enabled">
<label class="custom-control-label" for="enable_qr_code_for_ref_num">
{{trans('messages.enable')}}
<i class="fas fa-info-circle"
data-toggle="tooltip"
:title="trans('messages.submission_ref_qr_code_tooltip')"></i>
</label>
</div>
<small class="form-text text-muted"
v-html="trans('messages.bar_code_help_text')">
</small>
</div>
</div>
<!-- ref num bar code -->
<div class="form-group row" v-show="settings.notification.post_submit_action === same_page">
<label for="enable_bar_code_for_ref_num" class="col-sm-3 col-form-label">
{{trans('messages.bar_code_for_ref_num')}}
</label>
<div class="col-sm-9">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input"
id="enable_bar_code_for_ref_num"
v-model="settings.is_ref_num_bar_code_enabled">
<label class="custom-control-label" for="enable_bar_code_for_ref_num">
{{trans('messages.enable')}}
<i class="fas fa-info-circle"
data-toggle="tooltip"
:title="trans('messages.submission_ref_qr_code_tooltip')"></i>
</label>
</div>
<small class="form-text text-muted"
v-html="trans('messages.bar_code_help_text')">
</small>
</div>
</div>
<div class="form-group row" v-show="settings.notification.post_submit_action === redirect">
<label for="redirect_url" class="col-sm-3 col-form-label">
{{trans('messages.redirect_url')}}<span class="error">*</span>
</label>
<div class="col-sm-9">
<input type="text"
class="form-control"
id="redirect_url"
:placeholder="trans('messages.enter_redirect_url')"
name="settings.notification.redirect_url"
:required="settings.notification.post_submit_action === redirect"
data-rule-url="true"
v-model="settings.notification.redirect_url">
</div>
</div>
<!-- submit button settings -->
<h5 class="text-primary">
{{trans('messages.submit_btn_setting')}}
</h5>
<div class="form-group row">
<label for="btn_style" class="col-sm-3 col-form-label">
{{trans('messages.submit_btn_style')}}
</label>
<div class="col-sm-9">
<label class="btn btn-primary">
<input type="radio" name="btn_style" :value="'default'" v-model="settings.submit.btn_style"> {{trans('messages.default')}}
</label>
<label class="btn btn-outline-primary">
<input type="radio" name="btn_style" :value="'outline'" v-model="settings.submit.btn_style"> {{trans('messages.outline')}}
</label>
</div>
</div>
<div class="form-group row">
<label for="sb_btn_size" class="col-sm-3 col-form-label">
{{trans('messages.submit_btn_size')}}
</label>
<div class="col-sm-6">
<label class="btn btn-lg btn-primary">
<input type="radio" name="btn_size" :value="btn_large" v-model="settings.submit.btn_size"> {{trans('messages.large')}}
</label>
<label class="btn btn-primary">
<input type="radio" name="btn_size" :value="btn_default" v-model="settings.submit.btn_size"> {{trans('messages.medium')}}
</label>
<label class="btn btn-primary btn-sm" aria-describedby="sb_btn_size">
<input type="radio" name="btn_size" :value="btn_sm" v-model="settings.submit.btn_size"> {{trans('messages.small')}}
</label>
<small id="sb_btn_size" class="form-text text-muted">
{{trans('messages.submit_btn_size_help_text')}}
</small>
</div>
</div>
<div class="form-group row">
<label for="sb_btn_color" class="col-sm-3 col-form-label">
{{trans('messages.submit_btn_color')}}
</label>
<div class="col-sm-6" v-show="settings.submit.btn_style == 'default'">
<label class="btn">
<input type="radio" name="sb_btn_color" :value="default_value" v-model="settings.submit.btn_color"> {{trans('messages.default')}}
</label>
<label class="btn btn-primary">
<input type="radio" name="sb_btn_color" :value="primary" v-model="settings.submit.btn_color"> {{trans('messages.primary')}}
</label>
<label class="btn btn-success">
<input type="radio" name="sb_btn_color" :value="success" v-model="settings.submit.btn_color"> {{trans('messages.success')}}
</label>
<label class="btn btn-warning">
<input type="radio" name="sb_btn_color" :value="warning" v-model="settings.submit.btn_color"> {{trans('messages.warning')}}
</label>
<label class="btn btn-danger">
<input type="radio" name="sb_btn_color" :value="danger" v-model="settings.submit.btn_color" aria-describedby="sb_btn_color"> {{trans('messages.danger')}}
</label>
<small id="sb_btn_color" class="form-text text-muted">
{{trans('messages.submit_btn_color_help_text')}}
</small>
</div>
<div class="col-sm-6" v-show="settings.submit.btn_style == 'outline'">
<label class="btn">
<input type="radio" name="sb_btn_color" :value="default_value" v-model="settings.submit.btn_color"> {{trans('messages.default')}}
</label>
<label class="btn btn-outline-primary">
<input type="radio" name="sb_btn_color" :value="'btn-outline-primary'" v-model="settings.submit.btn_color"> {{trans('messages.primary')}}
</label>
<label class="btn btn-outline-success">
<input type="radio" name="sb_btn_color" :value="'btn-outline-success'" v-model="settings.submit.btn_color"> {{trans('messages.success')}}
</label>
<label class="btn btn-outline-warning">
<input type="radio" name="sb_btn_color" :value="'btn-outline-warning'" v-model="settings.submit.btn_color"> {{trans('messages.warning')}}
</label>
<label class="btn btn-outline-danger">
<input type="radio" name="sb_btn_color" :value="'btn-outline-danger'" v-model="settings.submit.btn_color" aria-describedby="sb_btn_color"> {{trans('messages.danger')}}
</label>
<small id="sb_btn_color" class="form-text text-muted">
{{trans('messages.submit_btn_color_help_text')}}
</small>
</div>
</div>
<div class="form-group row">
<label for="sb_btn_alignment" class="col-sm-3 col-form-label">
{{trans('messages.submit_btn_alignment')}}
</label>
<div class="col-sm-9">
<div class="custom-control custom-radio custom-control-inline">
<input class="custom-control-input" type="radio" id="btn_align_left" value="float-left" name="sb_btn_alignment" v-model="settings.submit.btn_alignment">
<label class="custom-control-label" for="btn_align_left">
{{trans('messages.left')}}
</label>
</div>
<div class="custom-control custom-radio custom-control-inline" aria-describedby="btn_align">
<input class="custom-control-input" name="sb_btn_alignment" type="radio" id="btn_align_right" value="float-right" v-model="settings.submit.btn_alignment">
<label class="custom-control-label" for="btn_align_right">
{{trans('messages.right')}}
</label>
</div>
<small id="btn_align" class="form-text text-muted">
{{trans('messages.submit_btn_alignment_help_text')}}
</small>
</div>
</div>
<div class="form-group row">
<label for="sb_text" class="col-sm-3 col-form-label">
{{trans('messages.submit_btn_text')}}
</label>
<div class="col-sm-9">
<input type="text" name="sb_text" class="form-control" :placeholder="trans('messages.enter_submit_btn_txt')" v-model="settings.submit.text">
</div>
</div>
<div class="form-group row">
<label for="sb_loading_text" class="col-sm-3 col-form-label">
{{trans('messages.submit_btn_loading_text')}}
</label>
<div class="col-sm-9">
<input type="text" name="sb_loading_text" class="form-control" :placeholder="trans('messages.enter_submit_btn_load_txt')" v-model="settings.submit.loading_text">
</div>
</div>
<div class="form-group row">
<label for="btn_icon" class="col-sm-3 col-form-label">
{{trans('messages.submit_btn_icon')}}
</label>
<div class="col-sm-9">
<div class="input-group">
<select id="btn_icon" class="form-control" v-model="settings.submit.btn_icon">
<option :value="'none'">None</option>
<option v-for="(icon, index) in getIcons()" :value="icon.c" :key="index">
{{icon.l}}
</option>
</select>
<select id="icon_position" class="form-control" v-model="settings.submit.icon_position">
<option :value="'left'">{{trans('messages.left')}}</option>
<option :value="'right'">{{trans('messages.right')}}</option>
</select>
</div>
</div>
</div>
<!-- form data settings -->
<h5 class="text-primary">
{{trans('messages.form_data_setting')}}
</h5>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.column_visibility')}}
</label>
<div class="col-sm-9">
<select multiple class="custom-select" aria-describedby="col_visibility" v-model="settings.form_data.col_visible">
<option v-for="element in selected_elements" :value="element.name" v-if="!_.includes(['terms_and_condition', 'heading', 'hr', 'html_text', 'page_break', 'youtube', 'iframe', 'pdf', 'countdown'], element.type)">
{{element.label}}
</option>
</select>
<small id="col_visibility" class="form-text text-muted">
{{trans('messages.column_visibility_help_text')}}
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.enable_button')}}
</label>
<div class="col-sm-9">
<div class="custom-control custom-checkbox custom-control-inline">
<input class="custom-control-input" type="checkbox" id="view" value="view" v-model="settings.form_data.btn_enabled">
<label class="custom-control-label" for="view">
{{trans('messages.view')}}
</label>
</div>
<div class="custom-control custom-checkbox custom-control-inline">
<input class="custom-control-input" type="checkbox" id="delete" value="delete" v-model="settings.form_data.btn_enabled">
<label class="custom-control-label" for="delete">
{{trans('messages.delete')}}
</label>
</div>
</div>
</div>
<!-- submit as draft -->
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.form_submit_as_draft')}}
<tooltip-component :tooltip="trans('messages.form_submit_as_draft_tooltip')">
</tooltip-component>
</label>
<div class="col-sm-9">
<div class="custom-control custom-checkbox custom-control-inline">
<input class="custom-control-input" type="checkbox" id="is_enabled_draft_submit" value="1" v-model="settings.is_enabled_draft_submit">
<label class="custom-control-label" for="is_enabled_draft_submit">
{{trans('messages.enable')}}
</label>
</div>
</div>
</div>
<!-- /submit as draft -->
<!-- form scheduling settings -->
<h5 class="text-primary">
{{trans('messages.form_scheduling_setting')}}
</h5>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.scheduling')}}
</label>
<div class="col-sm-9">
<div class="custom-control custom-checkbox custom-control-inline">
<input class="custom-control-input" type="checkbox" id="scheduling" value="1" v-model="settings.form_scheduling.is_enabled">
<label class="custom-control-label" for="scheduling">
{{trans('messages.enable')}}
</label>
</div>
</div>
</div>
<div class="text-left text-muted offset-sm-3 mb-2" v-if="settings.form_scheduling.is_enabled">
<small>{{trans('messages.not_in_downloaded_code')}}</small><br/>
</div>
<div class="form-group row" v-show="settings.form_scheduling.is_enabled">
<div class="col-sm-9 offset-sm-3">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="start_date_time">
{{trans('messages.start_date_time')}}
<i class="fas fa-info-circle" data-toggle="tooltip" data-placement="top" data-html="true" :title="trans('messages.form_closed_start_date_time_tooltip')"></i>
</label>
<div class="input-group date" id="start_date_time" data-target-input="nearest">
<input type="text"
class="form-control datetimepicker-input"
data-target="#start_date_time"
data-toggle="datetimepicker"
name="start_date_time"
id="start_date_time"
readonly
/>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="end_date_time">
{{trans('messages.end_date_time')}} *
<i class="fas fa-info-circle" data-toggle="tooltip" data-placement="top" data-html="true" :title="trans('messages.form_closed_end_date_time_tooltip')"></i>
</label>
<div class="input-group date" id="end_date_time" data-target-input="nearest">
<input type="text"
class="form-control datetimepicker-input"
data-target="#end_date_time"
data-toggle="datetimepicker"
name="end_date_time"
id="end_date_time"
:required="settings.form_scheduling.is_enabled"
readonly
/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label for="closed_msg">
{{trans('messages.closed_msg')}} *
<i class="fas fa-info-circle" data-toggle="tooltip" data-placement="top" data-html="true" :title="trans('messages.form_closed_msg_tooltip')"></i>
</label>
<textarea
class="form-control summer_note" id="closed_msg"
rows="3"
v-model="settings.form_scheduling.closed_msg"
:required="settings.form_scheduling.is_enabled">
</textarea>
</div>
</div>
</div>
</div>
</div>
<!-- form submission reference-->
<h5 class="text-primary">
{{trans('messages.form_submission_numbering')}}
</h5>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.submission_numbering')}}
</label>
<div class="col-sm-9">
<div class="custom-control custom-checkbox custom-control-inline">
<input class="custom-control-input" type="checkbox" id="submission_numbering" value="1" v-model="settings.form_submision_ref.is_enabled">
<label class="custom-control-label" for="submission_numbering">
{{trans('messages.enable')}}
</label>
</div>
</div>
</div>
<div class="text-left text-muted offset-sm-3 mb-2" v-if="settings.form_submision_ref.is_enabled">
<small>{{trans('messages.not_in_downloaded_code')}}</small><br/>
</div>
<div class="form-group row" v-if="settings.form_submision_ref.is_enabled">
<div class="col-sm-9 offset-sm-3">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="prefix">
{{trans('messages.prefix')}}
</label>
<input type="text" class="form-control" id="prefix"
:placeholder="trans('messages.prefix')" name="settings.form_submision_ref.prefix" v-model="settings.form_submision_ref.prefix">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="suffix">
{{trans('messages.suffix')}}
</label>
<input type="text" class="form-control" id="suffix"
:placeholder="trans('messages.suffix')" name="settings.form_submision_ref.suffix" v-model="settings.form_submision_ref.suffix">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="start_no">
{{trans('messages.start_no')}} *
</label>
<input type="text" class="form-control" id="start_no"
:placeholder="trans('messages.start_no')" name="settings.form_submision_ref.start_no" required v-model="settings.form_submision_ref.start_no">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="min_digit">
{{trans('messages.min_digit')}} *
</label>
<select class="form-control" required
name="settings.form_submision_ref.min_digit"
v-model="settings.form_submision_ref.min_digit" id="min_digit">
<option v-for="i in 9" :key="i">
{{i}}
</option>
</select>
</div>
</div>
</div>
</div>
</div>
<!-- / form subission reference -->
<!-- Password protection-->
<h5 class="text-primary">
{{trans('messages.password_protection')}}
</h5>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.enable_password_protection')}}
</label>
<div class="col-sm-9">
<div class="custom-control custom-checkbox custom-control-inline">
<input class="custom-control-input" type="checkbox" id="enable_password_protection" value="1" v-model="settings.password_protection.is_enabled">
<label class="custom-control-label" for="enable_password_protection">
{{trans('messages.enable')}}
<i class="fas fa-info-circle"
data-toggle="tooltip"
:title="trans('messages.password_protection_help_text')"></i>
</label>
</div>
</div>
</div>
<div class="form-group row" v-if="settings.password_protection.is_enabled">
<div class="col-sm-9 offset-sm-3">
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label for="password">
{{trans('messages.password')}} *
</label>
<input type="text" class="form-control" id="password"
:placeholder="trans('messages.password')" name="settings.password_protection.password" v-model="settings.password_protection.password" required>
</div>
</div>
</div>
</div>
</div>
<!-- / Password protection -->
<!-- Pdf Design-->
<h5 class="text-primary">
{{trans('messages.pdf_design')}}
<i class="fas fa-info-circle"
data-toggle="tooltip"
:title="trans('messages.pdf_design_help_text')"></i>
</h5>
<div class="form-group row">
<label class="col-sm-3 col-form-label">
{{trans('messages.header')}}
</label>
<div class="col-sm-9">
<textarea id="pdf_design"
class="form-control pdf_design_summer_note"
v-model="settings.pdf_design.header"></textarea>
<small class="form-text">
{{trans('messages.tags')}} : {form_name}, {submission_date}
</small>
</div>
</div>
<!-- /Pdf Design -->
</div>
</template>
<script>
import tooltipComponent from './TooltipComponent';
export default {
components: {
tooltipComponent
},
props:{
settings: Object,
selected_elements: Array
},
data() {
const self = this;
return {
default_value:'',
primary:'btn-primary',
success:'btn-success',
warning:'btn-warning',
danger:'btn-danger',
btn_large:'btn-lg',
btn_sm:'btn-sm',
btn_default:'',
same_page:'same_page',
redirect:'redirect',
dropzone: null,
themes: [
{
'key' : 'default',
'value' : self.trans('messages.default')
},
{
'key' : 'sketchy',
'value' : 'Sketchy'
},
{
'key' : 'materia',
'value' : 'Material'
},
{
'key' : 'cerulean',
'value' : 'Cerulean'
},
{
'key' : 'lux',
'value' : 'Lux'
},
{
'key' : 'cosmo',
'value' : 'Cosmo'
},
{
'key' : 'lumen',
'value' : 'Lumen'
},
{
'key' : 'simplex',
'value' : 'Simplex'
},
{
'key' : 'flatly',
'value' : 'Flatly'
},
{
'key' : 'journal',
'value' : 'Journal'
},
{
'key' : 'litera',
'value' : 'Litera'
},
{
'key' : 'minty',
'value' : 'Minty'
},
{
'key' : 'pulse',
'value' : 'Pulse'
},
{
'key' : 'sandstone',
'value' : 'Sandstone'
},
{
'key' : 'spacelab',
'value' : 'Spacelab'
},
{
'key' : 'yeti',
'value' : 'Yeti'
},
]
}
},
mounted() {
this.initDropzone();
},
created() {
const self = this;
$(function() {
initialize_datetimepicker_for_form_scheduling();
//set values
$('input#start_date_time').val(self.settings.form_scheduling.start_date_time);
$('input#end_date_time').val(self.settings.form_scheduling.end_date_time);
//on change of dateTimePicker get values
$('div#start_date_time').on('change.datetimepicker', function() {
self.settings.form_scheduling.start_date_time = $('input#start_date_time').val();
});
$('div#end_date_time').on('change.datetimepicker', function() {
self.settings.form_scheduling.end_date_time = $('input#end_date_time').val();
});
$('#closed_msg').summernote({
placeholder: self.trans('messages.jot_down_here'),
height: 200,
callbacks: {
onChange: function(contents, editable) {
self.settings.form_scheduling.closed_msg = contents;
}
}
});
$('#pdf_design').summernote({
placeholder: self.trans('messages.design_pdf_header'),
height: 250,
tabsize: 2,
toolbar: [
['style', ['style']],
['font', ['bold', 'italic', 'underline', 'clear', 'strikethrough', 'superscript', 'subscript']],
['fontsize', ['fontsize']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['height', ['height']],
['insert', ['link', 'picture']]
],
callbacks: {
onChange: function(contents, editable) {
self.settings.pdf_design.header = contents;
}
}
});
});
},
methods:{
initDropzone() {
const self = this;
if (self.dropzone) {
self.dropzone.destroy();
}
self.dropzone = new Dropzone('div#fileUpload', {
url: `${APP.APP_URL}/file-upload`,
uploadMultiple: false,
maxFiles: 1,
acceptedFiles: '.jpeg,.jpg,.png,.gif,.JPEG,.JPG,.PNG,.GIF',
autoProcessQueue: true,
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
init: function() {
var prevFile;
this.on('addedfile', function() {
if (typeof prevFile !== 'undefined') {
this.removeFile(prevFile);
}
});
this.on('success', function(file, response) {
prevFile = file;
});
},
success: function(file, response) {
if (response.success == true) {
self.settings.color.image_path = response.path;
toastr.success(response.msg);
} else {
toastr.error(response.msg);
}
},
});
},
getIcons() {
var icons = this.getFontAwesomeIcons();
return icons;
}
}
}
</script>

View File

@@ -1,86 +0,0 @@
<template>
<section>
<!-- form layout -->
<label>
{{trans('messages.layout')}}
</label>
<div class="row">
<!-- classic -->
<div class="col-md-6">
<div class="card mb-1 bg-light-gray hvr-grow cursor-pointer"
:class="[_.includes(['classic'], choosen_layout) ? 'border-primary border-1 border-solid' : '']"
@click="setFormLayout('classic')">
<div class="card-body text-center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 121 125" class="jfWizard-list-item-icon-svg" width="187" height="204"><g fill="none" fill-rule="evenodd"><path d="M4.417 0h112a4 4 0 014 4v121h-120V4a4 4 0 014-4z" fill="#FFF" fill-rule="nonzero"></path><g transform="translate(10.417 13)"><path d="M17.001 31.122h79.14a2.858 2.858 0 010 5.716h-79.14a2.858 2.858 0 110-5.716z" fill="#DAE2ED" fill-rule="nonzero"></path><rect fill="#DAE2ED" fill-rule="nonzero" y="20.324" width="74.571" height="5.716" rx="2.858"></rect><rect fill="#DAE2ED" fill-rule="nonzero" width="99" height="8.257" rx="3"></rect><path d="M17.001 41.284h79.14a2.858 2.858 0 010 5.716h-79.14a2.858 2.858 0 110-5.716z" fill="#DAE2ED" fill-rule="nonzero"></path><g transform="translate(0 30.486)"><rect fill="#2F90FF" fill-rule="nonzero" width="6.429" height="6.351" rx="2"></rect><path d="M2.734 4.765a.33.33 0 01-.238-.103L1.304 3.424a.36.36 0 010-.495.328.328 0 01.477 0l.953.99L4.878 1.69a.328.328 0 01.477 0 .36.36 0 010 .496L2.972 4.662a.33.33 0 01-.238.103" fill="#FFF"></path></g><rect fill="#DAE2ED" fill-rule="nonzero" y="40.649" width="6.429" height="6.351" rx="2"></rect></g><g transform="translate(10.417 72)"><path d="M17.036 10.929h79.071a2.893 2.893 0 010 5.785H17.036a2.893 2.893 0 110-5.785zM2.893 0h68.786a2.893 2.893 0 110 5.786H2.893a2.893 2.893 0 010-5.786zm14.143 21.214h79.071a2.893 2.893 0 010 5.786H17.036a2.893 2.893 0 110-5.786z" fill="#DAE2ED" fill-rule="nonzero"></path><g transform="translate(0 10.286)"><rect fill="#2F90FF" fill-rule="nonzero" width="6.429" height="6.429" rx="2"></rect><path d="M2.734 4.823a.327.327 0 01-.238-.104L1.304 3.465a.367.367 0 010-.5.325.325 0 01.477 0l.953 1.002L4.878 1.71a.325.325 0 01.477 0 .367.367 0 010 .501L2.972 4.72a.328.328 0 01-.238.104" fill="#FFF"></path></g><rect fill="#DAE2ED" fill-rule="nonzero" y="20.571" width="6.429" height="6.429" rx="2"></rect><g transform="translate(0 20.571)"><rect fill="#2F90FF" fill-rule="nonzero" width="6.429" height="6.429" rx="2"></rect><path d="M2.734 4.823a.327.327 0 01-.238-.104L1.304 3.465a.367.367 0 010-.5.325.325 0 01.477 0l.953 1.002L4.878 1.71a.325.325 0 01.477 0 .367.367 0 010 .501L2.972 4.72a.328.328 0 01-.238.104" fill="#FFF"></path></g></g><rect fill="#2F90FF" fill-rule="nonzero" x="77.417" y="109" width="32" height="10" rx="4"></rect></g></svg>
</div>
</div>
<h6 class="text-center mt-0 mb-0">
{{trans('messages.classic_form')}}
</h6>
<p class="text-center mt-0 mb-0">
<small>{{trans('messages.classic_form_subtitle')}}</small>
</p>
</div>
<!-- card form -->
<div class="col-md-6">
<div class="card mb-1 bg-light-gray hvr-grow cursor-pointer"
:class="[_.includes(['card_form'], choosen_layout) ? 'border-primary border-1 border-solid' : '']"
@click="setFormLayout('card_form')">
<div class="card-body text-center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 121 92" class="jfWizard-list-item-icon-svg" width="166" height="146"><g fill="none" fill-rule="evenodd"><rect fill="#FFF" fill-rule="nonzero" x="7.934" width="105.131" height="62.153" rx="4"></rect><path d="M7.934 49.59h105.132v9.224a4 4 0 01-4 4H11.934a4 4 0 01-4-4V49.59z" fill="#2A5ACA" fill-rule="nonzero"></path><g transform="translate(15.208 11.24)"><rect fill="#DAE2ED" fill-rule="nonzero" x="10.579" y="11.24" width="80.667" height="5.951" rx="2.975"></rect><rect fill="#DAE2ED" fill-rule="nonzero" width="50.913" height="5.951" rx="2.975"></rect><path d="M13.555 21.82H88.27a2.975 2.975 0 010 5.95H13.555a2.975 2.975 0 010-5.95z" fill="#DAE2ED" fill-rule="nonzero"></path><g transform="translate(0 10.58)"><rect fill="#2F90FF" fill-rule="nonzero" width="6.612" height="6.612" rx="2"></rect><path d="M2.812 4.96a.337.337 0 01-.245-.107L1.34 3.564a.378.378 0 010-.515.334.334 0 01.49 0l.98 1.031 2.206-2.32a.334.334 0 01.49 0 .378.378 0 010 .515l-2.45 2.578a.337.337 0 01-.245.107" fill="#FFF"></path></g><rect fill="#DAE2ED" fill-rule="nonzero" y="21.158" width="6.612" height="6.612" rx="2"></rect></g><rect fill="#FFF" fill-rule="nonzero" width="121" height="62.153" rx="4"></rect><path d="M0 49.59h121v9.224a4 4 0 01-4 4H4a4 4 0 01-4-4V49.59z" fill="#51DCA9" fill-rule="nonzero"></path><g transform="translate(9.257 11.24)"><path d="M14.877 11.24H98.85a2.975 2.975 0 010 5.951H14.877a2.975 2.975 0 110-5.95zM2.975 0h50.913a2.975 2.975 0 110 5.95H2.975a2.975 2.975 0 110-5.95zm11.902 21.82H98.85a2.975 2.975 0 010 5.95H14.877a2.975 2.975 0 110-5.95z" fill="#DAE2ED" fill-rule="nonzero"></path><g transform="translate(0 10.58)"><rect fill="#2F90FF" fill-rule="nonzero" width="6.612" height="6.612" rx="2"></rect><path d="M2.812 4.96a.337.337 0 01-.245-.107L1.34 3.564a.378.378 0 010-.515.334.334 0 01.49 0l.98 1.031 2.206-2.32a.334.334 0 01.49 0 .378.378 0 010 .515l-2.45 2.578a.337.337 0 01-.245.107" fill="#FFF"></path></g><rect fill="#DAE2ED" fill-rule="nonzero" y="21.158" width="6.612" height="6.612" rx="2"></rect></g><path stroke="#319BF3" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M8.596 86.646h104.47"></path><circle stroke="#319BF3" stroke-width="1.5" fill="#51DCA9" fill-rule="nonzero" cx="60.831" cy="86.646" r="3.967"></circle><circle fill="#319BF3" fill-rule="nonzero" cx="9.918" cy="86.646" r="3.967"></circle><circle fill="#319BF3" fill-rule="nonzero" cx="111.743" cy="86.646" r="3.967"></circle></g></svg>
</div>
</div>
<h6 class="text-center mt-0 mb-0">
{{trans('messages.card_form')}}
</h6>
<p class="text-center mt-0 mb-0">
<small>{{trans('messages.card_form_subtitle')}}</small>
</p>
</div>
<div
v-if="_.some(selected_elements, {type: 'page_break'})"
class="col-md-12 text-center text-danger">
<i class="fas fa-info-circle mr-1"></i>
<small v-text="trans('messages.card_layout_disabled')"></small>
</div>
</div>
<!-- /form layout -->
</section>
</template>
<script>
export default {
props:{
selected_elements: Array,
settings:Object,
},
data(){
return {
layout: 'classic',
choosen_layout: 'classic'
}
},
created() {
const self = this;
if (_.isUndefined(self.settings.layout)) {
Vue.set(self.settings, 'layout', self.layout);
} else {
self.choosen_layout = self.settings.layout;
}
},
methods:{
setFormLayout(layout) {
const self = this;
if (!_.some(self.selected_elements, {type: 'page_break'})) {
self.settings.layout = layout;
self.choosen_layout = layout;
}
}
}
}
</script>
<style scoped>
svg{
max-width: 100%;
height: 100px;
}
</style>

View File

@@ -1,159 +0,0 @@
<template>
<div class="row mb-1">
<!-- remove pdf -->
<div class="card border-secondary mb-2"
v-show="!_.isEmpty(element.pdf)">
<div class="row">
<div class="col-md-4 mt-auto mb-auto">
<i class="fas fa-file-pdf fa-5x ml-1 text-primary"></i>
</div>
<div class="col-md-8">
<div class="card-body">
<p class="card-text text-truncate">
{{element.pdf}}
</p>
<p class="card-text text-warning cursor-pointer"
@click="removePdf">
{{trans('messages.remove_pdf')}}
</p>
</div>
</div>
</div>
</div>
<!-- dropzone -->
<div class="col-md-12 mb-1"
v-show="_.isEmpty(element.pdf)">
<label for="pdf_upload">
{{trans('messages.upload_pdf')}}
</label>
<div class="dropzone" id="pdf_upload"></div>
</div>
<!-- pdf properties -->
<div v-if="!_.isEmpty(element.pdf)">
<div class="mb-1">
<label>
{{trans('messages.width')}}
</label>
<div class="input-group mb-2">
<input type="number" class="form-control" v-model="element.width">
<div class="input-group-append">
<span class="input-group-text">
%
</span>
</div>
</div>
</div>
<div class="mb-1">
<label>
{{trans('messages.height')}}
</label>
<div class="input-group mb-2">
<input type="number" class="form-control" v-model="element.height">
<div class="input-group-append">
<span class="input-group-text">
px
</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
element: Object,
},
data(){
return{
MAX_UPLOAD_SIZE: APP.MAX_PDF_UPLOAD_SIZE,
dropzone_has_error: false,
dropzone_error_msg: ''
}
},
mounted() {
const self = this;
self.initPdfUploader();
},
methods:{
initPdfUploader() {
const self = this;
if (self.dropzone) {
self.dropzone.destroy();
}
self.dropzone = new Dropzone('div#pdf_upload', {
url: `${APP.APP_URL}/file-upload`,
addRemoveLinks: true,
uploadMultiple: false,
dictDefaultMessage: self.trans('messages.drop_a_pdf_here'),
maxFiles: 1,
maxFilesize: self.MAX_UPLOAD_SIZE,
acceptedFiles: '.pdf',
autoProcessQueue: true,
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
init: function() {
//function to be use on removeing a file
this.on("removedfile", function(file) {
$.ajax({
url: `${APP.APP_URL}/file-delete`,
data: { "file_name": file.uploaded_as },
type: "POST",
success: function(result) {
if(result.success == 1){
self.element.pdf = '';
} else {
toastr.error(result.msg);
}
}
});
});
this.on('success', function(file, response) {
self.dropzone_has_error = false;
self.dropzone_error_msg = '';
});
this.on("error", function(file, message) {
self.dropzone_has_error = true;
self.dropzone_error_msg = message;
});
},
success: function(file, response) {
if (response.success == true) {
file.uploaded_as = response.path;
self.element.pdf = response.path;
toastr.success(response.msg);
} else {
toastr.error(response.msg);
}
},
});
},
removePdf() {
const self = this;
Swal.fire({
title: 'Are you sure?',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, remove it!'
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
url: `${APP.APP_URL}/file-delete`,
data: { "file_name": self.element.pdf},
type: "POST",
success: function(result) {
if(result.success == 1){
self.element.pdf = '';
self.dropzone.removeAllFiles();
} else {
toastr.error(result.msg);
}
}
});
}
});
}
}
}
</script>

View File

@@ -1,29 +0,0 @@
<template>
<!-- Modal -->
<div class="modal fade" :id="`${element.name}_modal`" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">
{{element.label}}
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12"
v-html="element.popover_help_text.content">
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props:['element']
}
</script>

View File

@@ -1,520 +0,0 @@
<template>
<form id="show_form" v-bind="getCustomAttributes(form_custom_attributes)">
<div class="row">
<template
v-for="(element, index) in formFields">
<div
v-if="!_.includes(['page_break'], element.type)"
:key="index"
:class="[element.col ? element.col : 'col-md-12']"
v-show="togglePageVisibility(element.page_num)">
<fieldGenerator
:element="element"
:settings="settings"
:submitted_data="submitted_data"
:action="action"
:action-by="actionBy"
@apply_conditions="applyConditions">
</fieldGenerator>
</div>
</template>
</div>
<div class="g-recaptcha" :data-sitekey="settings.recaptcha.site_key" v-if="settings.recaptcha.is_enable"></div>
<div class="row"
:class="[!isCardFormLayout() ? settings.submit.btn_alignment : 'float-right']"
v-show="isSubmitVisible()">
<button v-if="!actionBy.length && settings.is_enabled_draft_submit"
formnovalidate="formnovalidate" type="submit" class="btn m-1 draft_btn"
:class="[settings.submit.btn_size, settings.submit.btn_style == 'default' ? 'btn-warning': 'btn-outline-warning']" name="status" value="incomplete">
<i class="fas " :class="settings.submit.btn_icon" v-if="settings.submit.btn_icon != 'none' && settings.submit.icon_position == 'left'"></i>
{{trans('messages.draft')}}
<i class="fas " :class="settings.submit.btn_icon" v-if="settings.submit.btn_icon != 'none' && settings.submit.icon_position == 'right'"></i>
</button>
<button type="submit" class="btn submit_btn ladda-button m-1" :class="[settings.submit.btn_color, settings.submit.btn_size]" data-style="expand-right" name="status" value="complete">
<i class="fas " :class="settings.submit.btn_icon" v-if="settings.submit.btn_icon != 'none' && settings.submit.icon_position == 'left'"></i>
<span class="btn_text ladda-label"> {{settings.submit.text}} </span>
<i class="fas " :class="settings.submit.btn_icon" v-if="settings.submit.btn_icon != 'none' && settings.submit.icon_position == 'right'"></i>
</button>
</div>
<div class="row" v-if="isCardFormLayout()">
<div class="col-md-12 d-flex justify-content-between">
<button v-show="current_page_number > 0" type="button"
class="btn bg-gradient-primary mr-auto"
@click="changePage('prev')">
<i class="fas fa-arrow-circle-left"></i> {{trans('messages.previous')}}
</button>
<button v-show="current_page_number < page_number" type="button"
class="btn bg-gradient-primary ml-auto" @click="changePage('next')">
{{trans('messages.next')}} <i class="fas fa-arrow-circle-right"></i>
</button>
</div>
</div>
<div class="alert alert-success mt-5 cursor-pointer" role="alert"
v-show="is_available_form_editable_url"
@click="copyLink">
<h4 class="alert-heading cursor-pointer"
v-html="trans('messages.form_editable_url')">
</h4>
<hr>
<span id="form_editable_url" class="cursor-pointer"></span>
<i class="far fa-copy float-right fa-lg cursor-pointer"></i>
</div>
</form>
</template>
<script>
import fieldGenerator from "./FieldGenerator";
export default{
props: ['form', 'actionBy', 'action'],
components: {
fieldGenerator
},
data() {
return {
schema: [],
form_parsed: [],
settings:{},
conditional_fields:[],
is_available_form_editable_url: false,
submitted_data:{},
token:'',
form_data_id: '',
form_custom_attributes : [],
formFields:[],
page_number: 0,
current_page_number:0,
is_page_active:'page#0',
};
},
mounted() {
const self = this;
let rules = {};
let messages = {};
self.formFields.forEach(function(field) {
if(!_.isEmpty(field?.allowed_input?.values)) {
let tempRule = {
remote: {
url: "/validate-input-value",
type: "post",
data: {
field: function() {
return JSON.stringify(field);
},
field_value: function() {
return $(`#${field.name}`).val();
}
}
}
}
let tempMsg = {
remote: field?.allowed_input?.error_msg || 'This value is not allowed.'
}
rules = {...rules, ...{[field.name]:tempRule}};
messages = {...messages, ...{[field.name]:tempMsg}};
}
});
var validator = $('#show_form').validate({
ignore: ".note-editor *, .hide",
rules: rules,
messages: messages,
submitHandler: function(form, e) {
e.preventDefault();
let disabled = $('#show_form :input:disabled').removeAttr('disabled');
var form_data = $('#show_form').serialize();
disabled.attr('disabled', 'disabled');
$("button.submit_btn, button.draft_btn").attr('disabled', 'disabled');
var status = $("input[name=status]").val();
if (status == 'complete') {
$("span.btn_text").text(self.settings.submit.loading_text);
var ladda = Ladda.create(document.querySelector('.ladda-button'));
} else if (status == 'incomplete') {
var ladda = Ladda.create(document.querySelector('.draft_btn'));
}
ladda.start();
if(typeof mpfg_form_submitted === "function"){
var form_array_data = $('#show_form').serializeArray();
mpfg_form_submitted(self.form_parsed.id, form_array_data);
}
let url = '/form-data/' + self.form_parsed.id + '?token=' + self.token + '&form_data_id=' + self.form_data_id;
// if (self.actionBy.length && self.actionBy === 'admin') {
// url = '/update/'+self.form_parsed.id+'/data/'+self.form_data_id;
// }
axios
.post(url, {form_data})
.then(function(response) {
//set token & form data id for form
if (status == 'incomplete') {
self.token = response.data.notification.token;
self.form_data_id = response.data.notification.form_data_id;
}
//remove disabled attr.
$("button.submit_btn, button.draft_btn").removeAttr("disabled");
//set submit text to submit btn
$("span.btn_text").text(self.settings.submit.text);
ladda.stop();
window.onbeforeunload = null;
if (response.data.success == true) {
//if notification action is redirect & status is compelete, redirect user to given url
if ((response.data.notification.post_submit_action === 'redirect') && (status == 'complete')) {
toastr.success(response.data.notification.success_msg);
window.parent.location = response.data.notification.redirect_url;
}
//if submit action is on same page & status is complete, replace url to form view url after 10 sec
if (status == 'complete' && !_.includes(['redirect'], response.data.notification.post_submit_action)) {
$('.card-body').html(response.data.notification.submission_msg);
if (response.data.notification.qr_code_text) {
try {
let qr_option = {
title: self.form_parsed.name,
titleFont: "bold 16px Arial",
titleColor: "#1b294b",
titleBackgroundColor: "#ffffff",
titleHeight: 20,
titleTop: 0,
text: response.data.notification.qr_code_text,
margin: 0,
width: 200,
height: 200,
quietZone: 20,
colorDark: "#1b294b",
colorLight: "#ffffffff",
correctLevel : QRCode.CorrectLevel.L
}
let qr_code = new QRCode(document.getElementById("qrcode"), qr_option);
$('#qrcode').find('canvas').attr('id', 'canvas');
let canvas = document.getElementById('canvas');
$('#download_qrcode').attr('href', canvas.toDataURL());
} catch (error) {
$('#qrcode, #download_qrcode').hide();
}
}
}
//if status is incomplete display form editable url
if (status == 'incomplete') {
toastr.success(response.data.notification.success_msg);
if (response.data.notification.form_editable_url) {
self.is_available_form_editable_url = true;
$('span#form_editable_url').text(response.data.notification.form_editable_url);
} else {
location.reload();
}
}
setTimeout(function() {
window.location.href = document.referrer;
}, 3000);
} else {
toastr.error(response.data.msg);
}
})
.catch(function(error) {
toastr.error(error);
});
}
});
//show aleart before page reloading
var form_obj = $('form#show_form');
var orig_forn_data = form_obj.serialize();
window.onbeforeunload = function() {
if($('form#show_form').length == 1){
if (form_obj.serialize() != orig_forn_data) {
return 'Are you sure?';
}
}
}
},
created() {
this.form_parsed = JSON.parse(this.form);
this.schema = this.form_parsed.schema.form;
this.settings = this.form_parsed.schema.settings;
this.conditional_fields = this.form_parsed.schema.conditional_fields;
this.form_custom_attributes = this.form_parsed.schema.form_attributes;
if (!_.isEmpty(this.form_parsed.data)) {
this.submitted_data = this.form_parsed.data[0].data;
this.token = this.form_parsed.data[0].token;
this.form_data_id = this.form_parsed.data[0].id;
}
this.getUrlParameters();
this.customizeFieldsArrayForLayout();
this.$eventBus.$on('callApplyConditions', (data) => {
this.applyConditions();
});
//if page break enabled, set layout 'card_form'
if (
this.form_parsed.schema.contains_page_break &&
this.form_parsed.schema.contains_page_break
) {
this.settings.layout = 'card_form';
}
},
beforeDestroy() {
this.$eventBus.$off('callApplyConditions');
},
methods: {
applyConditions(){
var schema = this.schema;
var is_condition_satisfied = true;
_.forEach(this.conditional_fields, function(conditional_field) {
_.forEach(conditional_field.conditions, function(element) {
if (!_.isNull(element.condition)) {
//find element as condition is present & if present check its type and find it value
var index = schema.findIndex(field => field.name === element.condition);
var form_element_value = '';
var logical_operator = element?.logical_operator || 'AND';
if (schema[index].type === 'radio') {
form_element_value = $('input[name='+element.condition+']:checked').val();
} else if (schema[index].type === 'checkbox') {
var checked_value = [];
$('input[name='+'"'+element.condition+'[]"'+']:checked').each(function() {
checked_value.push($(this).val());
});
if (_.includes(checked_value, element.value)) {
form_element_value = element.value;
}
} else if (schema[index].type === 'dropdown' && schema[index].multiselect) {
var selected_value = $('select[name='+'"'+element.condition+'[]"'+']').val();
if (_.includes(selected_value, element.value)) {
form_element_value = element.value;
}
} else if(schema[index].type === 'calendar') {
form_element_value = $('input[name='+element.condition+']').val();
} else if(schema[index].type === 'terms_and_condition') {
form_element_value = $('input[name='+element.condition+']').is(':checked') ? 'true' : 'false';
} else if(schema[index].type === 'switch') {
form_element_value = $('input[name='+element.condition+']').is(':checked') ? '1' : '0';
} else {
form_element_value = document.getElementById(element.condition).value;
}
//check if condition_satisfied or not
if(logical_operator == 'AND') {
if (element.operator == '==') {
if (form_element_value == element.value) {
is_condition_satisfied = true && is_condition_satisfied;
} else {
is_condition_satisfied = false;
}
} else if (element.operator == '!=') {
if (form_element_value != element.value) {
is_condition_satisfied = true && is_condition_satisfied;
} else {
is_condition_satisfied = false;
}
} else if (element.operator == 'empty') {
if (form_element_value.length == 0) {
is_condition_satisfied = true && is_condition_satisfied;
} else {
is_condition_satisfied = false;
}
} else if (element.operator == 'not_empty') {
if (form_element_value.length > 0) {
is_condition_satisfied = true && is_condition_satisfied;
} else {
is_condition_satisfied = false;
}
}
} else {
if (element.operator == '==') {
is_condition_satisfied = (form_element_value == element.value) || is_condition_satisfied;
} else if (element.operator == '!=') {
is_condition_satisfied = (form_element_value != element.value) || is_condition_satisfied;
} else if (element.operator == 'empty') {
is_condition_satisfied = (form_element_value.length == 0) || is_condition_satisfied;
} else if (element.operator == 'not_empty') {
is_condition_satisfied = (form_element_value.length > 0) || is_condition_satisfied;
}
}
}
});
//check if element is exist or not in schema
var index = schema.findIndex(element => element.name === conditional_field.element);
var action = conditional_field.action;
//if element exist then toggle conditional class
if (index !== -1) {
if (is_condition_satisfied) {
schema[index].conditional_class = conditional_field.action;
} else {
action = (conditional_field.action === 'show') ? 'hide' : 'show';
schema[index].conditional_class = (conditional_field.action === 'show') ? 'hide' : 'show'
}
is_condition_satisfied = true;
if(action == 'hide') {
if(schema[index]['type'] == 'radio') {
$(`input[name="${schema[index]['name']}"]`).prop('checked',false).trigger("change");
} else if(schema[index]['type'] == 'checkbox') {
$(`input[name="${schema[index]['name']}"]:checkbox`).prop('checked',false).trigger("change");
} else if(schema[index].type === 'dropdown' && schema[index].multiselect) {
$(`select[name="${schema[index]['name']}"]`).val('').trigger("change");
} else if(schema[index].type === 'terms_and_condition' || schema[index].type === 'switch') {
$(`input[name="${schema[index]['name']}"]`).prop('checked',false).trigger("change");
} else {
$(`input[name="${schema[index]['name']}"]`).val('').trigger("change");
}
}
}
});
},
getUrlParameters(){
const self = this;
let url = window.location.href;
let parameters = url.split('?')[1];
if (
!_.isEmpty(parameters) &&
_.isEmpty(self.submitted_data)
) {
let query_string = new URLSearchParams(parameters);
let data = {};
//convert query string to key value object
for (let parameter_pair of query_string.entries()) {
data[parameter_pair[0]] = parameter_pair[1];
}
self.submitted_data = data;
}
},
customizeFieldsArrayForLayout(){
const self = this;
let tempArrayEls = [];
if (!_.isEmpty(self.schema)) {
let maxIndex = self.schema.length - 1;
_.forEach(self.schema, function(element, index){
element['page_num'] = `page#${self.page_number}`;
tempArrayEls.push(element);
let nextEl = self.schema[index+1];//find next field
//increase page num if page break exists & not consecutive page break
if (
_.includes(['page_break'], element.type) &&
index > 0 //remove first index page break
&& nextEl &&
!_.includes(['page_break'], nextEl.type)
) {
self.page_number += 1;
}
//if layout is card.. & does not contain page break, insert one
if(
_.includes(['card_form'], self.settings.layout) &&
!self.form_parsed.schema.contains_page_break &&
(index < maxIndex)
) {
self.page_number += 1;
}
});
}
self.formFields = tempArrayEls;
},
isSubmitVisible() {
const self = this;
let is_visible = true;
if (self.isCardFormLayout() && (self.current_page_number < self.page_number)) {
is_visible = false;
}
return is_visible;
},
isCardFormLayout() {
const self = this;
if (
self.settings.layout &&
_.includes(['card_form'], self.settings.layout)
) {
return true
}
return false;
},
togglePageVisibility(page_num) {
const self = this;
if (!self.isCardFormLayout()) return true;
if (self.isCardFormLayout() && _.includes([self.is_page_active],page_num)) return true;
return false;
},
changePage(move) {
const self = this;
if (move == 'next') {
//validate fields before proceeding
let pageEles = self.formFields
.filter((el) => el.page_num == `page#${self.current_page_number}`);
let is_page_valid = true; //default true
for(let el of pageEles){
if (!_.includes(['page_break'], el.type)) {
is_page_valid = self.validateElement(el);
if(!is_page_valid) break;
}
}
//if page's field validated, move to next page
if (
is_page_valid &&
(self.current_page_number < self.page_number)
) {
self.current_page_number += 1;
self.is_page_active = `page#${self.current_page_number}`;
}
} else if (move == 'prev') {
if (self.current_page_number != 0) {
self.current_page_number -= 1;
self.is_page_active = `page#${self.current_page_number}`;
}
}
},
validateElement(element) {
const self = this;
let element_name = element.name;
let is_element_valid = true;
if (
_.includes(['checkbox', 'file_upload'], element.type) ||
(element.type == 'dropdown' && element.multiselect === true)
) {
element_name = element_name + '[]';
}
if (
!_.includes(['heading', 'hr', 'html_text'], element.type) &&
$('[name="' + element_name + '"]').rules()
) {
is_element_valid = $('[name="' + element_name + '"]').valid();
}
return is_element_valid;
},
copyLink(){
const self = this;
let textarea = document.createElement('textarea');
textarea.innerHTML = $("#form_editable_url").text();
document.body.appendChild(textarea);
textarea.select();
textarea.setSelectionRange(0, 99999);
document.execCommand("copy");
document.body.removeChild(textarea);
Swal.fire(self.trans('messages.link_copied'));
}
}
}
</script>

View File

@@ -1,63 +0,0 @@
<template>
<span>
<button type="button"
class="btn btn-sm btn-outline-primary ladda-button btn-test-smtp"
data-style="expand-right"
data-spinner-color="blue"
@click="testSmtp()">
<span class="ladda-label">
{{trans('messages.test_smtp_details')}}
</span>
</button>
<small class="form-text text-muted">
{{trans('messages.email_will_be_sent_to')}} {{this.details.from_address}}
</small>
</span>
</template>
<script>
export default {
props: ['details'],
methods:{
testSmtp(){
var isValid = true;
_.forEach(this.details, function(detail){
if (!_.isNull(detail)) {
isValid = true && isValid;
} else {
isValid = false;
}
});
if (isValid) {
var ladda = Ladda.create($('.btn-test-smtp')[0]);
ladda.start();
axios.get('/test-smtp', {
params:{
host: this.details.host,
port: this.details.port,
from_name: this.details.from_name,
from_address: this.details.from_address,
encryption: this.details.encryption,
username: this.details.username,
password: this.details.password
}
})
.then(function (response) {
ladda.stop();
alert(response.data.msg);
})
.catch(function (error) {
ladda.stop();
alert(error);
});
} else {
isValid = true;
alert('Please fill all the SMTP details.');
}
}
}
}
</script>

View File

@@ -1,10 +0,0 @@
<template>
<span class="text-success">
<i class="fas fa-info-circle ml-1" data-toggle="tooltip" :title="tooltip"></i>
</span>
</template>
<script>
export default {
props:['tooltip'],
}
</script>

View File

@@ -1,94 +0,0 @@
<template>
<section class="mt-3">
<div class="row">
<div class="col-md-12">
<div class="custom-control custom-checkbox">
<input type="checkbox"
class="custom-control-input"
id="is_enabled_webhook"
v-model="webhookInfo.is_enable"
value="1">
<label class="custom-control-label" for="is_enabled_webhook">
{{trans('messages.enable')}}
</label>
</div>
</div>
</div>
<template
v-if="webhookInfo.is_enable">
<div class="row">
<div class="col-md-12">
<div class="text-left text-muted text-center">
<small>
<i class="fa fa-info-circle"></i>
{{trans('messages.not_in_downloaded_code')}}
</small>
<br/>
</div>
</div>
</div>
<div class="form-group row">
<label for="webhook_url" class="col-sm-3 col-form-label">
{{trans('messages.webhook_url')}}:
<span class="error" v-if="webhookInfo.is_enable">*</span>
</label>
<div class="col-sm-9">
<div class="form-group">
<input type="url" class="form-control"
pattern="https://.*"
id="webhook_url"
:placeholder="trans('messages.webhook_url')"
name="webhookInfo.webhook_url"
:required="webhookInfo.is_enable"
v-model="webhookInfo.url">
</div>
</div>
</div>
<div class="form-group row">
<label for="secret_key" class="col-sm-3 col-form-label">
{{trans('messages.secret_key')}}:
<span class="error" v-if="webhookInfo.is_enable">*</span>
</label>
<div class="col-sm-9">
<div class="input-group">
<input type="text" class="form-control"
id="secret_key"
:placeholder="trans('messages.secret_key')"
name="webhookInfo.secret_key"
:required="webhookInfo.is_enable"
v-model="webhookInfo.secret_key"
readonly>
<div class="input-group-append">
<button type="button" class="btn btn-primary"
@click="generateSecretKey"
:disabled="loading">
{{trans('messages.generate_secret_key')}}
<i class="fas fa-spinner fa-pulse fa-spin ml-1" v-if="loading"></i>
</button>
</div>
</div>
</div>
</div>
</template>
</section>
</template>
<script>
export default {
props:['webhookInfo'],
data() {
return {
loading: false,
}
},
methods:{
generateSecretKey() {
const self = this;
self.loading = true;
self.webhookInfo.secret_key = self.generateRandomString(18);
setTimeout(() => {
self.loading = false;
}, 1000);
}
}
}
</script>