diff --git a/app/frontend/src/components/admin/FormComponentsProactiveHelp.vue b/app/frontend/src/components/admin/FormComponentsProactiveHelp.vue
index 844c89b78..e424f2922 100644
--- a/app/frontend/src/components/admin/FormComponentsProactiveHelp.vue
+++ b/app/frontend/src/components/admin/FormComponentsProactiveHelp.vue
@@ -1,172 +1,80 @@
-
-
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/app/frontend/src/components/forms/PrintOptions.vue b/app/frontend/src/components/forms/PrintOptions.vue
index 99c7a3451..e6b0c4d46 100644
--- a/app/frontend/src/components/forms/PrintOptions.vue
+++ b/app/frontend/src/components/forms/PrintOptions.vue
@@ -1,7 +1,7 @@
@@ -446,6 +466,7 @@ defineExpose({
value="upload"
>
0) {
- if (sort[0].key === 'date') {
- sortBy.value.column = 'createdAt';
- } else if (sort[0].key === 'submitter') {
- sortBy.value.column = 'createdBy';
- } else if (sort[0].key === 'status') {
- sortBy.value.column = 'formSubmissionStatusCode';
+ if (sortBy?.length > 0) {
+ if (sortBy[0].key === 'date') {
+ sort.value.column = 'createdAt';
+ } else if (sortBy[0].key === 'submitter') {
+ sort.value.column = 'createdBy';
+ } else if (sortBy[0].key === 'status') {
+ sort.value.column = 'formSubmissionStatusCode';
} else {
- sortBy.value.column = sort[0].key;
+ sort.value.column = sortBy[0].key;
}
- sortBy.value.order = sort[0].order;
+ sort.value.order = sortBy[0].order;
} else {
- sortBy.value = {};
+ sort.value = {};
}
- if (itemsPP) {
- itemsPerPage.value = itemsPP;
+ if (itemsPerPage) {
+ itemsPP.value = itemsPerPage;
}
if (!firstDataLoad.value) {
await refreshSubmissions();
@@ -336,11 +336,11 @@ async function updateTableOptions({ pg, itemsPP, sort }) {
async function getSubmissionData() {
let criteria = {
formId: properties.formId,
- itemsPerPage: itemsPerPage.value,
- page: page.value - 1,
+ itemsPerPage: itemsPP.value,
+ page: currentPage.value - 1,
filterformSubmissionStatusCode: true,
paginationEnabled: true,
- sortBy: sortBy.value,
+ sortBy: sort.value,
search: search.value,
searchEnabled: search.value.length > 0 ? true : false,
createdAt: Object.values({
@@ -539,11 +539,11 @@ defineExpose({
getSubmissionData,
handleSearch,
HEADERS,
- itemsPerPage,
+ itemsPP,
multiDeleteMessage,
multiRestoreMessage,
onShowColumnDialog,
- page,
+ currentPage,
restoreSub,
serverItems,
showColumnsDialog,
@@ -554,7 +554,7 @@ defineExpose({
singleRestoreMessage,
singleSubmissionDelete,
singleSubmissionRestore,
- sortBy,
+ sort,
updateFilter,
userColumns,
USER_PREFERENCES,
@@ -691,7 +691,7 @@ defineExpose({
hover
:items-length="totalSubmissions"
class="submissions-table"
- :items-per-page="itemsPerPage"
+ :items-per-page="itemsPP"
:headers="HEADERS"
item-value="submissionId"
:items="serverItems"
diff --git a/app/frontend/src/components/forms/manage/DocumentTemplate.vue b/app/frontend/src/components/forms/manage/DocumentTemplate.vue
index fa1f8d21a..a15b0ce28 100644
--- a/app/frontend/src/components/forms/manage/DocumentTemplate.vue
+++ b/app/frontend/src/components/forms/manage/DocumentTemplate.vue
@@ -27,6 +27,7 @@ const headers = ref([
const loading = ref(true);
const isFileInputEmpty = ref(true);
const isValidFile = ref(true);
+const isValidSize = ref(true);
const techdocsLinkTemplateUpload = ref(
'https://developer.gov.bc.ca/docs/default/component/chefs-techdocs/Capabilities/Functionalities/CDOGS-Template-Upload/'
);
@@ -38,6 +39,7 @@ const notificationStore = useNotificationStore();
const { form, isRTL } = storeToRefs(useFormStore());
const validationRules = computed(() => [
+ isValidSize.value || t('trans.documentTemplate.fileSizeError'),
isValidFile.value || t('trans.documentTemplate.invalidFileMessage'),
]);
@@ -83,6 +85,15 @@ function handleFileInput(event) {
if (event && event.length > 0) {
isFileInputEmpty.value = false;
uploadedFile = event[0];
+
+ // validate file size
+ if (uploadedFile.size > 25000000) {
+ isValidSize.value = false;
+ } else {
+ isValidSize.value = true;
+ }
+
+ // validate file extension
const fileExtension = event[0].name.split('.').pop();
if (validFileExtensions.includes(fileExtension)) {
isValidFile.value = true;
@@ -92,6 +103,7 @@ function handleFileInput(event) {
} else {
isFileInputEmpty.value = true;
isValidFile.value = true;
+ isValidSize.value = true;
}
}
@@ -120,12 +132,21 @@ async function handleFileUpload() {
...NotificationTypes.SUCCESS,
});
} catch (e) {
- notificationStore.addNotification({
- text: t('trans.documentTemplate.uploadError'),
- consoleError: t('trans.documentTemplate.uploadError', {
- error: e.message,
- }),
- });
+ if (e.response.status === 413) {
+ notificationStore.addNotification({
+ text: t('trans.documentTemplate.fileSizeError'),
+ consoleError: t('trans.documentTemplate.fileSizeError', {
+ error: e.message,
+ }),
+ });
+ } else {
+ notificationStore.addNotification({
+ text: t('trans.documentTemplate.uploadError'),
+ consoleError: t('trans.documentTemplate.uploadError', {
+ error: e.message,
+ }),
+ });
+ }
} finally {
loading.value = false;
}
@@ -196,6 +217,7 @@ defineExpose({
handleFileInput,
isFileInputEmpty,
isValidFile,
+ isValidSize,
uploadedFile,
});
@@ -322,7 +344,10 @@ defineExpose({
-import { mapActions, mapState } from 'pinia';
+
@@ -143,7 +149,7 @@ export default {
hide-default-header
hide-default-footer
disable-pagination
- :items="layoutList"
+ :items="formComponentNames"
:loading="loading"
:loading-text="$t('trans.generalLayout.loadingText')"
:lang="locale"
@@ -164,7 +170,7 @@ export default {
size="small"
variant="text"
:title="$t('trans.generalLayout.edit')"
- @click="onOpenDialog(item.componentName)"
+ @click="onOpenEditDialog(item.componentName)"
>
@@ -195,55 +201,45 @@ export default {
-
-
- {{
- publish[index]
- ? $t('trans.generalLayout.published')
- : $t('trans.generalLayout.unpublished')
- }}
-
+
+ {{
+ publish[index]
+ ? $t('trans.generalLayout.published')
+ : $t('trans.generalLayout.unpublished')
+ }}
+
+
diff --git a/app/frontend/src/components/infolinks/ProactiveHelpDialog.vue b/app/frontend/src/components/infolinks/ProactiveHelpDialog.vue
index 99b54a85b..3aff3a9d8 100644
--- a/app/frontend/src/components/infolinks/ProactiveHelpDialog.vue
+++ b/app/frontend/src/components/infolinks/ProactiveHelpDialog.vue
@@ -1,131 +1,154 @@
-
@@ -173,7 +196,7 @@ export default {
>
{{ $t('trans.proactiveHelpDialog.componentName') }}
-
+
diff --git a/app/frontend/src/components/infolinks/ProactiveHelpPreviewDialog.vue b/app/frontend/src/components/infolinks/ProactiveHelpPreviewDialog.vue
index dc66afe6d..ded3203ff 100644
--- a/app/frontend/src/components/infolinks/ProactiveHelpPreviewDialog.vue
+++ b/app/frontend/src/components/infolinks/ProactiveHelpPreviewDialog.vue
@@ -1,40 +1,31 @@
-
diff --git a/app/frontend/src/internationalization/trans/chefs/ar/ar.json b/app/frontend/src/internationalization/trans/chefs/ar/ar.json
index 949e70408..f661cf1b6 100644
--- a/app/frontend/src/internationalization/trans/chefs/ar/ar.json
+++ b/app/frontend/src/internationalization/trans/chefs/ar/ar.json
@@ -84,7 +84,8 @@
"deleteSuccess": "تم حذف القالب بنجاح.",
"deleteError": "حدث خطأ أثناء حذف القالب.",
"fetchError": "حدث خطأ أثناء جلب القالب.",
- "info": "قم بتحميل قالب لاستخدام خدمة توليد الوثائق المشتركة (CDOGS)"
+ "info": "قم بتحميل قالب لاستخدام خدمة توليد الوثائق المشتركة (CDOGS)",
+ "fileSizeError": "يجب أن يكون حجم الملف أقل من 25 ميغابايت."
},
"formSettings": {
"pressToAddMultiEmail": "اضغط على مفتاح الإدخال أو ، أو مسافة لإضافة عناوين بريد إلكتروني متعددة",
diff --git a/app/frontend/src/internationalization/trans/chefs/de/de.json b/app/frontend/src/internationalization/trans/chefs/de/de.json
index c35fa2d65..c2115567f 100644
--- a/app/frontend/src/internationalization/trans/chefs/de/de.json
+++ b/app/frontend/src/internationalization/trans/chefs/de/de.json
@@ -84,7 +84,8 @@
"deleteSuccess": "Vorlage erfolgreich gelöscht.",
"deleteError": "Beim Löschen der Vorlage ist ein Fehler aufgetreten.",
"fetchError": "Beim Abrufen der Vorlage ist ein Fehler aufgetreten.",
- "info": "Laden Sie eine Vorlage hoch, um den Gemeinsamen Dokumenterstellungsdienst (CDOGS) zu verwenden"
+ "info": "Laden Sie eine Vorlage hoch, um den Gemeinsamen Dokumenterstellungsdienst (CDOGS) zu verwenden",
+ "fileSizeError": "Die Dateigröße muss weniger als 25 MB betragen."
},
"formSettings": {
"pressToAddMultiEmail": "Drücken Sie die Eingabetaste oder die Leertaste oder , um mehrere E-Mail-Adressen hinzuzufügen",
diff --git a/app/frontend/src/internationalization/trans/chefs/en/en.json b/app/frontend/src/internationalization/trans/chefs/en/en.json
index 182747575..74196626e 100644
--- a/app/frontend/src/internationalization/trans/chefs/en/en.json
+++ b/app/frontend/src/internationalization/trans/chefs/en/en.json
@@ -82,7 +82,8 @@
"deleteSuccess": "Template deleted successfully.",
"deleteError": "An error occurred while deleting the template.",
"fetchError": "An error occurred while fetching the template.",
- "info": "Upload a template to use the Common Document Generation Service (CDOGS)"
+ "info": "Upload a template to use the Common Document Generation Service (CDOGS)",
+ "fileSizeError": "File size must be less than 25MB."
},
"eventStreamConfig": {
"info": "Configure Event Stream for your form.",
diff --git a/app/frontend/src/internationalization/trans/chefs/es/es.json b/app/frontend/src/internationalization/trans/chefs/es/es.json
index aa005e6c0..22ddb28aa 100644
--- a/app/frontend/src/internationalization/trans/chefs/es/es.json
+++ b/app/frontend/src/internationalization/trans/chefs/es/es.json
@@ -84,7 +84,8 @@
"deleteSuccess": "Plantilla eliminada exitosamente.",
"deleteError": "Ocurrió un error al eliminar la plantilla.",
"fetchError": "Ocurrió un error al obtener la plantilla.",
- "info": "Sube una plantilla para usar el Servicio de Generación de Documentos Comunes (CDOGS)"
+ "info": "Sube una plantilla para usar el Servicio de Generación de Documentos Comunes (CDOGS)",
+ "fileSizeError": "El tamaño del archivo debe ser menor de 25 MB."
},
"formSettings": {
"pressToAddMultiEmail": "Presiona enter o , o espacio para agregar varias direcciones de correo electrónico",
diff --git a/app/frontend/src/internationalization/trans/chefs/fa/fa.json b/app/frontend/src/internationalization/trans/chefs/fa/fa.json
index 29cd29556..be613f2e8 100644
--- a/app/frontend/src/internationalization/trans/chefs/fa/fa.json
+++ b/app/frontend/src/internationalization/trans/chefs/fa/fa.json
@@ -84,7 +84,8 @@
"deleteSuccess": "قالب با موفقیت حذف شد.",
"deleteError": "خطایی در هنگام حذف قالب رخ داد.",
"fetchError": "خطایی در هنگام دریافت قالب رخ داد.",
- "info": "قالبی را بارگذاری کنید تا از خدمات تولید سند مشترک (CDOGS) استفاده کنید"
+ "info": "قالبی را بارگذاری کنید تا از خدمات تولید سند مشترک (CDOGS) استفاده کنید",
+ "fileSizeError": "اندازه فایل باید کمتر از 25 مگابایت باشد."
},
"formSettings": {
"pressToAddMultiEmail": "برای افزودن چندین آدرس ایمیل، اینتر یا ، یا فاصله را فشار دهید",
diff --git a/app/frontend/src/internationalization/trans/chefs/fr/fr.json b/app/frontend/src/internationalization/trans/chefs/fr/fr.json
index 0d287188f..11a37d431 100644
--- a/app/frontend/src/internationalization/trans/chefs/fr/fr.json
+++ b/app/frontend/src/internationalization/trans/chefs/fr/fr.json
@@ -84,7 +84,8 @@
"deleteSuccess": "Modèle supprimé avec succès.",
"deleteError": "Une erreur s'est produite lors de la suppression du modèle.",
"fetchError": "Une erreur s'est produite lors de la récupération du modèle.",
- "info": "Téléchargez un modèle pour utiliser le Service de Génération de Documents Communs (CDOGS)"
+ "info": "Téléchargez un modèle pour utiliser le Service de Génération de Documents Communs (CDOGS)",
+ "fileSizeError": "La taille du fichier doit être inférieure à 25 Mo."
},
"formSettings": {
"pressToAddMultiEmail": "Appuyez sur entrée ou , ou espace pour ajouter plusieurs adresses e-mail",
diff --git a/app/frontend/src/internationalization/trans/chefs/hi/hi.json b/app/frontend/src/internationalization/trans/chefs/hi/hi.json
index bf23ba611..bf2b7c9c8 100644
--- a/app/frontend/src/internationalization/trans/chefs/hi/hi.json
+++ b/app/frontend/src/internationalization/trans/chefs/hi/hi.json
@@ -84,7 +84,8 @@
"deleteSuccess": "टेम्पलेट सफलतापूर्वक हटाया गया।",
"deleteError": "टेम्पलेट हटाते समय एक त्रुटि हुई।",
"fetchError": "टेम्पलेट प्राप्त करते समय एक त्रुटि हुई।",
- "info": "कॉमन डॉक्युमेंट जनरेशन सर्विस (CDOGS) का उपयोग करने के लिए एक टेम्पलेट अपलोड करें"
+ "info": "कॉमन डॉक्युमेंट जनरेशन सर्विस (CDOGS) का उपयोग करने के लिए एक टेम्पलेट अपलोड करें",
+ "fileSizeError": "फ़ाइल का आकार 25MB से कम होना चाहिए।"
},
"formSettings": {
"pressToAddMultiEmail": "एकाधिक ईमेल पते जोड़ने के लिए एंटर या , या स्पेस दबाएँ",
diff --git a/app/frontend/src/internationalization/trans/chefs/it/it.json b/app/frontend/src/internationalization/trans/chefs/it/it.json
index d614f6798..077d2f0cb 100644
--- a/app/frontend/src/internationalization/trans/chefs/it/it.json
+++ b/app/frontend/src/internationalization/trans/chefs/it/it.json
@@ -84,7 +84,8 @@
"deleteSuccess": "Template eliminato con successo.",
"deleteError": "Si è verificato un errore durante l'eliminazione del template.",
"fetchError": "Si è verificato un errore durante il recupero del template.",
- "info": "Carica un template per utilizzare il Servizio di Generazione Documenti Comuni (CDOGS)"
+ "info": "Carica un template per utilizzare il Servizio di Generazione Documenti Comuni (CDOGS)",
+ "fileSizeError": "La dimensione del file deve essere inferiore a 25 MB."
},
"formSettings": {
"pressToAddMultiEmail": "Premi invio o , o spazio per aggiungere più indirizzi email",
diff --git a/app/frontend/src/internationalization/trans/chefs/ja/ja.json b/app/frontend/src/internationalization/trans/chefs/ja/ja.json
index 4db0ec2c4..0d0326376 100644
--- a/app/frontend/src/internationalization/trans/chefs/ja/ja.json
+++ b/app/frontend/src/internationalization/trans/chefs/ja/ja.json
@@ -84,7 +84,8 @@
"deleteSuccess": "テンプレートが正常に削除されました。",
"deleteError": "テンプレートの削除中にエラーが発生しました。",
"fetchError": "テンプレートの取得中にエラーが発生しました。",
- "info": "共通ドキュメント生成サービス(CDOGS)を使用するためのテンプレートをアップロードしてください"
+ "info": "共通ドキュメント生成サービス(CDOGS)を使用するためのテンプレートをアップロードしてください",
+ "fileSizeError": "ファイルサイズは25MB以下でなければなりません。"
},
"formSettings": {
"pressToAddMultiEmail": "Enterまたは、またはスペースを押して複数の電子メール アドレスを追加します",
diff --git a/app/frontend/src/internationalization/trans/chefs/ko/ko.json b/app/frontend/src/internationalization/trans/chefs/ko/ko.json
index f59332df6..171bf2ed3 100644
--- a/app/frontend/src/internationalization/trans/chefs/ko/ko.json
+++ b/app/frontend/src/internationalization/trans/chefs/ko/ko.json
@@ -84,7 +84,8 @@
"deleteSuccess": "템플릿이 성공적으로 삭제되었습니다.",
"deleteError": "템플릿 삭제 중 오류가 발생했습니다.",
"fetchError": "템플릿 가져오기 중 오류가 발생했습니다.",
- "info": "공통 문서 생성 서비스(CDOGS)를 사용하기 위해 템플릿을 업로드하십시오"
+ "info": "공통 문서 생성 서비스(CDOGS)를 사용하기 위해 템플릿을 업로드하십시오",
+ "fileSizeError": "파일 크기는 25MB 이하여야 합니다."
},
"formSettings": {
"pressToAddMultiEmail": "여러 이메일 주소를 추가하려면 enter 또는 , 또는 space를 누르십시오.",
diff --git a/app/frontend/src/internationalization/trans/chefs/pa/pa.json b/app/frontend/src/internationalization/trans/chefs/pa/pa.json
index 1c04cf1c7..4175c49ef 100644
--- a/app/frontend/src/internationalization/trans/chefs/pa/pa.json
+++ b/app/frontend/src/internationalization/trans/chefs/pa/pa.json
@@ -84,7 +84,8 @@
"deleteSuccess": "ਟੈਂਪਲੇਟ ਸਫਲਤਾਪੂਰਵਕ ਮਿਟਾਈ ਗਈ।",
"deleteError": "ਟੈਂਪਲੇਟ ਮਿਟਾਉਣ ਸਮੇਂ ਇੱਕ ਗਲਤੀ ਆਈ।",
"fetchError": "ਟੈਂਪਲੇਟ ਲਿਆਉਣ ਸਮੇਂ ਇੱਕ ਗਲਤੀ ਆਈ।",
- "info": "ਕੌਮਨ ਦਸਤਾਵੇਜ਼ ਜਨਰੇਸ਼ਨ ਸਰਵਿਸ (CDOGS) ਵਰਤਣ ਲਈ ਇੱਕ ਟੈਂਪਲੇਟ ਅੱਪਲੋਡ ਕਰੋ"
+ "info": "ਕੌਮਨ ਦਸਤਾਵੇਜ਼ ਜਨਰੇਸ਼ਨ ਸਰਵਿਸ (CDOGS) ਵਰਤਣ ਲਈ ਇੱਕ ਟੈਂਪਲੇਟ ਅੱਪਲੋਡ ਕਰੋ",
+ "fileSizeError": "ਫਾਈਲ ਦਾ ਆਕਾਰ 25MB ਤੋਂ ਘੱਟ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।"
},
"formSettings": {
"pressToAddMultiEmail": "ਕਈ ਈਮੇਲ ਪਤੇ ਜੋੜਨ ਲਈ ਐਂਟਰ ਜਾਂ ਸਪੇਸ ਦਬਾਓ",
diff --git a/app/frontend/src/internationalization/trans/chefs/pt/pt.json b/app/frontend/src/internationalization/trans/chefs/pt/pt.json
index b3a4e6528..2855f8a04 100644
--- a/app/frontend/src/internationalization/trans/chefs/pt/pt.json
+++ b/app/frontend/src/internationalization/trans/chefs/pt/pt.json
@@ -84,7 +84,8 @@
"deleteSuccess": "Modelo excluído com sucesso.",
"deleteError": "Ocorreu um erro ao excluir o modelo.",
"fetchError": "Ocorreu um erro ao buscar o modelo.",
- "info": "Carregue um modelo para usar o Serviço de Geração de Documentos Comuns (CDOGS)"
+ "info": "Carregue um modelo para usar o Serviço de Geração de Documentos Comuns (CDOGS)",
+ "fileSizeError": "O tamanho do arquivo deve ser menor que 25 MB."
},
"formSettings": {
"pressToAddMultiEmail": "Pressione enter ou , ou espaço para adicionar vários endereços de e-mail",
diff --git a/app/frontend/src/internationalization/trans/chefs/ru/ru.json b/app/frontend/src/internationalization/trans/chefs/ru/ru.json
index 8af28b6fc..e54aaebbe 100644
--- a/app/frontend/src/internationalization/trans/chefs/ru/ru.json
+++ b/app/frontend/src/internationalization/trans/chefs/ru/ru.json
@@ -84,7 +84,8 @@
"deleteSuccess": "Шаблон успешно удален.",
"deleteError": "Произошла ошибка при удалении шаблона.",
"fetchError": "Произошла ошибка при получении шаблона.",
- "info": "Загрузите шаблон для использования Общей службы генерации документов (CDOGS)"
+ "info": "Загрузите шаблон для использования Общей службы генерации документов (CDOGS)",
+ "fileSizeError": "Размер файла должен быть менее 25 МБ."
},
"formSettings": {
"pressToAddMultiEmail": "Нажмите Enter или пробел , чтобы добавить несколько адресов электронной почты.",
diff --git a/app/frontend/src/internationalization/trans/chefs/tl/tl.json b/app/frontend/src/internationalization/trans/chefs/tl/tl.json
index bccdaa983..a6df3828c 100644
--- a/app/frontend/src/internationalization/trans/chefs/tl/tl.json
+++ b/app/frontend/src/internationalization/trans/chefs/tl/tl.json
@@ -84,7 +84,8 @@
"deleteSuccess": "Matagumpay na natanggal ang template.",
"deleteError": "Nagkaroon ng error habang tinatanggal ang template.",
"fetchError": "Nagkaroon ng error habang kinukuha ang template.",
- "info": "Mag-upload ng template upang gamitin ang Common Document Generation Service (CDOGS)"
+ "info": "Mag-upload ng template upang gamitin ang Common Document Generation Service (CDOGS)",
+ "fileSizeError": "Ang laki ng file ay dapat mas mababa sa 25MB."
},
"formSettings": {
"pressToAddMultiEmail": "Pindutin ang enter o , o space para magdagdag ng maraming email address",
diff --git a/app/frontend/src/internationalization/trans/chefs/uk/uk.json b/app/frontend/src/internationalization/trans/chefs/uk/uk.json
index e915db0de..1ba0d44f5 100644
--- a/app/frontend/src/internationalization/trans/chefs/uk/uk.json
+++ b/app/frontend/src/internationalization/trans/chefs/uk/uk.json
@@ -84,7 +84,8 @@
"deleteSuccess": "Шаблон успішно видалено.",
"deleteError": "Під час видалення шаблону сталася помилка.",
"fetchError": "Під час отримання шаблону сталася помилка.",
- "info": "Завантажте шаблон, щоб використовувати Спільний сервіс генерації документів (CDOGS)"
+ "info": "Завантажте шаблон, щоб використовувати Спільний сервіс генерації документів (CDOGS)",
+ "fileSizeError": "Розмір файлу має бути менше 25 МБ."
},
"formSettings": {
"pressToAddMultiEmail": "Щоб додати кілька електронних адрес, натисніть enter або , або пробіл",
diff --git a/app/frontend/src/internationalization/trans/chefs/vi/vi.json b/app/frontend/src/internationalization/trans/chefs/vi/vi.json
index 09b45483a..430c073ad 100644
--- a/app/frontend/src/internationalization/trans/chefs/vi/vi.json
+++ b/app/frontend/src/internationalization/trans/chefs/vi/vi.json
@@ -84,7 +84,8 @@
"deleteSuccess": "Xóa mẫu thành công.",
"deleteError": "Có lỗi xảy ra khi xóa mẫu.",
"fetchError": "Có lỗi xảy ra khi lấy mẫu.",
- "info": "Tải lên một mẫu để sử dụng Dịch vụ Tạo Tài liệu Chung (CDOGS)"
+ "info": "Tải lên một mẫu để sử dụng Dịch vụ Tạo Tài liệu Chung (CDOGS)",
+ "fileSizeError": "Kích thước tệp phải nhỏ hơn 25MB."
},
"formSettings": {
"pressToAddMultiEmail": "Nhấn enter hoặc , hoặc dấu cách để thêm nhiều địa chỉ email",
diff --git a/app/frontend/src/internationalization/trans/chefs/zh/zh.json b/app/frontend/src/internationalization/trans/chefs/zh/zh.json
index a093b928c..531af0a66 100644
--- a/app/frontend/src/internationalization/trans/chefs/zh/zh.json
+++ b/app/frontend/src/internationalization/trans/chefs/zh/zh.json
@@ -84,7 +84,8 @@
"deleteSuccess": "模板删除成功。",
"deleteError": "删除模板时发生错误。",
"fetchError": "获取模板时发生错误。",
- "info": "上传模板以使用公共文档生成服务(CDOGS)"
+ "info": "上传模板以使用公共文档生成服务(CDOGS)",
+ "fileSizeError": "文件大小必须小于25MB。"
},
"formSettings": {
"pressToAddMultiEmail": "按Enter或,或空格键添加多个电子邮件地址",
diff --git a/app/frontend/src/internationalization/trans/chefs/zhTW/zh-TW.json b/app/frontend/src/internationalization/trans/chefs/zhTW/zh-TW.json
index a0020fd7b..3761d8d46 100644
--- a/app/frontend/src/internationalization/trans/chefs/zhTW/zh-TW.json
+++ b/app/frontend/src/internationalization/trans/chefs/zhTW/zh-TW.json
@@ -84,7 +84,8 @@
"deleteSuccess": "範本成功刪除。",
"deleteError": "刪除範本時發生錯誤。",
"fetchError": "獲取範本時發生錯誤。",
- "info": "上傳範本以使用公共文檔生成服務(CDOGS)"
+ "info": "上傳範本以使用公共文檔生成服務(CDOGS)",
+ "fileSizeError": "檔案大小必須小於25MB。"
},
"formSettings": {
"pressToAddMultiEmail": "按Enter或,或空格鍵添加多個電子郵件地址",
diff --git a/app/frontend/src/utils/constants.js b/app/frontend/src/utils/constants.js
index f1fa63c33..1af63296c 100755
--- a/app/frontend/src/utils/constants.js
+++ b/app/frontend/src/utils/constants.js
@@ -174,3 +174,68 @@ export const ExportLargeData = Object.freeze({
MAX_RECORDS: 300, // Maximum number of submissions after that we gonna upload the export to Cloud and send user a download link via email
MAX_FIELDS: 30, // Maximum number of fields in a form after that we gonna upload the export to Cloud and send user a download link via email
});
+
+/** Constants for the form components proactive help */
+export const FormComponentProactiveHelpValues = Object.freeze({
+ 'Basic Layout': [
+ 'Text/Images',
+ 'Columns - 2',
+ 'Columns - 3',
+ 'Columns - 4',
+ 'Tabs',
+ 'Panel',
+ ],
+ 'Basic Fields': [
+ 'Text Field',
+ 'Multi-line Text',
+ 'Select List',
+ 'Checkbox',
+ 'Checkbox Group',
+ 'Radio Group',
+ 'Number',
+ 'Phone Number',
+ 'Email',
+ 'Date / Time',
+ 'Day',
+ ],
+ 'Advanced Layout': [
+ 'HTML Element',
+ 'Content',
+ 'Columns',
+ 'Field Set',
+ 'Panel',
+ 'Table',
+ 'Tabs',
+ 'Well',
+ ],
+ 'Advanced Fields': [
+ 'Text Field',
+ 'Email',
+ 'Text Area',
+ 'Url',
+ 'Number',
+ 'Phone Number',
+ 'Tags',
+ 'Address',
+ 'Password',
+ 'Date / Time',
+ 'Checkbox',
+ 'Day',
+ 'Time',
+ 'Select Boxes',
+ 'Select',
+ 'Currency',
+ 'Radio',
+ 'Survey',
+ 'Signature',
+ ],
+ 'Advanced Data': [
+ 'Hidden',
+ 'Container',
+ 'Data Map',
+ 'Data Grid',
+ 'Edit Grid',
+ 'Tree',
+ ],
+ 'BC Government': ['File Upload', 'Business Name Search', 'BC Address'],
+});
diff --git a/app/frontend/tests/unit/components/admin/FormComponentsProactiveHelp.spec.js b/app/frontend/tests/unit/components/admin/FormComponentsProactiveHelp.spec.js
index 8a6c095e9..fefcc1482 100644
--- a/app/frontend/tests/unit/components/admin/FormComponentsProactiveHelp.spec.js
+++ b/app/frontend/tests/unit/components/admin/FormComponentsProactiveHelp.spec.js
@@ -1,23 +1,25 @@
-import { mount } from '@vue/test-utils';
+import { flushPromises, mount } from '@vue/test-utils';
import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia';
import { expect, vi } from 'vitest';
import FormComponentsProactiveHelp from '~/components/admin/FormComponentsProactiveHelp.vue';
+import { useAdminStore } from '~/store/admin';
+import { FormComponentProactiveHelpValues } from '~/utils/constants';
describe('Dashboard.vue', () => {
const pinia = createTestingPinia();
setActivePinia(pinia);
- const extractGroupComponentsSpy = vi.spyOn(
- FormComponentsProactiveHelp.methods,
- 'extractGroupComponents'
- );
+ const adminStore = useAdminStore(pinia);
+ const listFCProactiveHelpSpy = vi.spyOn(adminStore, 'listFCProactiveHelp');
+ listFCProactiveHelpSpy.mockImplementation(() => {});
beforeEach(() => {
- extractGroupComponentsSpy.mockReset();
+ adminStore.$reset();
+ listFCProactiveHelpSpy.mockReset();
});
afterAll(() => {
- extractGroupComponentsSpy.mockRestore();
+ listFCProactiveHelpSpy.mockRestore();
});
it('renders', async () => {
@@ -30,7 +32,12 @@ describe('Dashboard.vue', () => {
},
});
- wrapper.vm.onExpansionPanelClick('Basic Layout');
- expect(extractGroupComponentsSpy).toHaveBeenCalledTimes(1);
+ await flushPromises();
+
+ expect(listFCProactiveHelpSpy).toHaveBeenCalledTimes(1);
+
+ for (let [title] of Object.entries(FormComponentProactiveHelpValues)) {
+ expect(wrapper.html()).toContain(title);
+ }
});
});
diff --git a/app/frontend/tests/unit/components/forms/PrintOptions.spec.js b/app/frontend/tests/unit/components/forms/PrintOptions.spec.js
index ff04aec26..5214dfbfd 100644
--- a/app/frontend/tests/unit/components/forms/PrintOptions.spec.js
+++ b/app/frontend/tests/unit/components/forms/PrintOptions.spec.js
@@ -275,7 +275,7 @@ describe('PrintOptions.vue', () => {
expect(addNotificationSpy).toHaveBeenCalledTimes(1);
});
- it('validateFileExtension should remove the file extension from uploadExportFileTypes when the file input is cleared', async () => {
+ it('validateFile should remove the file extension from uploadExportFileTypes when the file input is cleared', async () => {
let submission = undefined;
formStore.form = {
id: 0,
@@ -302,11 +302,11 @@ describe('PrintOptions.vue', () => {
};
// Since this isn't in uploadExportFileTypes then it should be removed from uploadExportFileTypes
wrapper.vm.uploadExportFileTypes = ['pdf', 'txt'];
- wrapper.vm.validateFileExtension([]);
+ wrapper.vm.validateFile([]);
expect(wrapper.vm.uploadExportFileTypes).toEqual(['pdf']);
});
- it('validateFileExtension should set the output filename and set isValidFile to true if the file extension is valid', async () => {
+ it('validateFile should set the output filename and set isValidFile to true if the file extension is valid', async () => {
let submission = undefined;
formStore.form = {
id: 0,
@@ -332,7 +332,7 @@ describe('PrintOptions.vue', () => {
files: [],
};
wrapper.vm.uploadExportFileTypes = ['pdf'];
- wrapper.vm.validateFileExtension([
+ wrapper.vm.validateFile([
{
name: 'filename.txt',
},
@@ -341,7 +341,7 @@ describe('PrintOptions.vue', () => {
expect(wrapper.vm.isValidFile).toBeTruthy();
});
- it('validateFileExtension should set the output filename and set isValidFile to false if the file extension is invalid', async () => {
+ it('validateFile should set the output filename and set isValidFile to false if the file extension is invalid', async () => {
let submission = undefined;
formStore.form = {
id: 0,
@@ -367,7 +367,7 @@ describe('PrintOptions.vue', () => {
files: [],
};
wrapper.vm.uploadExportFileTypes = ['pdf'];
- wrapper.vm.validateFileExtension([
+ wrapper.vm.validateFile([
{
name: 'filename.zip',
},
diff --git a/app/frontend/tests/unit/components/forms/SubmissionsTable.spec.js b/app/frontend/tests/unit/components/forms/SubmissionsTable.spec.js
index 9ceaf82d3..3c94f627d 100644
--- a/app/frontend/tests/unit/components/forms/SubmissionsTable.spec.js
+++ b/app/frontend/tests/unit/components/forms/SubmissionsTable.spec.js
@@ -734,70 +734,70 @@ describe('SubmissionsTable.vue', () => {
// should refresh submissions
expect(getFormPreferencesForCurrentUserSpy).toBeCalledTimes(0);
expect(fetchSubmissionsSpy).toBeCalledTimes(0);
- expect(wrapper.vm.page).toEqual(1);
- expect(wrapper.vm.sortBy).toEqual({});
- expect(wrapper.vm.itemsPerPage).toEqual(10);
+ expect(wrapper.vm.currentPage).toEqual(1);
+ expect(wrapper.vm.sort).toEqual({});
+ expect(wrapper.vm.itemsPP).toEqual(10);
getFormPreferencesForCurrentUserSpy.mockReset();
fetchSubmissionsSpy.mockReset();
await wrapper.vm.updateTableOptions({
- pg: 5,
- itemsPP: 2,
- sort: [{ key: 'date', order: 'desc' }],
+ page: 5,
+ itemsPerPage: 2,
+ sortBy: [{ key: 'date', order: 'desc' }],
});
// should not refresh submissions
wrapper.vm.firstDataLoad = true;
expect(getFormPreferencesForCurrentUserSpy).toBeCalledTimes(0);
expect(fetchSubmissionsSpy).toBeCalledTimes(0);
- expect(wrapper.vm.page).toEqual(5);
- expect(wrapper.vm.sortBy).toEqual({ column: 'createdAt', order: 'desc' });
- expect(wrapper.vm.itemsPerPage).toEqual(2);
+ expect(wrapper.vm.currentPage).toEqual(5);
+ expect(wrapper.vm.sort).toEqual({ column: 'createdAt', order: 'desc' });
+ expect(wrapper.vm.itemsPP).toEqual(2);
await wrapper.vm.updateTableOptions({
- pg: 5,
- itemsPP: 2,
- sort: [{ key: 'submitter', order: 'desc' }],
+ page: 5,
+ itemsPerPage: 2,
+ sortBy: [{ key: 'submitter', order: 'desc' }],
});
// should not refresh submissions
wrapper.vm.firstDataLoad = true;
expect(getFormPreferencesForCurrentUserSpy).toBeCalledTimes(0);
expect(fetchSubmissionsSpy).toBeCalledTimes(0);
- expect(wrapper.vm.page).toEqual(5);
- expect(wrapper.vm.sortBy).toEqual({ column: 'createdBy', order: 'desc' });
- expect(wrapper.vm.itemsPerPage).toEqual(2);
+ expect(wrapper.vm.currentPage).toEqual(5);
+ expect(wrapper.vm.sort).toEqual({ column: 'createdBy', order: 'desc' });
+ expect(wrapper.vm.itemsPP).toEqual(2);
await wrapper.vm.updateTableOptions({
- pg: 5,
- itemsPP: 2,
- sort: [{ key: 'status', order: 'desc' }],
+ page: 5,
+ itemsPerPage: 2,
+ sortBy: [{ key: 'status', order: 'desc' }],
});
// should not refresh submissions
wrapper.vm.firstDataLoad = true;
expect(getFormPreferencesForCurrentUserSpy).toBeCalledTimes(0);
expect(fetchSubmissionsSpy).toBeCalledTimes(0);
- expect(wrapper.vm.page).toEqual(5);
- expect(wrapper.vm.sortBy).toEqual({
+ expect(wrapper.vm.currentPage).toEqual(5);
+ expect(wrapper.vm.sort).toEqual({
column: 'formSubmissionStatusCode',
order: 'desc',
});
- expect(wrapper.vm.itemsPerPage).toEqual(2);
+ expect(wrapper.vm.itemsPP).toEqual(2);
await wrapper.vm.updateTableOptions({
- pg: 5,
- itemsPP: 2,
- sort: [{ key: 'something', order: 'desc' }],
+ page: 5,
+ itemsPerPage: 2,
+ sortBy: [{ key: 'something', order: 'desc' }],
});
// should not refresh submissions
wrapper.vm.firstDataLoad = true;
expect(getFormPreferencesForCurrentUserSpy).toBeCalledTimes(0);
expect(fetchSubmissionsSpy).toBeCalledTimes(0);
- expect(wrapper.vm.page).toEqual(5);
- expect(wrapper.vm.sortBy).toEqual({
+ expect(wrapper.vm.currentPage).toEqual(5);
+ expect(wrapper.vm.sort).toEqual({
column: 'something',
order: 'desc',
});
- expect(wrapper.vm.itemsPerPage).toEqual(2);
+ expect(wrapper.vm.itemsPP).toEqual(2);
});
it('getSubmissionData will fetchSubmissions in different ways', async () => {
diff --git a/app/frontend/tests/unit/components/forms/manage/DocumentTemplate.spec.js b/app/frontend/tests/unit/components/forms/manage/DocumentTemplate.spec.js
index d4b8f8b8b..b78ddddfc 100644
--- a/app/frontend/tests/unit/components/forms/manage/DocumentTemplate.spec.js
+++ b/app/frontend/tests/unit/components/forms/manage/DocumentTemplate.spec.js
@@ -341,7 +341,9 @@ describe('DocumentTemplate.vue', () => {
'documentTemplateCreate'
);
documentTemplateCreateSpy.mockImplementation(() => {
- throw new Error('Error');
+ const error = new Error('Error');
+ error.response = { status: 500 };
+ throw error;
});
const wrapper = mount(DocumentTemplate, {
global: {
diff --git a/app/frontend/tests/unit/components/infolinks/GeneralLayout.spec.js b/app/frontend/tests/unit/components/infolinks/GeneralLayout.spec.js
index 1b4112791..8f7dad40f 100644
--- a/app/frontend/tests/unit/components/infolinks/GeneralLayout.spec.js
+++ b/app/frontend/tests/unit/components/infolinks/GeneralLayout.spec.js
@@ -1,17 +1,20 @@
// @vitest-environment happy-dom
// happy-dom is required to access window.location
-import { mount } from '@vue/test-utils';
+import { flushPromises, mount, shallowMount } from '@vue/test-utils';
import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia';
import { createRouter, createWebHistory } from 'vue-router';
-import { expect, vi } from 'vitest';
+import { beforeEach, expect, vi } from 'vitest';
import getRouter from '~/router';
import GeneralLayout from '~/components/infolinks/GeneralLayout.vue';
+import { useAdminStore } from '~/store/admin';
+import { faL } from '@fortawesome/free-solid-svg-icons';
describe('GeneralLayout.vue', () => {
const pinia = createTestingPinia();
+ const adminStore = useAdminStore(pinia);
const router = createRouter({
history: createWebHistory(),
routes: getRouter().getRoutes(),
@@ -19,18 +22,29 @@ describe('GeneralLayout.vue', () => {
setActivePinia(pinia);
- it('onOpenDialog()', async () => {
- const getComponentSpy = vi.spyOn(GeneralLayout.methods, 'getComponent');
- const onDialogSpy = vi.spyOn(GeneralLayout.methods, 'onDialog');
+ beforeEach(() => {
+ adminStore.$reset();
+ });
+
+ it('renders', async () => {
const wrapper = mount(GeneralLayout, {
props: {
- componentsList: [
- { componentName: 'content', status: true },
- { componentName: 'textfiled', status: false },
+ formComponentData: [
+ {
+ componentName: 'Text/Images',
+ description:
+ 'See Also: Content component and HTML Element component in the "advanced layout" section',
+ externalLink: 'http://link.com',
+ groupName: 'Basic Layout',
+ id: '123-456',
+ imageName: 'image.jpeg',
+ isLinkEnabled: true,
+ status: true,
+ },
],
- layoutList: [
- { componentName: 'content' },
- { componentName: 'textfiled' },
+ formComponentNames: [
+ { componentName: 'Text/Images' },
+ { componentName: 'Columns - 2' },
],
groupName: '',
},
@@ -42,21 +56,32 @@ describe('GeneralLayout.vue', () => {
},
},
});
- //wrapper.vm.onOpenDialog('Text Field');
- //expect(getComponentSpy).toHaveBeenCalledTimes(1);
- //expect(onDialogSpy).toHaveBeenCalledTimes(1);
+
+ await flushPromises();
+
+ expect(wrapper.html()).toContain('Text/Images');
+ expect(wrapper.html()).toContain('Columns - 2');
});
- it('onPreviewDialog()', async () => {
- const wrapper = mount(GeneralLayout, {
+ it('toggleProactiveHelpDialog should toggle the boolean for showProactiveHelpDialog', async () => {
+ const wrapper = shallowMount(GeneralLayout, {
props: {
- componentsList: [
- { componentName: 'content', status: true },
- { componentName: 'textfiled', status: false },
+ formComponentData: [
+ {
+ componentName: 'Text/Images',
+ description:
+ 'See Also: Content component and HTML Element component in the "advanced layout" section',
+ externalLink: 'http://link.com',
+ groupName: 'Basic Layout',
+ id: '123-456',
+ imageName: 'image.jpeg',
+ isLinkEnabled: true,
+ status: true,
+ },
],
- layoutList: [
- { componentName: 'content' },
- { componentName: 'textfiled' },
+ formComponentNames: [
+ { componentName: 'Text/Images' },
+ { componentName: 'Columns - 2' },
],
groupName: '',
},
@@ -68,20 +93,102 @@ describe('GeneralLayout.vue', () => {
},
},
});
- //wrapper.vm.onPreviewDialog();
- //expect(wrapper.vm.showPreviewDialog).toBe(true);
+
+ expect(wrapper.vm.showEditProactiveHelpDialog).toBeFalsy();
+ wrapper.vm.toggleEditProactiveHelpDialog();
+ expect(wrapper.vm.showEditProactiveHelpDialog).toBeTruthy();
});
- it('onDialog()', async () => {
- const wrapper = mount(GeneralLayout, {
+ it('togglePreviewDialog should toggle the boolean for showPreviewDialog', async () => {
+ const wrapper = shallowMount(GeneralLayout, {
+ props: {
+ formComponentData: [
+ {
+ componentName: 'Text/Images',
+ description:
+ 'See Also: Content component and HTML Element component in the "advanced layout" section',
+ externalLink: 'http://link.com',
+ groupName: 'Basic Layout',
+ id: '123-456',
+ imageName: 'image.jpeg',
+ isLinkEnabled: true,
+ status: true,
+ },
+ ],
+ formComponentNames: [
+ { componentName: 'Text/Images' },
+ { componentName: 'Columns - 2' },
+ ],
+ groupName: '',
+ },
+ global: {
+ plugins: [router, pinia],
+ stubs: {
+ ProactiveHelpDialog: true,
+ ProactiveHelpPreviewDialog: true,
+ },
+ },
+ });
+
+ expect(wrapper.vm.showPreviewDialog).toBeFalsy();
+ wrapper.vm.togglePreviewDialog();
+ expect(wrapper.vm.showPreviewDialog).toBeTruthy();
+ });
+
+ it('isPreviewEnabled takes a component name and returns true if an admin has previously set data for a form component proactive help and false otherwise', async () => {
+ const wrapper = shallowMount(GeneralLayout, {
+ props: {
+ formComponentData: [
+ {
+ componentName: 'Text/Images',
+ description:
+ 'See Also: Content component and HTML Element component in the "advanced layout" section',
+ externalLink: 'http://link.com',
+ groupName: 'Basic Layout',
+ id: '123-456',
+ imageName: 'image.jpeg',
+ isLinkEnabled: true,
+ status: true,
+ },
+ ],
+ formComponentNames: [
+ { componentName: 'Text/Images' },
+ { componentName: 'Columns - 2' },
+ ],
+ groupName: '',
+ },
+ global: {
+ plugins: [router, pinia],
+ stubs: {
+ ProactiveHelpDialog: true,
+ ProactiveHelpPreviewDialog: true,
+ },
+ },
+ });
+
+ expect(wrapper.vm.isPreviewEnabled('Text/Images')).toBeFalsy();
+ expect(wrapper.vm.isPreviewEnabled('Columns - 2')).toBeTruthy();
+ });
+
+ it('onOpenEditDialog should set the component data and toggle the boolean for showProactiveHelpDialog', async () => {
+ const wrapper = shallowMount(GeneralLayout, {
props: {
- componentsList: [
- { componentName: 'content', status: true },
- { componentName: 'textfiled', status: false },
+ formComponentData: [
+ {
+ componentName: 'Text/Images',
+ description:
+ 'See Also: Content component and HTML Element component in the "advanced layout" section',
+ externalLink: 'http://link.com',
+ groupName: 'Basic Layout',
+ id: '123-456',
+ imageName: 'image.jpeg',
+ isLinkEnabled: true,
+ status: true,
+ },
],
- layoutList: [
- { componentName: 'content' },
- { componentName: 'textfiled' },
+ formComponentNames: [
+ { componentName: 'Text/Images' },
+ { componentName: 'Columns - 2' },
],
groupName: '',
},
@@ -93,7 +200,129 @@ describe('GeneralLayout.vue', () => {
},
},
});
- //wrapper.vm.onDialog();
- //expect(wrapper.vm.showDialog).toBe(true);
+
+ expect(wrapper.vm.showEditProactiveHelpDialog).toBeFalsy();
+ expect(wrapper.vm.component).toEqual({});
+ wrapper.vm.onOpenEditDialog('Text/Images');
+ expect(wrapper.vm.component).toEqual({
+ componentName: 'Text/Images',
+ description:
+ 'See Also: Content component and HTML Element component in the "advanced layout" section',
+ externalLink: 'http://link.com',
+ groupName: 'Basic Layout',
+ id: '123-456',
+ imageName: 'image.jpeg',
+ isLinkEnabled: true,
+ status: true,
+ });
+ expect(wrapper.vm.showEditProactiveHelpDialog).toBeTruthy();
+ });
+
+ it('onOpenPreviewDialog should get the image URL, set the component data and toggle the boolean for showPreviewDialog', async () => {
+ const wrapper = shallowMount(GeneralLayout, {
+ props: {
+ formComponentData: [
+ {
+ componentName: 'Text/Images',
+ description:
+ 'See Also: Content component and HTML Element component in the "advanced layout" section',
+ externalLink: 'http://link.com',
+ groupName: 'Basic Layout',
+ id: '123-456',
+ imageName: 'image.jpeg',
+ isLinkEnabled: true,
+ status: true,
+ },
+ ],
+ formComponentNames: [
+ { componentName: 'Text/Images' },
+ { componentName: 'Columns - 2' },
+ ],
+ groupName: '',
+ },
+ global: {
+ plugins: [router, pinia],
+ stubs: {
+ ProactiveHelpDialog: true,
+ ProactiveHelpPreviewDialog: true,
+ },
+ },
+ });
+
+ const getFCProactiveHelpImageUrlSpy = vi.spyOn(
+ adminStore,
+ 'getFCProactiveHelpImageUrl'
+ );
+ getFCProactiveHelpImageUrlSpy.mockImplementation(() => {});
+
+ expect(wrapper.vm.showPreviewDialog).toBeFalsy();
+ expect(wrapper.vm.component).toEqual({});
+ await wrapper.vm.onOpenPreviewDialog('Text/Images');
+ expect(getFCProactiveHelpImageUrlSpy).toBeCalledTimes(1);
+ expect(getFCProactiveHelpImageUrlSpy).toBeCalledWith('123-456');
+ expect(wrapper.vm.component).toEqual({
+ componentName: 'Text/Images',
+ description:
+ 'See Also: Content component and HTML Element component in the "advanced layout" section',
+ externalLink: 'http://link.com',
+ groupName: 'Basic Layout',
+ id: '123-456',
+ imageName: 'image.jpeg',
+ isLinkEnabled: true,
+ status: true,
+ });
+ expect(wrapper.vm.showPreviewDialog).toBeTruthy();
+ });
+
+ it('onSwitchChange will set the published status for a component based on the switch value', async () => {
+ const wrapper = shallowMount(GeneralLayout, {
+ props: {
+ formComponentData: [
+ {
+ componentName: 'Text/Images',
+ description:
+ 'See Also: Content component and HTML Element component in the "advanced layout" section',
+ externalLink: 'http://link.com',
+ groupName: 'Basic Layout',
+ id: '123-456',
+ imageName: 'image.jpeg',
+ isLinkEnabled: true,
+ status: true,
+ },
+ ],
+ formComponentNames: [
+ { componentName: 'Text/Images' },
+ { componentName: 'Columns - 2' },
+ ],
+ groupName: '',
+ },
+ global: {
+ plugins: [router, pinia],
+ stubs: {
+ ProactiveHelpDialog: true,
+ ProactiveHelpPreviewDialog: true,
+ },
+ },
+ });
+
+ const updateFCProactiveHelpStatusSpy = vi.spyOn(
+ adminStore,
+ 'updateFCProactiveHelpStatus'
+ );
+ updateFCProactiveHelpStatusSpy.mockImplementation(() => {});
+ await wrapper.vm.onSwitchChange('Text/Images', 0);
+ expect(updateFCProactiveHelpStatusSpy).toBeCalledTimes(1);
+ expect(updateFCProactiveHelpStatusSpy).toBeCalledWith({
+ componentId: '123-456',
+ publishStatus: true,
+ });
+ wrapper.vm.publish[0] = false;
+ updateFCProactiveHelpStatusSpy.mockReset();
+ await wrapper.vm.onSwitchChange('Text/Images', 0);
+ expect(updateFCProactiveHelpStatusSpy).toBeCalledTimes(1);
+ expect(updateFCProactiveHelpStatusSpy).toBeCalledWith({
+ componentId: '123-456',
+ publishStatus: false,
+ });
});
});
diff --git a/app/frontend/tests/unit/components/infolinks/ProactiveHelpDialog.spec.js b/app/frontend/tests/unit/components/infolinks/ProactiveHelpDialog.spec.js
index d64797a30..15b24e2f0 100644
--- a/app/frontend/tests/unit/components/infolinks/ProactiveHelpDialog.spec.js
+++ b/app/frontend/tests/unit/components/infolinks/ProactiveHelpDialog.spec.js
@@ -1,18 +1,55 @@
// @vitest-environment happy-dom
// happy-dom is required to access window.location
-import { mount } from '@vue/test-utils';
+import { flushPromises, mount, shallowMount } from '@vue/test-utils';
import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia';
import { createRouter, createWebHistory } from 'vue-router';
import { expect, vi } from 'vitest';
-import { nextTick } from 'vue';
import getRouter from '~/router';
import ProactiveHelpDialog from '~/components/infolinks/ProactiveHelpDialog.vue';
+import { useAdminStore } from '~/store/admin';
+
+const STUBS = {
+ VRow: {
+ template: '
',
+ },
+ VCol: {
+ template: '
',
+ },
+ VDialog: {
+ template: '
',
+ },
+ VCard: {
+ template: '
',
+ },
+ VContainer: {
+ template: '
',
+ },
+ VTextField: {
+ template: '
',
+ },
+ VCheckbox: {
+ template: '
',
+ },
+ VTextArea: {
+ template: '
',
+ },
+ VIcon: {
+ template: '
',
+ },
+ VFileInput: {
+ template: '
',
+ },
+ VBtn: {
+ template: '
',
+ },
+};
describe('ProactiveHelpDialog.vue', () => {
const pinia = createTestingPinia();
+ const adminStore = useAdminStore(pinia);
const router = createRouter({
history: createWebHistory(),
routes: getRouter().getRoutes(),
@@ -20,8 +57,176 @@ describe('ProactiveHelpDialog.vue', () => {
setActivePinia(pinia);
- it('resetDialog', async () => {
+ it('renders', async () => {
const wrapper = mount(ProactiveHelpDialog, {
+ props: {
+ component: {
+ componentName: 'content',
+ description: 'dump text',
+ imageUrl: 'https://dumpurl.com',
+ moreHelpInfoLink: 'https://dumpurl.com',
+ },
+ componentName: 'content',
+ groupName: 'test',
+ showDialog: true,
+ },
+ global: {
+ plugins: [router, pinia],
+ stubs: STUBS,
+ },
+ });
+
+ await flushPromises();
+
+ expect(wrapper.html()).toContain('content');
+ });
+
+ it('rules should return largeImgTxt if it fails', () => {
+ const wrapper = shallowMount(ProactiveHelpDialog, {
+ props: {
+ component: {
+ componentName: 'content',
+ description: 'dump text',
+ imageUrl: 'https://dumpurl.com',
+ moreHelpInfoLink: 'https://dumpurl.com',
+ },
+ groupName: 'test',
+ showDialog: true,
+ },
+ global: {
+ plugins: [router, pinia],
+ },
+ });
+
+ expect(wrapper.vm.rules[0]([{ size: 5000000 }])).toEqual(
+ 'trans.proactiveHelpDialog.largeImgTxt'
+ );
+ });
+
+ it('onCloseDialog should call resetDialog and emit close-dialog', () => {
+ const wrapper = shallowMount(ProactiveHelpDialog, {
+ props: {
+ component: {
+ componentName: 'content',
+ description: 'dump text',
+ imageUrl: 'https://dumpurl.com',
+ moreHelpInfoLink: 'https://dumpurl.com',
+ },
+ groupName: 'test',
+ showDialog: true,
+ },
+ global: {
+ plugins: [router, pinia],
+ },
+ });
+
+ wrapper.vm.onCloseDialog();
+ expect(wrapper.emitted()).toHaveProperty('close-dialog');
+ });
+
+ it('validateLinkUrl should return true and set linkError to true if isLinkEnabled and moreHelpInfoLink is blank otherwise false', () => {
+ const wrapper = shallowMount(ProactiveHelpDialog, {
+ props: {
+ component: {
+ componentName: 'content',
+ description: 'dump text',
+ imageUrl: 'https://dumpurl.com',
+ moreHelpInfoLink: 'https://dumpurl.com',
+ },
+ groupName: 'test',
+ showDialog: true,
+ },
+ global: {
+ plugins: [router, pinia],
+ },
+ });
+
+ expect(wrapper.vm.validateLinkUrl()).toBeFalsy();
+ expect(wrapper.vm.linkError).toBeFalsy();
+ wrapper.vm.isLinkEnabled = true;
+ wrapper.vm.moreHelpInfoLink = '';
+ expect(wrapper.vm.validateLinkUrl()).toBeTruthy();
+ expect(wrapper.vm.linkError).toBeTruthy();
+ });
+
+ it('selectImage will set imageSizeError to true if the image size is too large', async () => {
+ const wrapper = shallowMount(ProactiveHelpDialog, {
+ props: {
+ component: {
+ componentName: 'content',
+ description: 'dump text',
+ imageUrl: 'https://dumpurl.com',
+ moreHelpInfoLink: 'https://dumpurl.com',
+ },
+ groupName: 'test',
+ showDialog: true,
+ },
+ global: {
+ plugins: [router, pinia],
+ },
+ });
+
+ wrapper.vm.files = [{ size: 50000000 }];
+ await wrapper.vm.selectImage();
+ expect(wrapper.vm.imageSizeError).toBeTruthy();
+ });
+
+ it('selectImage will set imageSizeError to true if the image size is too large', async () => {
+ const wrapper = shallowMount(ProactiveHelpDialog, {
+ props: {
+ component: {
+ componentName: 'content',
+ description: 'dump text',
+ imageUrl: 'https://dumpurl.com',
+ moreHelpInfoLink: 'https://dumpurl.com',
+ },
+ groupName: 'test',
+ showDialog: true,
+ },
+ global: {
+ plugins: [router, pinia],
+ },
+ });
+
+ window.FileReader = function () {
+ this.readAsDataURL = vi.fn();
+ this.onerror = null;
+ };
+
+ wrapper.vm.files = [{ size: 1 }];
+
+ await wrapper.vm.selectImage();
+ expect(wrapper.vm.imageSizeError).toBeFalsy();
+ });
+
+ it('submit will call addFCProactiveHelp then emit close-dialog', async () => {
+ const wrapper = shallowMount(ProactiveHelpDialog, {
+ props: {
+ component: {
+ componentName: 'content',
+ description: 'dump text',
+ imageUrl: 'https://dumpurl.com',
+ moreHelpInfoLink: 'https://dumpurl.com',
+ },
+ groupName: 'test',
+ showDialog: true,
+ },
+ global: {
+ plugins: [router, pinia],
+ },
+ });
+
+ const addFCProactiveHelpSpy = vi.spyOn(adminStore, 'addFCProactiveHelp');
+ addFCProactiveHelpSpy.mockImplementation(() => {});
+
+ await wrapper.vm.submit();
+
+ expect(addFCProactiveHelpSpy).toBeCalledTimes(1);
+ expect(wrapper.emitted()).toHaveProperty('close-dialog');
+ });
+
+ it('resetDialog', async () => {
+ const wrapper = shallowMount(ProactiveHelpDialog, {
props: {
component: {
componentName: 'content',
@@ -38,7 +243,6 @@ describe('ProactiveHelpDialog.vue', () => {
});
wrapper.vm.resetDialog();
- await nextTick();
expect(wrapper.vm.description).toBe('');
});
});
diff --git a/app/frontend/tests/unit/components/infolinks/ProactiveHelpPreviewDialog.spec.js b/app/frontend/tests/unit/components/infolinks/ProactiveHelpPreviewDialog.spec.js
index c5a767b12..9475bcd62 100644
--- a/app/frontend/tests/unit/components/infolinks/ProactiveHelpPreviewDialog.spec.js
+++ b/app/frontend/tests/unit/components/infolinks/ProactiveHelpPreviewDialog.spec.js
@@ -1,17 +1,17 @@
-import { mount } from '@vue/test-utils';
+import { mount, shallowMount } from '@vue/test-utils';
import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia';
import { createRouter, createWebHistory } from 'vue-router';
-import { beforeEach, expect, vi } from 'vitest';
+import { expect } from 'vitest';
-import { rbacService } from '~/services';
import getRouter from '~/router';
import ProactiveHelpPreviewDialog from '~/components/infolinks/ProactiveHelpPreviewDialog.vue';
+
import { useFormStore } from '~/store/form';
import { useAppStore } from '~/store/app';
+
describe('ProactiveHelpPreviewDialog.vue', () => {
- const getSubmissionUsersSpy = vi.spyOn(rbacService, 'getSubmissionUsers');
const pinia = createTestingPinia();
const router = createRouter({
history: createWebHistory(),
@@ -19,6 +19,7 @@ describe('ProactiveHelpPreviewDialog.vue', () => {
});
setActivePinia(pinia);
+
const formStore = useFormStore(pinia);
const appStore = useAppStore(pinia);
@@ -32,9 +33,8 @@ describe('ProactiveHelpPreviewDialog.vue', () => {
getSubmissionUsersSpy.mockRestore();
});
+
it('renders', () => {
- formStore.form.name = 'myForm';
- getSubmissionUsersSpy.mockImplementation(() => ({ data: [] }));
const wrapper = mount(ProactiveHelpPreviewDialog, {
props: {
component: {
@@ -58,4 +58,30 @@ describe('ProactiveHelpPreviewDialog.vue', () => {
expect(wrapper.text()).toContain('content').toContain('dump description');
});
+
+ it('onCloseDialog should emit close-dialog', () => {
+ const wrapper = shallowMount(ProactiveHelpPreviewDialog, {
+ props: {
+ component: {
+ componentName: 'content',
+ description: 'dump description',
+ imageUrl: 'https://dumpurl.com',
+ moreHelpInfoLink: 'https://dumpurl.com',
+ },
+ showDialog: true,
+ },
+ global: {
+ plugins: [router, pinia],
+ stubs: {
+ VDialog: {
+ name: 'VDialog',
+ template: '
',
+ },
+ },
+ },
+ });
+
+ wrapper.vm.onCloseDialog();
+ expect(wrapper.emitted()).toHaveProperty('close-dialog');
+ });
});