feat: add validation and error messages for custom HTML fields in portal settings
This commit is contained in:
parent
eaac65c973
commit
a4ff73d496
@ -7,7 +7,13 @@ import { useStore, useStoreGetters } from 'dashboard/composables/store';
|
|||||||
import { uploadFile } from 'dashboard/helper/uploadHelper';
|
import { uploadFile } from 'dashboard/helper/uploadHelper';
|
||||||
import { checkFileSizeLimit } from 'shared/helpers/FileHelper';
|
import { checkFileSizeLimit } from 'shared/helpers/FileHelper';
|
||||||
import { useVuelidate } from '@vuelidate/core';
|
import { useVuelidate } from '@vuelidate/core';
|
||||||
import { required, minLength, helpers, url } from '@vuelidate/validators';
|
import {
|
||||||
|
required,
|
||||||
|
minLength,
|
||||||
|
maxLength,
|
||||||
|
helpers,
|
||||||
|
url,
|
||||||
|
} from '@vuelidate/validators';
|
||||||
import { isValidSlug } from 'shared/helpers/Validators';
|
import { isValidSlug } from 'shared/helpers/Validators';
|
||||||
|
|
||||||
import Button from 'dashboard/components-next/button/Button.vue';
|
import Button from 'dashboard/components-next/button/Button.vue';
|
||||||
@ -35,6 +41,7 @@ const store = useStore();
|
|||||||
const getters = useStoreGetters();
|
const getters = useStoreGetters();
|
||||||
|
|
||||||
const MAXIMUM_FILE_UPLOAD_SIZE = 4; // in MB
|
const MAXIMUM_FILE_UPLOAD_SIZE = 4; // in MB
|
||||||
|
const CUSTOM_HTML_MAX_LENGTH = 15_000;
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
name: '',
|
name: '',
|
||||||
@ -84,6 +91,8 @@ const rules = {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
homePageLink: { url },
|
homePageLink: { url },
|
||||||
|
customHeadHtml: { maxLength: maxLength(CUSTOM_HTML_MAX_LENGTH) },
|
||||||
|
customBodyHtml: { maxLength: maxLength(CUSTOM_HTML_MAX_LENGTH) },
|
||||||
};
|
};
|
||||||
|
|
||||||
const v$ = useVuelidate(rules, state);
|
const v$ = useVuelidate(rules, state);
|
||||||
@ -102,6 +111,18 @@ const homePageLinkError = computed(() =>
|
|||||||
: ''
|
: ''
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const customHeadHtmlError = computed(() =>
|
||||||
|
v$.value.customHeadHtml.$error
|
||||||
|
? t('HELP_CENTER.PORTAL_SETTINGS.FORM.CUSTOM_HEAD_HTML.ERROR')
|
||||||
|
: ''
|
||||||
|
);
|
||||||
|
|
||||||
|
const customBodyHtmlError = computed(() =>
|
||||||
|
v$.value.customBodyHtml.$error
|
||||||
|
? t('HELP_CENTER.PORTAL_SETTINGS.FORM.CUSTOM_BODY_HTML.ERROR')
|
||||||
|
: ''
|
||||||
|
);
|
||||||
|
|
||||||
const isUpdatingPortal = computed(() => {
|
const isUpdatingPortal = computed(() => {
|
||||||
const slug = props.activePortal?.slug;
|
const slug = props.activePortal?.slug;
|
||||||
if (slug) return getters['portals/uiFlagsIn'].value(slug)?.isUpdating;
|
if (slug) return getters['portals/uiFlagsIn'].value(slug)?.isUpdating;
|
||||||
@ -375,10 +396,20 @@ const handleAvatarDelete = () => {
|
|||||||
t('HELP_CENTER.PORTAL_SETTINGS.FORM.CUSTOM_HEAD_HTML.PLACEHOLDER')
|
t('HELP_CENTER.PORTAL_SETTINGS.FORM.CUSTOM_HEAD_HTML.PLACEHOLDER')
|
||||||
"
|
"
|
||||||
rows="4"
|
rows="4"
|
||||||
class="w-full px-3 py-2 text-sm border rounded-lg resize-y border-n-weak bg-transparent dark:bg-transparent text-n-slate-12 placeholder:text-n-slate-9 focus:outline-none focus:ring-1 focus:ring-n-brand font-mono"
|
class="w-full px-3 py-2 text-sm border rounded-lg resize-y bg-transparent dark:bg-transparent text-n-slate-12 placeholder:text-n-slate-9 focus:outline-none focus:ring-1 font-mono"
|
||||||
|
:class="
|
||||||
|
customHeadHtmlError
|
||||||
|
? 'border-n-ruby-9 focus:ring-n-ruby-9'
|
||||||
|
: 'border-n-weak focus:ring-n-brand'
|
||||||
|
"
|
||||||
|
@input="v$.customHeadHtml.$touch()"
|
||||||
/>
|
/>
|
||||||
<span class="text-xs text-n-slate-11">
|
<span
|
||||||
|
class="text-xs"
|
||||||
|
:class="customHeadHtmlError ? 'text-n-ruby-9' : 'text-n-slate-11'"
|
||||||
|
>
|
||||||
{{
|
{{
|
||||||
|
customHeadHtmlError ||
|
||||||
t('HELP_CENTER.PORTAL_SETTINGS.FORM.CUSTOM_HEAD_HTML.HELP_TEXT')
|
t('HELP_CENTER.PORTAL_SETTINGS.FORM.CUSTOM_HEAD_HTML.HELP_TEXT')
|
||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
@ -399,10 +430,20 @@ const handleAvatarDelete = () => {
|
|||||||
t('HELP_CENTER.PORTAL_SETTINGS.FORM.CUSTOM_BODY_HTML.PLACEHOLDER')
|
t('HELP_CENTER.PORTAL_SETTINGS.FORM.CUSTOM_BODY_HTML.PLACEHOLDER')
|
||||||
"
|
"
|
||||||
rows="4"
|
rows="4"
|
||||||
class="w-full px-3 py-2 text-sm border rounded-lg resize-y border-n-weak bg-transparent dark:bg-transparent text-n-slate-12 placeholder:text-n-slate-9 focus:outline-none focus:ring-1 focus:ring-n-brand font-mono"
|
class="w-full px-3 py-2 text-sm border rounded-lg resize-y bg-transparent dark:bg-transparent text-n-slate-12 placeholder:text-n-slate-9 focus:outline-none focus:ring-1 font-mono"
|
||||||
|
:class="
|
||||||
|
customBodyHtmlError
|
||||||
|
? 'border-n-ruby-9 focus:ring-n-ruby-9'
|
||||||
|
: 'border-n-weak focus:ring-n-brand'
|
||||||
|
"
|
||||||
|
@input="v$.customBodyHtml.$touch()"
|
||||||
/>
|
/>
|
||||||
<span class="text-xs text-n-slate-11">
|
<span
|
||||||
|
class="text-xs"
|
||||||
|
:class="customBodyHtmlError ? 'text-n-ruby-9' : 'text-n-slate-11'"
|
||||||
|
>
|
||||||
{{
|
{{
|
||||||
|
customBodyHtmlError ||
|
||||||
t('HELP_CENTER.PORTAL_SETTINGS.FORM.CUSTOM_BODY_HTML.HELP_TEXT')
|
t('HELP_CENTER.PORTAL_SETTINGS.FORM.CUSTOM_BODY_HTML.HELP_TEXT')
|
||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -754,12 +754,14 @@
|
|||||||
"CUSTOM_HEAD_HTML": {
|
"CUSTOM_HEAD_HTML": {
|
||||||
"LABEL": "Custom head HTML",
|
"LABEL": "Custom head HTML",
|
||||||
"PLACEHOLDER": "Add custom HTML to the <head> section (e.g., meta tags, analytics, custom CSS)",
|
"PLACEHOLDER": "Add custom HTML to the <head> section (e.g., meta tags, analytics, custom CSS)",
|
||||||
"HELP_TEXT": "This code will be injected into the <head> of your portal pages"
|
"HELP_TEXT": "This code will be injected into the <head> of your portal pages",
|
||||||
|
"ERROR": "Custom head HTML must be less than 15,000 characters"
|
||||||
},
|
},
|
||||||
"CUSTOM_BODY_HTML": {
|
"CUSTOM_BODY_HTML": {
|
||||||
"LABEL": "Custom body HTML",
|
"LABEL": "Custom body HTML",
|
||||||
"PLACEHOLDER": "Add custom HTML before </body> (e.g., scripts, tracking pixels, widgets)",
|
"PLACEHOLDER": "Add custom HTML before </body> (e.g., scripts, tracking pixels, widgets)",
|
||||||
"HELP_TEXT": "This code will be injected before the closing </body> tag of your portal pages"
|
"HELP_TEXT": "This code will be injected before the closing </body> tag of your portal pages",
|
||||||
|
"ERROR": "Custom body HTML must be less than 15,000 characters"
|
||||||
},
|
},
|
||||||
"SAVE_CHANGES": "Save changes"
|
"SAVE_CHANGES": "Save changes"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -754,12 +754,14 @@
|
|||||||
"CUSTOM_HEAD_HTML": {
|
"CUSTOM_HEAD_HTML": {
|
||||||
"LABEL": "HTML personalizado no head",
|
"LABEL": "HTML personalizado no head",
|
||||||
"PLACEHOLDER": "Adicione HTML personalizado na seção <head> (ex: meta tags, analytics, CSS personalizado)",
|
"PLACEHOLDER": "Adicione HTML personalizado na seção <head> (ex: meta tags, analytics, CSS personalizado)",
|
||||||
"HELP_TEXT": "Este código será injetado no <head> das páginas do seu portal"
|
"HELP_TEXT": "Este código será injetado no <head> das páginas do seu portal",
|
||||||
|
"ERROR": "O HTML personalizado do head deve ter menos de 15.000 caracteres"
|
||||||
},
|
},
|
||||||
"CUSTOM_BODY_HTML": {
|
"CUSTOM_BODY_HTML": {
|
||||||
"LABEL": "HTML personalizado no body",
|
"LABEL": "HTML personalizado no body",
|
||||||
"PLACEHOLDER": "Adicione HTML personalizado antes do </body> (ex: scripts, pixels de rastreamento, widgets)",
|
"PLACEHOLDER": "Adicione HTML personalizado antes do </body> (ex: scripts, pixels de rastreamento, widgets)",
|
||||||
"HELP_TEXT": "Este código será injetado antes da tag de fechamento </body> das páginas do seu portal"
|
"HELP_TEXT": "Este código será injetado antes da tag de fechamento </body> das páginas do seu portal",
|
||||||
|
"ERROR": "O HTML personalizado do body deve ter menos de 15.000 caracteres"
|
||||||
},
|
},
|
||||||
"SAVE_CHANGES": "Salvar Alterações"
|
"SAVE_CHANGES": "Salvar Alterações"
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user