feat: Add regex validation on form message inputs (#2317)
Co-authored-by: Nithin David Thomas <webofnithin@gmail.com> Co-authored-by: Sojan <sojan@pepalo.com>
This commit is contained in:
parent
0a087c95fd
commit
67ce6f5704
5 changed files with 84 additions and 14 deletions
|
@ -44,6 +44,9 @@ Metrics/BlockLength:
|
|||
- '**/routes.rb'
|
||||
- 'config/environments/*'
|
||||
- db/schema.rb
|
||||
Metrics/ModuleLength:
|
||||
Exclude:
|
||||
- lib/woot_message_seeder.rb
|
||||
Rails/ApplicationController:
|
||||
Exclude:
|
||||
- 'app/controllers/api/v1/widget/messages_controller.rb'
|
||||
|
|
|
@ -1,12 +1,33 @@
|
|||
<template>
|
||||
<div class="form chat-bubble agent">
|
||||
<form @submit.prevent="onSubmit">
|
||||
<div v-for="item in items" :key="item.key" class="form-block">
|
||||
<div
|
||||
v-for="item in items"
|
||||
:key="item.key"
|
||||
class="form-block"
|
||||
:class="{
|
||||
'has-submitted': hasSubmitted,
|
||||
}"
|
||||
>
|
||||
<label>{{ item.label }}</label>
|
||||
<input
|
||||
v-if="item.type === 'email' || item.type === 'text'"
|
||||
v-if="item.type === 'email'"
|
||||
v-model="formValues[item.name]"
|
||||
:type="item.type"
|
||||
:pattern="item.regex"
|
||||
:title="item.title"
|
||||
:required="item.required && 'required'"
|
||||
:name="item.name"
|
||||
:placeholder="item.placeholder"
|
||||
:disabled="!!submittedValues.length"
|
||||
/>
|
||||
<input
|
||||
v-else-if="item.type === 'text'"
|
||||
v-model="formValues[item.name]"
|
||||
:required="item.required && 'required'"
|
||||
:pattern="item.pattern"
|
||||
:title="item.title"
|
||||
:type="item.type"
|
||||
:name="item.name"
|
||||
:placeholder="item.placeholder"
|
||||
:disabled="!!submittedValues.length"
|
||||
|
@ -14,6 +35,8 @@
|
|||
<textarea
|
||||
v-else-if="item.type === 'text_area'"
|
||||
v-model="formValues[item.name]"
|
||||
:required="item.required && 'required'"
|
||||
:title="item.title"
|
||||
:name="item.name"
|
||||
:placeholder="item.placeholder"
|
||||
:disabled="!!submittedValues.length"
|
||||
|
@ -21,6 +44,7 @@
|
|||
<select
|
||||
v-else-if="item.type === 'select'"
|
||||
v-model="formValues[item.name]"
|
||||
:required="item.required && 'required'"
|
||||
>
|
||||
<option
|
||||
v-for="option in item.options"
|
||||
|
@ -30,13 +54,16 @@
|
|||
{{ option.label }}
|
||||
</option>
|
||||
</select>
|
||||
<span class="error-message">
|
||||
{{ item.pattern_error || $t('CHAT_FORM.INVALID.FIELD') }}
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
v-if="!submittedValues.length"
|
||||
class="button block"
|
||||
type="submit"
|
||||
:disabled="!isFormValid"
|
||||
:style="{ background: widgetColor, borderColor: widgetColor }"
|
||||
@click="onSubmitClick"
|
||||
>
|
||||
{{ buttonLabel || $t('COMPONENTS.FORM_BUBBLE.SUBMIT') }}
|
||||
</button>
|
||||
|
@ -64,6 +91,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
formValues: {},
|
||||
hasSubmitted: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -84,6 +112,9 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
onSubmitClick() {
|
||||
this.hasSubmitted = true;
|
||||
},
|
||||
onSubmit() {
|
||||
if (!this.isFormValid) {
|
||||
return;
|
||||
|
@ -171,5 +202,29 @@ export default {
|
|||
.button {
|
||||
font-size: $font-size-default;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
display: none;
|
||||
margin-top: $space-smaller;
|
||||
color: $color-error;
|
||||
}
|
||||
|
||||
.has-submitted {
|
||||
input:invalid {
|
||||
border: 1px solid $color-error;
|
||||
}
|
||||
|
||||
input:invalid + .error-message {
|
||||
display: block;
|
||||
}
|
||||
|
||||
textarea:invalid {
|
||||
border: 1px solid $color-error;
|
||||
}
|
||||
|
||||
textarea:invalid + .error-message {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -51,5 +51,10 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"FILE_SIZE_LIMIT": "File exceeds the {MAXIMUM_FILE_UPLOAD_SIZE} attachment limit"
|
||||
"FILE_SIZE_LIMIT": "File exceeds the {MAXIMUM_FILE_UPLOAD_SIZE} attachment limit",
|
||||
"CHAT_FORM": {
|
||||
"INVALID": {
|
||||
"FIELD": "Invalid field"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ class ContentAttributeValidator < ActiveModel::Validator
|
|||
ALLOWED_SELECT_ITEM_KEYS = [:title, :value].freeze
|
||||
ALLOWED_CARD_ITEM_KEYS = [:title, :description, :media_url, :actions].freeze
|
||||
ALLOWED_CARD_ITEM_ACTION_KEYS = [:text, :type, :payload, :uri].freeze
|
||||
ALLOWED_FORM_ITEM_KEYS = [:type, :placeholder, :label, :name, :options, :default].freeze
|
||||
ALLOWED_FORM_ITEM_KEYS = [:type, :placeholder, :label, :name, :options, :default, :required, :pattern, :title, :pattern_error].freeze
|
||||
ALLOWED_ARTICLE_KEYS = [:title, :description, :link].freeze
|
||||
|
||||
def validate(record)
|
||||
|
|
|
@ -74,18 +74,25 @@ module WootMessageSeeder
|
|||
message_type: :template,
|
||||
content_type: 'form',
|
||||
content: 'form',
|
||||
content_attributes: {
|
||||
items: [
|
||||
{ name: 'email', placeholder: 'Please enter your email', type: 'email', label: 'Email' },
|
||||
{ name: 'text_area', placeholder: 'Please enter text', type: 'text_area', label: 'Large Text' },
|
||||
{ name: 'text', placeholder: 'Please enter text', type: 'text', label: 'text', default: 'defaut value' },
|
||||
{ name: 'select', label: 'Select Option', type: 'select', options: [{ label: '🌯 Burito', value: 'Burito' },
|
||||
{ label: '🍝 Pasta', value: 'Pasta' }] }
|
||||
]
|
||||
}
|
||||
content_attributes: sample_form
|
||||
)
|
||||
end
|
||||
|
||||
def self.sample_form
|
||||
{
|
||||
"items": [
|
||||
{ "name": 'email', "placeholder": 'Please enter your email', "type": 'email', "label": 'Email', "required": 'required',
|
||||
"pattern_error": 'Please fill this field', "pattern": '^[^\s@]+@[^\s@]+\.[^\s@]+$' },
|
||||
{ "name": 'text_area', "placeholder": 'Please enter text', "type": 'text_area', "label": 'Large Text', "required": 'required',
|
||||
"pattern_error": 'Please fill this field' },
|
||||
{ "name": 'text', "placeholder": 'Please enter text', "type": 'text', "label": 'text', "default": 'defaut value', "required": 'required',
|
||||
"pattern": '^[a-zA-Z ]*$', "pattern_error": 'Only alphabets are allowed' },
|
||||
{ "name": 'select', "label": 'Select Option', "type": 'select', "options": [{ "label": '🌯 Burito', "value": 'Burito' },
|
||||
{ "label": '🍝 Pasta', "value": 'Pasta' }] }
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def self.create_sample_articles_message(conversation)
|
||||
Message.create!(
|
||||
account: conversation.account,
|
||||
|
|
Loading…
Reference in a new issue