+
+
+ {{ SAVE_TEXT }}
+
+
+
+
+
+
+ {{ $t('trans.floatButton.preview') }}
+
+
+
+
+
+ {{ $t('trans.floatButton.undo') }}
+
+
+
+
+
+ {{ $t('trans.floatButton.redo') }}
+
+
+
+
-
+
{{ $t('trans.floatButton.manage') }}
-
-
+
-
+
{{ $t('trans.floatButton.publish') }}
-
-
+
-
-
-
-
-
-
{{ savedMsg }}
-
-
-
-
-
-
-
-
-
{{ scrollName }}
-
-
-
-
-
-
-
-
{{ scrollName }}
+
+ {{ COLLAPSE_TEXT }}
-
-
+
-
diff --git a/app/frontend/src/components/designer/FormDesigner.vue b/app/frontend/src/components/designer/FormDesigner.vue
index 309bc8ca8..17df2cba2 100644
--- a/app/frontend/src/components/designer/FormDesigner.vue
+++ b/app/frontend/src/components/designer/FormDesigner.vue
@@ -1,772 +1,597 @@
-
+async function schemaCreateNew() {
+ const response = await formService.createForm({
+ name: form.value.name,
+ description: form.value.description,
+ schema: formSchema.value,
+ identityProviders: generateIdps({
+ idps: form.value.idps,
+ userType: form.value.userType,
+ }),
+ sendSubmissionReceivedEmail: form.value.sendSubmissionReceivedEmail,
+ enableSubmitterDraft: form.value.enableSubmitterDraft,
+ enableCopyExistingSubmission: form.value.enableCopyExistingSubmission,
+ wideFormLayout: form.value.wideFormLayout,
+ enableStatusUpdates: form.value.enableStatusUpdates,
+ showSubmissionConfirmation: form.value.showSubmissionConfirmation,
+ submissionReceivedEmails: form.value.submissionReceivedEmails,
+ reminder_enabled: false,
+ deploymentLevel: form.value.deploymentLevel,
+ ministry: form.value.ministry,
+ apiIntegration: form.value.apiIntegration,
+ useCase: form.value.useCase,
+ labels: form.value.labels,
+ formMetadata: form.value.formMetadata,
+ });
+ // update user labels with any new added labels
+ if (
+ form.value.labels.some((label) => userLabels.value.indexOf(label) === -1)
+ ) {
+ const userLabelResponse = await userService.updateUserLabels(
+ form.value.labels
+ );
+ userLabels.value = userLabelResponse.data;
+ }
+
+ // Navigate back to this page with ID updated
+ router.push({
+ name: 'FormDesigner',
+ query: {
+ f: response.data.id,
+ d: response.data.draft.id,
+ sv: true,
+ svs: 'Saved',
+ },
+ });
+}
+
+async function schemaCreateDraftFromVersion() {
+ const { data } = await formService.createDraft(properties.formId, {
+ schema: formSchema.value,
+ formVersionId: properties.versionId,
+ });
+
+ // Navigate back to this page with ID updated
+ router.push({
+ name: 'FormDesigner',
+ query: {
+ f: properties.formId,
+ d: data.id,
+ sv: true,
+ svs: 'Saved',
+ },
+ });
+}
+async function schemaUpdateExistingDraft() {
+ await formService.updateDraft(properties.formId, properties.draftId, {
+ schema: formSchema.value,
+ });
+
+ // Update this route with saved flag
+ router.replace({
+ name: 'FormDesigner',
+ query: { ...router.currentRoute.value.query, sv: true, svs: 'Saved' },
+ });
+}
+// ----------------------------------------------------------------------------------/ Saving the Schema
+async function setProxyHeaders() {
+ try {
+ let response = await formService.getProxyHeaders({
+ formId: properties.formId,
+ versionId: properties.versionId,
+ });
+ // error checking for response
+ sessionStorage.setItem(
+ 'X-CHEFS-PROXY-DATA',
+ response.data['X-CHEFS-PROXY-DATA']
+ );
+ } catch (error) {
+ notificationStore.addNotification({
+ text: 'Failed to set proxy headers',
+ consoleError: error,
+ });
+ }
+}
+
+async function getFormSchema() {
+ try {
+ let res;
+ if (properties.versionId) {
+ // Making a new draft from a previous version
+ res = await formService.readVersion(
+ properties.formId,
+ properties.versionId
+ );
+ } else if (properties.draftId) {
+ // Editing an existing draft
+ res = await formService.readDraft(properties.formId, properties.draftId);
+ }
+ formSchema.value = {
+ ...formSchema.value,
+ ...res.data.schema,
+ };
+ if (patch.value.history.length === 0) {
+ // We are fetching an existing form, so we get the original schema here because
+ // using the original schema in the mount will give you the default schema
+ patch.value.originalSchema = deepClone(formSchema.value);
+ }
+ reRenderFormIo.value += 1;
+ } catch (error) {
+ notificationStore.addNotification({
+ text: t('trans.formDesigner.formLoadErrMsg'),
+ consoleError: t('trans.formDesigner.formLoadConsoleErrMsg', {
+ formId: properties.formId,
+ versionId: properties.versionId,
+ draftId: properties.draftId,
+ error: error,
+ }),
+ });
+ }
+}
+
+async function loadFile(event) {
+ try {
+ const result = await importFormSchemaFromFile(event.target.files[0]);
+
+ formSchema.value = JSON.parse(result);
+ addPatchToHistory();
+ patch.value.undoClicked = false;
+ patch.value.redoClicked = false;
+ resetHistoryFlags();
+ // Key-changing to force a re-render of the formio component when we want to load a new schema after the page is already in
+ reRenderFormIo.value += 1;
+ } catch (error) {
+ notificationStore.addNotification({
+ text: t('trans.formDesigner.formSchemaImportErrMsg'),
+ consoleError: t('trans.formDesigner.formSchemaImportConsoleErrMsg', {
+ error: error,
+ }),
+ });
+ }
+}
+
+defineExpose({ designerOptions, reRenderFormIo });
+
-
+
-
+
{{ $t('trans.formDesigner.formDesign') }}
{{ form.name }}
- {{ $t('trans.formDesigner.version') }} : {{ displayVersion }}
-
+
+
+
+ {{ $t('trans.formDesigner.version') }} : {{ DISPLAY_VERSION }}
@@ -790,7 +615,6 @@ export default {
>
-
-
-
diff --git a/app/frontend/src/components/designer/FormDisclaimer.vue b/app/frontend/src/components/designer/FormDisclaimer.vue
index 7863a8c3f..6a96c71ee 100644
--- a/app/frontend/src/components/designer/FormDisclaimer.vue
+++ b/app/frontend/src/components/designer/FormDisclaimer.vue
@@ -1,19 +1,12 @@
-
diff --git a/app/frontend/src/components/designer/FormSettings.vue b/app/frontend/src/components/designer/FormSettings.vue
index 634d3c2e9..478b3bd7e 100644
--- a/app/frontend/src/components/designer/FormSettings.vue
+++ b/app/frontend/src/components/designer/FormSettings.vue
@@ -1,31 +1,22 @@
-
@@ -46,6 +37,9 @@ export default {
+
+
+
diff --git a/app/frontend/src/components/designer/FormViewer.vue b/app/frontend/src/components/designer/FormViewer.vue
index 74ddcc4c4..42c6714e2 100644
--- a/app/frontend/src/components/designer/FormViewer.vue
+++ b/app/frontend/src/components/designer/FormViewer.vue
@@ -1,8 +1,17 @@
-
@@ -1297,7 +1303,7 @@ export default {
@toggleBlock="toggleBlock"
/>
-
-import { mapState } from 'pinia';
+
diff --git a/app/frontend/src/components/designer/FormsTable.vue b/app/frontend/src/components/designer/FormsTable.vue
index 6bf7aecb3..9fa350128 100644
--- a/app/frontend/src/components/designer/FormsTable.vue
+++ b/app/frontend/src/components/designer/FormsTable.vue
@@ -1,79 +1,72 @@
-
diff --git a/app/frontend/src/components/designer/settings/FormMetadataSettings.vue b/app/frontend/src/components/designer/settings/FormMetadataSettings.vue
new file mode 100644
index 000000000..f10d91692
--- /dev/null
+++ b/app/frontend/src/components/designer/settings/FormMetadataSettings.vue
@@ -0,0 +1,122 @@
+
+
+
+
+ {{
+ $t('trans.formSettings.formMetadataTitle')
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/frontend/src/components/designer/settings/FormScheduleSettings.vue b/app/frontend/src/components/designer/settings/FormScheduleSettings.vue
index 872bc187d..68909117f 100644
--- a/app/frontend/src/components/designer/settings/FormScheduleSettings.vue
+++ b/app/frontend/src/components/designer/settings/FormScheduleSettings.vue
@@ -555,7 +555,7 @@ defineExpose({
cols="12"
md="12"
>
-
+
{{ $t('trans.formSettings.submissionsOpenDateRange') }}
{{ form.schedule.openSubmissionDateTime }}
{{ $t('trans.formSettings.to') }}
@@ -567,9 +567,7 @@ defineExpose({
AVAILABLE_DATES[0]['closeDate'] &&
AVAILABLE_DATES[0]['closeDate'].split(' ')[0]
: ''
- }}
-
- {{
+ }}{{
form.schedule.scheduleType === SCHEDULE_TYPE.CLOSINGDATE
? form.schedule.closeSubmissionDateTime
: ''
@@ -577,11 +575,13 @@ defineExpose({
- {{
+ {{
form.schedule.allowLateSubmissions.enabled &&
form.schedule.allowLateSubmissions.forNext.intervalType &&
form.schedule.allowLateSubmissions.forNext.term
- ? $t('trans.formSettings.allowLateSubmissnInterval') +
+ ? ' ' +
+ $t('trans.formSettings.allowLateSubmissnInterval') +
+ ' ' +
form.schedule.allowLateSubmissions.forNext.term +
' ' +
form.schedule.allowLateSubmissions.forNext.intervalType +
@@ -599,9 +599,11 @@ defineExpose({
AVAILABLE_DATES[1]
"
:lang="locale"
- >{{ $t('trans.formSettings.scheduleRepetition') }}
- {{ form.schedule.repeatSubmission.everyTerm }}
- {{ form.schedule.repeatSubmission.everyIntervalType }}
+ >{{ ' ' + $t('trans.formSettings.scheduleRepetition') }}
+
+ {{ form.schedule.repeatSubmission.everyTerm }}
+ {{ form.schedule.repeatSubmission.everyIntervalType }}
+
{{ $t('trans.formSettings.until') }}
{{ form.schedule.repeatSubmission.repeatUntil }}.
diff --git a/app/frontend/src/components/forms/ExportSubmissions.vue b/app/frontend/src/components/forms/ExportSubmissions.vue
index 870a25cb8..fd0f8b1f3 100644
--- a/app/frontend/src/components/forms/ExportSubmissions.vue
+++ b/app/frontend/src/components/forms/ExportSubmissions.vue
@@ -1,7 +1,8 @@
-
@@ -419,7 +419,11 @@ export default {
{{ $t('trans.exportSubmissions.submissionDate') }}
-
+
-import { mapActions, mapState } from 'pinia';
+
diff --git a/app/frontend/src/components/forms/PrintOptions.vue b/app/frontend/src/components/forms/PrintOptions.vue
index 718decbf2..e6b0c4d46 100644
--- a/app/frontend/src/components/forms/PrintOptions.vue
+++ b/app/frontend/src/components/forms/PrintOptions.vue
@@ -1,360 +1,339 @@
-
@@ -487,6 +466,7 @@ export default {
value="upload"
>
-import { mapState } from 'pinia';
+
diff --git a/app/frontend/src/components/forms/SubmissionsTable.vue b/app/frontend/src/components/forms/SubmissionsTable.vue
index 64ba3e9a8..dc97e9eee 100644
--- a/app/frontend/src/components/forms/SubmissionsTable.vue
+++ b/app/frontend/src/components/forms/SubmissionsTable.vue
@@ -1,8 +1,8 @@
-
@@ -687,7 +689,7 @@ export default {
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({
diff --git a/app/frontend/src/components/forms/submission/MySubmissionsTable.vue b/app/frontend/src/components/forms/submission/MySubmissionsTable.vue
index 28a150531..a8206efd9 100644
--- a/app/frontend/src/components/forms/submission/MySubmissionsTable.vue
+++ b/app/frontend/src/components/forms/submission/MySubmissionsTable.vue
@@ -16,7 +16,6 @@ const properties = defineProps({
},
});
-const filterData = ref([]);
const filterIgnore = ref([
{
key: 'confirmationId',
@@ -32,7 +31,8 @@ const showColumnsDialog = ref(false);
const formStore = useFormStore();
-const { form, formFields, submissionList, isRTL } = storeToRefs(formStore);
+const { form, formFields, mySubmissionPreferences, submissionList, isRTL } =
+ storeToRefs(formStore);
//------------------------ TABLE HEADERS
// These are headers that will be available by default for the
@@ -102,11 +102,11 @@ const HEADERS = computed(() => {
let headers = BASE_HEADERS.value;
// The user selected some columns
- if (filterData.value.length > 0) {
+ if (USER_PREFERENCES.value.length > 0) {
headers = headers.filter(
(header) =>
// It must be in the user selected columns
- filterData.value.some((fd) => fd === header.key) ||
+ USER_PREFERENCES.value.some((up) => up === header.key) ||
// except if it's in the filter ignore
filterIgnore.value.some((fd) => fd.key === header.key)
);
@@ -181,6 +181,21 @@ const isCopyFromExistingSubmissionEnabled = computed(
() => form.value && form.value.enableCopyExistingSubmission
);
+// These are columns that the user has previously selected
+// through the select columns dialog. These are columns
+// that they wish to see in the table in this view.
+const USER_PREFERENCES = computed(() => {
+ let preselectedData = [];
+ if (
+ mySubmissionPreferences.value?.preferences?.formId &&
+ mySubmissionPreferences.value.preferences.formId == properties.formId &&
+ mySubmissionPreferences.value?.preferences?.columns
+ ) {
+ preselectedData = mySubmissionPreferences.value.preferences.columns;
+ }
+ return preselectedData;
+});
+
onBeforeMount(async () => {
await Promise.all([
await formStore.fetchForm(properties.formId),
@@ -280,14 +295,20 @@ async function populateSubmissionsTable() {
}
async function updateFilter(data) {
- filterData.value = data;
+ let preferences = {
+ formId: properties.formId,
+ columns: [],
+ };
+ data.forEach((d) => {
+ preferences.columns.push(d);
+ });
+ mySubmissionPreferences.value.preferences = preferences;
showColumnsDialog.value = false;
}
defineExpose({
BASE_FILTER_HEADERS,
BASE_HEADERS,
- filterData,
filterIgnore,
getCurrentStatus,
getStatusDate,
diff --git a/app/frontend/src/components/forms/submission/StatusPanel.vue b/app/frontend/src/components/forms/submission/StatusPanel.vue
index 9f3e824f3..c5075b3ea 100644
--- a/app/frontend/src/components/forms/submission/StatusPanel.vue
+++ b/app/frontend/src/components/forms/submission/StatusPanel.vue
@@ -1,6 +1,6 @@
@@ -428,14 +517,46 @@ defineExpose({
- {{
+ $t('trans.statusPanel.recipientEmail')
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
@@ -553,13 +674,12 @@ defineExpose({
margin: 0;
}
-@media (max-width: 959px) {
+@media (max-width: 1279px) {
.hide-on-narrow {
display: none;
}
}
-
-@media (min-width: 960px) {
+@media (min-width: 1280px) {
.hide-on-wide {
display: none;
}
diff --git a/app/frontend/src/components/infolinks/GeneralLayout.vue b/app/frontend/src/components/infolinks/GeneralLayout.vue
index 10284a5f4..002279cd9 100644
--- a/app/frontend/src/components/infolinks/GeneralLayout.vue
+++ b/app/frontend/src/components/infolinks/GeneralLayout.vue
@@ -1,138 +1,144 @@
-
@@ -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')
+ }}
+
+