From 9a67cae00beecbe7ce6a1a29405fcf04107c9f10 Mon Sep 17 00:00:00 2001 From: Le Date: Wed, 20 Nov 2024 14:21:52 -0800 Subject: [PATCH 01/11] ccfir-3756 - code refactor, add isAFSComplete check to navBar --- backend/src/components/application.js | 9 +- backend/src/routes/application.js | 7 +- backend/src/util/mapping/Mappings.js | 6 +- .../AFS/ApprovableFeeSchedule.vue | 123 ++++++++++-------- frontend/src/components/util/NavBar.vue | 19 ++- frontend/src/store/application.js | 1 + frontend/src/store/ccfriApp.js | 42 +++++- frontend/src/store/navBar.js | 20 ++- 8 files changed, 146 insertions(+), 81 deletions(-) diff --git a/backend/src/components/application.js b/backend/src/components/application.js index 9a3c6b85..7e53318b 100644 --- a/backend/src/components/application.js +++ b/backend/src/components/application.js @@ -57,17 +57,14 @@ async function renewCCOFApplication(req, res) { } async function patchCCFRIApplication(req, res) { - let payload = req.body; - payload = new MappableObjectForBack(payload, CCFRIFacilityMappings); - payload = payload.toJSON(); - try { - await patchOperationWithObjectId('ccof_applicationccfris', req.params.ccfriId, payload); + const payload = new MappableObjectForBack(req.body, CCFRIFacilityMappings).toJSON(); + const response = await patchOperationWithObjectId('ccof_applicationccfris', req.params.ccfriId, payload); + return res.status(HttpStatus.OK).json(response); } catch (e) { log.error(e); return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json(e.data ? e.data : e?.status); } - return res.status(HttpStatus.OK).json(payload); } async function deleteCCFRIApplication(req, res) { diff --git a/backend/src/routes/application.js b/backend/src/routes/application.js index 0b9d3d59..a3c8edb1 100644 --- a/backend/src/routes/application.js +++ b/backend/src/routes/application.js @@ -11,7 +11,6 @@ const { updateECEWEApplication, updateECEWEFacilityApplication, getApprovableFeeSchedules, - getCCFRIApplication, getDeclaration, submitApplication, updateStatusForApplicationComponents, @@ -26,10 +25,6 @@ router.post('/renew-ccof', passport.authenticate('jwt', { session: false }), isV /* CREATE or UPDATE an existing CCFRI application for opt-in and out CCOF application guid and facility guid are defined in the payload */ -router.get('/ccfri/:ccfriId', passport.authenticate('jwt', { session: false }), isValidBackendToken, [param('ccfriId', 'URL param: [ccfriId] is required').notEmpty().isUUID()], (req, res) => { - validationResult(req).throw(); - return getCCFRIApplication(req, res); -}); router.get('/ccfri/:ccfriId/afs', passport.authenticate('jwt', { session: false }), isValidBackendToken, [param('ccfriId', 'URL param: [ccfriId] is required').notEmpty().isUUID()], (req, res) => { validationResult(req).throw(); @@ -67,7 +62,7 @@ router.patch('/ccfri', passport.authenticate('jwt', { session: false }), isValid }); router.patch('/ccfri/:ccfriId/', passport.authenticate('jwt', { session: false }), isValidBackendToken, [param('ccfriId', 'URL param: [ccfriId] is required').notEmpty().isUUID()], (req, res) => { - //validationResult(req).throw(); + validationResult(req).throw(); return patchCCFRIApplication(req, res); }); diff --git a/backend/src/util/mapping/Mappings.js b/backend/src/util/mapping/Mappings.js index c73c74a3..728bbe5f 100644 --- a/backend/src/util/mapping/Mappings.js +++ b/backend/src/util/mapping/Mappings.js @@ -57,9 +57,7 @@ const CCFRIFacilityMappings = [ { back: 'ccof_chargefeeccfri', front: 'hasClosureFees' }, { back: 'ccof_applicationccfriid', front: 'ccfriApplicationId' }, { back: 'ccof_unlock_rfi', front: 'unlockRfi' }, - - // XXXXXXXXXXXXX: 'licenseEffectiveDate', - // XXXXXXXXXXXXX: 'hasReceivedFunding', + { back: 'ccof_afs_status', front: 'afsStatus' }, ]; const RFIApplicationMappings = [ @@ -319,6 +317,7 @@ const UserProfileCCFRIMappings = [ { back: 'ccof_unlock_nmf_rfi', front: 'unlockNmf' }, { back: 'ccof_unlock_afs', front: 'unlockAfs' }, { back: 'ccof_unlock_afsenable', front: 'enableAfs' }, + { back: 'ccof_afs_status', front: 'afsStatus' }, ...UserProfileBaseCCFRIMappings, ]; const UserProfileECEWEMappings = [ @@ -429,7 +428,6 @@ const ApplicationSummaryCcfriMappings = [ { back: 'ccof_has_rfi', front: 'hasRfi' }, // false, { back: 'ccof_unlock_rfi', front: 'unlockRfi' }, // null, { back: 'ccof_rfi_formcomplete', front: 'isRfiComplete' }, // false, - { back: 'ccof_afs_status', front: 'afsStatus' }, ]; const CCFRIApprovableFeeSchedulesMappings = [ diff --git a/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue b/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue index fa278ff2..de80d76e 100644 --- a/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue +++ b/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue @@ -35,8 +35,9 @@ , we can approve the following parent fee schedule: + @@ -45,48 +46,52 @@
Please call us at 1-888-338-6622 (Option 2) if you have any questions or require assistance.
- -
Please select one of the following options regarding the approvable fee schedule:
- - -
- After submission please wait to receive notification confirming your approval to participate in CCFRI. -
- - -
- After submission please wait to receive confirmation from the ministry on the results of your CCFRI - application. -
-
-
+ + + +
+ Please select one of the following options regarding the approvable fee schedule: +
+ + +
+ After submission, please wait for a notification confirming your approval to participate in CCFRI. +
+ + +
+ After submission please wait to receive confirmation from the ministry on the results of your CCFRI + application. +
+
+
+
+
import { mapState, mapActions } from 'pinia'; +import { isEmpty } from 'lodash'; import ApprovableParentFeesCards from '@/components/ccfriApplication/AFS/ApprovableParentFeesCards.vue'; import FacilityHeader from '@/components/guiComponents/FacilityHeader.vue'; @@ -127,55 +133,48 @@ export default { return { afs: {}, isValidForm: false, - loading: false, processing: false, }; }, computed: { - ...mapState(useAppStore, ['getChildCareCategoryNumberById', 'getFundingUrl', 'getProgramYearOrderById']), - ...mapState(useApplicationStore, ['formattedProgramYear', 'programYearId']), + ...mapState(useAppStore, ['getFundingUrl']), + ...mapState(useApplicationStore, ['formattedProgramYear', 'isApplicationSubmitted', 'programYearId']), + ...mapState(useCcfriAppStore, ['approvableFeeSchedules']), ...mapState(useNavBarStore, ['navBarList', 'nextPath', 'previousPath']), currentFacility() { return this.navBarList.find((el) => el.ccfriApplicationId == this.$route.params.urlGuid); }, + // Note: CCFRI-3752 - AFS for change request is not in scope at this time. + isReadOnly() { + return isEmpty(this.afs) || this.processing || (this.isApplicationSubmitted && !this.currentFacility?.unlockAfs); + }, isFormComplete() { return this.isValidForm; }, }, watch: { + approvableFeeSchedules: { + handler() { + this.reloadAfs(); + }, + }, '$route.params.urlGuid': { - async handler() { - await this.loadData(); + handler() { + this.reloadAfs(); }, }, }, - async created() { + created() { this.rules = rules; this.AFS_STATUSES = AFS_STATUSES; - await this.loadData(); + this.reloadAfs(); }, methods: { - ...mapActions(useCcfriAppStore, ['getApprovableFeeSchedules']), - async loadData() { - try { - this.loading = true; - this.afs = await this.getApprovableFeeSchedules(this.$route.params.urlGuid); - this.afs?.approvableFeeSchedules?.forEach((item) => { - item.programYearOrder = this.getProgramYearOrderById(item.programYearId); - item.childCareCategoryNumber = this.getChildCareCategoryNumberById(item.childCareCategoryId); - }); - this.sortApprovableFeeSchedules(); - } catch (error) { - console.error('Unable to load Approvable Fee Schedules: ' + error); - this.setErrorAlert('Sorry, an unexpected error seems to have occurred.'); - } finally { - this.loading = false; - } - }, - sortApprovableFeeSchedules() { - this.afs?.approvableFeeSchedules?.sort( - (a, b) => a.programYearOrder - b.programYearOrder || a.childCareCategoryNumber - b.childCareCategoryNumber, - ); + ...mapActions(useCcfriAppStore, ['updateApplicationCCFRI']), + ...mapActions(useNavBarStore, ['setNavBarAfsComplete']), + isEmpty, + reloadAfs() { + this.afs = this.approvableFeeSchedules?.find((item) => item.ccfriApplicationId === this.$route.params.urlGuid); }, next() { this.$router.push(this.nextPath); @@ -188,8 +187,22 @@ export default { }, // TODO (vietle-cgi) - CCFRI-3756 - work in progress async save(showMessage) { - if (showMessage) { - this.setSuccessAlert('Changes Successfully Saved'); + try { + if (this.isReadOnly) return; + this.processing = true; + const payload = { + afsStatus: this.afs?.afsStatus, + }; + await this.updateApplicationCCFRI(this.$route.params.urlGuid, payload); + this.setNavBarAfsComplete({ ccfriId: this.$route.params.urlGuid, complete: this.isFormComplete }); + if (showMessage) { + this.setSuccessAlert('Changes Successfully Saved'); + } + } catch (error) { + console.log(error); + this.setFailureAlert('An error occurred while saving. Please try again later.'); + } finally { + this.processing = false; } }, }, diff --git a/frontend/src/components/util/NavBar.vue b/frontend/src/components/util/NavBar.vue index cada2a2b..bc1711d3 100644 --- a/frontend/src/components/util/NavBar.vue +++ b/frontend/src/components/util/NavBar.vue @@ -110,7 +110,7 @@ import { useNavBarStore } from '@/store/navBar.js'; import { useOrganizationStore } from '@/store/ccof/organization.js'; import { useReportChangesStore } from '@/store/reportChanges.js'; -import { NAV_BAR_GROUPS, CHANGE_TYPES, ORGANIZATION_PROVIDER_TYPES } from '@/utils/constants.js'; +import { NAV_BAR_GROUPS, CHANGE_TYPES, ORGANIZATION_PROVIDER_TYPES, PATHS } from '@/utils/constants.js'; import StaticConfig from '@/common/staticConfig.js'; let positionIndex = 0; @@ -143,7 +143,7 @@ export default { 'isRenewal', ]), ...mapState(useAuthStore, ['userInfo']), - ...mapState(useCcfriAppStore, ['getCCFRIById']), + ...mapState(useCcfriAppStore, ['approvableFeeSchedules', 'getCCFRIById']), ...mapState(useFacilityStore, ['isNewFacilityStarted']), ...mapState(useFundingStore, ['isNewFundingStarted']), ...mapState(useNavBarStore, [ @@ -207,8 +207,14 @@ export default { deep: true, }, }, + + async created() { + await this.loadApprovableFeeSchedules(); + }, + methods: { - ...mapActions(useNavBarStore, ['setNavBarItems', 'setCanSubmit']), + ...mapActions(useCcfriAppStore, ['getApprovableFeeSchedulesForFacilities']), + ...mapActions(useNavBarStore, ['checkApprovableFeeSchedulesComplete', 'setNavBarItems', 'setCanSubmit']), setActive(item) { let index = this.items.findIndex((obj) => obj.title === item.title); if (item.active) { @@ -576,7 +582,7 @@ export default { id: item.facilityId, link: { name: 'ccfri-afs', params: { urlGuid: item.ccfriApplicationId } }, isAccessible: true, - icon: this.getCheckbox(item.isAfsComplete), // TODO (vietle-cgi) - CCFRI-3756 - work in progress + icon: this.getCheckbox(item.isAFSComplete), isActive: this.$route.params.urlGuid === item.ccfriApplicationId && 'ccfri-afs' === this.$route.name, position: positionIndex++, navBarId: navBarId++, @@ -1026,6 +1032,11 @@ export default { this.$router.push(page.link); } }, + async loadApprovableFeeSchedules() { + if (!this.$route.path?.includes(`${PATHS.PREFIX.PCF}/`)) return; + await this.getApprovableFeeSchedulesForFacilities(this.userProfileList); + this.checkApprovableFeeSchedulesComplete(); + }, }, }; diff --git a/frontend/src/store/application.js b/frontend/src/store/application.js index 5d660ed3..17c5c09d 100644 --- a/frontend/src/store/application.js +++ b/frontend/src/store/application.js @@ -141,6 +141,7 @@ export const useApplicationStore = defineStore('application', { }, }, getters: { + isApplicationSubmitted: (state) => state.applicationStatus !== 'INCOMPLETE', formattedProgramYear: (state) => formatFiscalYearName(state.programYearLabel), fiscalStartAndEndDates: (state) => { //set fiscal year dates to prevent user from choosing dates outside the current FY diff --git a/frontend/src/store/ccfriApp.js b/frontend/src/store/ccfriApp.js index e5d087e2..0d8afc0b 100644 --- a/frontend/src/store/ccfriApp.js +++ b/frontend/src/store/ccfriApp.js @@ -1,4 +1,4 @@ -import { isEqual } from 'lodash'; +import { isEmpty, isEqual } from 'lodash'; import { defineStore } from 'pinia'; import ApiService from '@/common/apiService.js'; @@ -112,6 +112,7 @@ export const useCcfriAppStore = defineStore('ccfriApp', { ccfriStore: {}, ccfriMedianStore: {}, previousFeeStore: {}, + approvableFeeSchedules: null, }), getters: { getCCFRIById: (state) => (ccfriId) => { @@ -571,12 +572,43 @@ export const useCcfriAppStore = defineStore('ccfriApp', { } }, - async getApprovableFeeSchedules(ccfriId) { + async getApprovableFeeSchedulesForFacilities(facilities) { try { - const response = await ApiService.apiAxios.get(`${ApiRoutes.APPLICATION_CCFRI}/${ccfriId}/afs`); - return response?.data; + if (isEmpty(facilities)) return; + const appStore = useAppStore(); + this.approvableFeeSchedules = []; + const enabledAfsFacilities = facilities?.filter((facility) => facility.enableAfs); + if (isEmpty(enabledAfsFacilities)) return; + await Promise.all( + enabledAfsFacilities?.map(async (facility) => { + const response = await ApiService.apiAxios.get( + `${ApiRoutes.APPLICATION_CCFRI}/${facility.ccfriApplicationId}/afs`, + ); + const afs = response?.data; + afs?.approvableFeeSchedules?.forEach((item) => { + item.programYearOrder = appStore.getProgramYearOrderById(item.programYearId); + item.childCareCategoryNumber = appStore.getChildCareCategoryNumberById(item.childCareCategoryId); + }); + afs?.approvableFeeSchedules?.sort( + (a, b) => + a.programYearOrder - b.programYearOrder || a.childCareCategoryNumber - b.childCareCategoryNumber, + ); + this.approvableFeeSchedules = this.approvableFeeSchedules?.concat(afs); + }), + ); + } catch (e) { + console.log(`Failed to Approvable Fee Schedules for facilities with error - ${e}`); + throw e; + } + }, + + async updateApplicationCCFRI(ccfriId, payload) { + try { + if (!ccfriId || isEmpty(payload)) return; + const response = await ApiService.apiAxios.patch(`${ApiRoutes.APPLICATION_CCFRI}/${ccfriId}`, payload); + return response; } catch (e) { - console.log(`Failed to get existing approvable parent fees with error - ${e}`); + console.log(`Failed to update Application CCFRI with error - ${e}`); throw e; } }, diff --git a/frontend/src/store/navBar.js b/frontend/src/store/navBar.js index 0de0398a..241ef7a5 100644 --- a/frontend/src/store/navBar.js +++ b/frontend/src/store/navBar.js @@ -1,10 +1,12 @@ +import { isEmpty } from 'lodash'; import { defineStore } from 'pinia'; import { useAppStore } from '@/store/app.js'; import { useApplicationStore } from '@/store/application.js'; +import { useCcfriAppStore } from '@/store/ccfriApp.js'; import { useReportChangesStore } from '@/store/reportChanges.js'; import { filterFacilityListForPCF } from '@/utils/common.js'; -import { CHANGE_REQUEST_TYPES, PATHS } from '@/utils/constants.js'; +import { AFS_STATUSES, CHANGE_REQUEST_TYPES, PATHS } from '@/utils/constants.js'; function getActiveIndex(items) { let foundIndex = -1; @@ -258,6 +260,12 @@ export const useNavBarStore = defineStore('navBar', { this.refreshNavBar++; } }, + setNavBarAfsComplete({ ccfriId, complete }) { + const userProfileItem = this.userProfileList?.find((item) => item.ccfriApplicationId === ccfriId); + if (isEmpty(userProfileItem)) return; + userProfileItem.isAFSComplete = complete; + this.refreshNavBarList(); + }, addToNavBar(payload) { this.userProfileList.push(payload); this.filterNavBar(); @@ -383,5 +391,15 @@ export const useNavBarStore = defineStore('navBar', { this.navBarList = filterFacilityListForPCF(this.userProfileList, this.isRenewal, applicationStatus); } }, + checkApprovableFeeSchedulesComplete() { + const ccfriApStore = useCcfriAppStore(); + this.userProfileList?.forEach((facility) => { + const afs = ccfriApStore?.approvableFeeSchedules?.find( + (item) => item.ccfriApplicationId === facility?.ccfriApplicationId, + ); + facility.isAFSComplete = [AFS_STATUSES.ACCEPT, AFS_STATUSES.DECLINE].includes(afs?.afsStatus); + }); + this.refreshNavBarList(); + }, }, }); From 2122f5e6a41e1ca082f2729d28f5ade36beb4c98 Mon Sep 17 00:00:00 2001 From: Le Date: Thu, 21 Nov 2024 10:25:03 -0800 Subject: [PATCH 02/11] ccfri-3756 - add AppDocumentUpload --- frontend/package-lock.json | 26 ++ frontend/package.json | 1 + .../AFS/ApprovableFeeSchedule.vue | 11 +- .../src/components/util/AppDocumentUpload.vue | 247 ++++++++++++++++++ frontend/src/utils/constants.js | 3 + 5 files changed, 284 insertions(+), 4 deletions(-) create mode 100644 frontend/src/components/util/AppDocumentUpload.vue diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 99f1347d..3c3b841d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -30,6 +30,7 @@ "vue-pdf-app": "^2.1.0", "vue-quick-chat": "^1.2.8", "vue-router": "^4.4.3", + "vue-uuid": "^3.0.0", "vuetify": "^3.7.1", "vuex-map-fields": "^1.4.1" }, @@ -927,6 +928,11 @@ "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.4.2.tgz", "integrity": "sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==" }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" + }, "node_modules/@vitejs/plugin-vue": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.3.tgz", @@ -2978,6 +2984,14 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/vite": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz", @@ -3220,6 +3234,18 @@ "vue": "^3.2.0" } }, + "node_modules/vue-uuid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vue-uuid/-/vue-uuid-3.0.0.tgz", + "integrity": "sha512-+5DP857xVmTHYd00dMC1c1gVg/nxG6+K4Lepojv9ckHt8w0fDpGc5gQCCttS9D+AkSkTJgb0cekidKjTWu5OQQ==", + "dependencies": { + "@types/uuid": "^8.3.4", + "uuid": "^8.3.2" + }, + "peerDependencies": { + "vue": ">= 3.0.0" + } + }, "node_modules/vuetify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.7.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index bc4d1346..ea385424 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -44,6 +44,7 @@ "vue-pdf-app": "^2.1.0", "vue-quick-chat": "^1.2.8", "vue-router": "^4.4.3", + "vue-uuid": "^3.0.0", "vuetify": "^3.7.1", "vuex-map-fields": "^1.4.1" }, diff --git a/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue b/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue index de80d76e..bf28fdbc 100644 --- a/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue +++ b/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue @@ -52,7 +52,7 @@
  • Upload Supporting Documents: By selecting "I want to upload supporting documents", you confirm that you decline the approvable fee schedule and have new - information to submit for review, This will require additional processing time for your application. + information to submit for review. This will require additional processing time for your application.
  • Decline the fee schedule: By selecting "I decline", @@ -74,7 +74,8 @@
    - After submission, please wait for a notification confirming your approval to participate in CCFRI. + After submission please wait to receive notification confirming your approval to participate in + CCFRI.
    @@ -84,6 +85,7 @@
    + @@ -109,6 +111,7 @@ import { isEmpty } from 'lodash'; import ApprovableParentFeesCards from '@/components/ccfriApplication/AFS/ApprovableParentFeesCards.vue'; import FacilityHeader from '@/components/guiComponents/FacilityHeader.vue'; +import AppDocumentUpload from '@/components/util/AppDocumentUpload.vue'; import NavButton from '@/components/util/NavButton.vue'; import alertMixin from '@/mixins/alertMixin.js'; @@ -123,7 +126,7 @@ import rules from '@/utils/rules.js'; export default { name: 'ApprovableFeeSchedule', - components: { ApprovableParentFeesCards, FacilityHeader, NavButton }, + components: { AppDocumentUpload, ApprovableParentFeesCards, FacilityHeader, NavButton }, mixins: [alertMixin], async beforeRouteLeave(_to, _from, next) { await this.save(false); @@ -142,7 +145,7 @@ export default { ...mapState(useCcfriAppStore, ['approvableFeeSchedules']), ...mapState(useNavBarStore, ['navBarList', 'nextPath', 'previousPath']), currentFacility() { - return this.navBarList.find((el) => el.ccfriApplicationId == this.$route.params.urlGuid); + return this.navBarList?.find((el) => el.ccfriApplicationId === this.$route.params.urlGuid); }, // Note: CCFRI-3752 - AFS for change request is not in scope at this time. isReadOnly() { diff --git a/frontend/src/components/util/AppDocumentUpload.vue b/frontend/src/components/util/AppDocumentUpload.vue new file mode 100644 index 00000000..b3da61e2 --- /dev/null +++ b/frontend/src/components/util/AppDocumentUpload.vue @@ -0,0 +1,247 @@ + + + diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index cd8b8c0b..918084f4 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -293,3 +293,6 @@ export const PARENT_FEE_FREQUENCIES = Object.freeze({ WEEKLY: 100000001, DAILY: 100000002, }); + +export const DOCUMENTS_REQUIREMENT_MESSAGE = + 'The maximum file size is 2MB for each document. Accepted file types are jpg, jpeg, heic, png, pdf, docx, doc, xls, and xlsx.'; From 5f2d9c31a30ca1aad843acdb0c731dd998cbd8cd Mon Sep 17 00:00:00 2001 From: Le Date: Thu, 21 Nov 2024 11:40:38 -0800 Subject: [PATCH 03/11] ccfri-3756 - clean up AppDocumentUpload --- .../AFS/ApprovableFeeSchedule.vue | 6 ++- .../src/components/util/AppDocumentUpload.vue | 54 +++++++++---------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue b/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue index bf28fdbc..73b828c5 100644 --- a/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue +++ b/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue @@ -85,7 +85,11 @@ - + diff --git a/frontend/src/components/util/AppDocumentUpload.vue b/frontend/src/components/util/AppDocumentUpload.vue index b3da61e2..f9712e5c 100644 --- a/frontend/src/components/util/AppDocumentUpload.vue +++ b/frontend/src/components/util/AppDocumentUpload.vue @@ -1,28 +1,21 @@ diff --git a/frontend/src/components/util/AppDocumentUpload.vue b/frontend/src/components/util/AppDocumentUpload.vue index f9712e5c..d9767794 100644 --- a/frontend/src/components/util/AppDocumentUpload.vue +++ b/frontend/src/components/util/AppDocumentUpload.vue @@ -1,5 +1,5 @@ diff --git a/frontend/src/components/util/NavBar.vue b/frontend/src/components/util/NavBar.vue index ee0ee149..0db4106f 100644 --- a/frontend/src/components/util/NavBar.vue +++ b/frontend/src/components/util/NavBar.vue @@ -190,6 +190,10 @@ export default { expandedNavBarItems() { return this.items?.filter((item) => item.expanded)?.map((item) => item.title); }, + + isApplication() { + return this.$route.path?.includes(`${PATHS.PREFIX.PCF}/`); + }, }, watch: { navRefresh: { @@ -209,12 +213,25 @@ export default { }, async created() { - await this.loadApprovableFeeSchedules(); + await this.loadData(); }, methods: { + ...mapActions(useApplicationStore, ['getApplicationUploadedDocuments']), ...mapActions(useCcfriAppStore, ['getApprovableFeeSchedulesForFacilities']), ...mapActions(useNavBarStore, ['checkApprovableFeeSchedulesComplete', 'setNavBarItems', 'setCanSubmit']), + async loadData() { + try { + if (this.isApplication) { + await this.getApprovableFeeSchedulesForFacilities(this.userProfileList); + await this.getApplicationUploadedDocuments(); + this.checkApprovableFeeSchedulesComplete(); + } + } catch (error) { + console.log(error); + this.setFailureAlert('An error occurred while loading. Please try again later.'); + } + }, setActive(item) { let index = this.items.findIndex((obj) => obj.title === item.title); if (item.active) { @@ -1032,11 +1049,6 @@ export default { this.$router.push(page.link); } }, - async loadApprovableFeeSchedules() { - if (!this.$route.path?.includes(`${PATHS.PREFIX.PCF}/`)) return; - await this.getApprovableFeeSchedulesForFacilities(this.userProfileList); - this.checkApprovableFeeSchedulesComplete(); - }, }, }; diff --git a/frontend/src/services/documentService.js b/frontend/src/services/documentService.js new file mode 100644 index 00000000..bfd7d80d --- /dev/null +++ b/frontend/src/services/documentService.js @@ -0,0 +1,40 @@ +import ApiService from '@/common/apiService'; +import { ApiRoutes } from '@/utils/constants'; + +// function sortDocuments(documents) { +// documents?.sort((doc1, doc2) => { +// return new Date(doc1.lastUpdatedTime) - new Date(doc2.lastUpdatedTime); +// }); +// return documents; +// } + +export default { + async getApplicationUploadedDocuments(applicationId) { + try { + if (!applicationId) return; + const response = await ApiService.apiAxios.get(`${ApiRoutes.DOCUMENT_APPLICATION}/${applicationId}`); + return response?.data; + } catch (error) { + console.log(`Failed to get application's documents - ${error}`); + throw error; + } + }, + + async createDocuments(payload) { + try { + await ApiService.apiAxios.post(ApiRoutes.DOCUMENT_APPLICATION, payload); + } catch (error) { + console.log(`Failed to create application's documents - ${error}`); + throw error; + } + }, + + async deleteDocuments(payload) { + try { + await ApiService.apiAxios.delete(ApiRoutes.DOCUMENT_APPLICATION, payload); + } catch (error) { + console.log(`Failed to delete application's documents - ${error}`); + throw error; + } + }, +}; diff --git a/frontend/src/store/application.js b/frontend/src/store/application.js index 9a510642..9c1464db 100644 --- a/frontend/src/store/application.js +++ b/frontend/src/store/application.js @@ -1,6 +1,7 @@ import { defineStore } from 'pinia'; import ApiService from '@/common/apiService.js'; +import DocumentService from '@/services/documentService'; import { useAppStore } from '@/store/app.js'; import { useNavBarStore } from '@/store/navBar.js'; import { checkApplicationUnlocked, filterFacilityListForPCF } from '@/utils/common.js'; @@ -28,6 +29,8 @@ export const useApplicationStore = defineStore('application', { ccofConfirmationEnabled: false, applicationMap: new Map(), + + uploadedDocuments: [], }), actions: { setApplicationId(value) { @@ -143,6 +146,14 @@ export const useApplicationStore = defineStore('application', { throw error; } }, + async getApplicationUploadedDocuments() { + try { + this.uploadedDocuments = await DocumentService.getApplicationUploadedDocuments(this.applicationId); + } catch (error) { + console.log(error); + throw error; + } + }, }, getters: { isApplicationSubmitted: (state) => state.applicationStatus !== 'INCOMPLETE', diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index 918084f4..94f706ff 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -50,6 +50,7 @@ export const ApiRoutes = Object.freeze({ CHANGE_REQUEST: baseRoot + '/changeRequest/', PDFS: baseRoot + '/pdf', PDF: baseRoot + '/pdf/getDocument/', + DOCUMENT_APPLICATION: baseRoot + '/document/application', }); export const PAGE_TITLES = Object.freeze({ @@ -296,3 +297,7 @@ export const PARENT_FEE_FREQUENCIES = Object.freeze({ export const DOCUMENTS_REQUIREMENT_MESSAGE = 'The maximum file size is 2MB for each document. Accepted file types are jpg, jpeg, heic, png, pdf, docx, doc, xls, and xlsx.'; + +export const DOCUMENT_TYPES = Object.freeze({ + APPLICATION_AFS: 'AFS - Supporting Documents', +}); From f18aa29c72b4c935a84fe9acbc90f2f3f965b1af Mon Sep 17 00:00:00 2001 From: Le Date: Tue, 26 Nov 2024 00:18:33 -0800 Subject: [PATCH 05/11] ccfri-3756 - add delete document, Summary wip --- backend/src/components/document.js | 10 +- backend/src/util/mapping/Mappings.js | 2 + .../src/components/SummaryDeclaration.vue | 11 ++ .../AFS/ApprovableFeeSchedule.vue | 56 ++++++--- .../components/summary/group/AFSSummary.vue | 112 ++++++++++++++++++ .../src/components/util/AppDocumentUpload.vue | 20 ++-- frontend/src/components/util/NavBar.vue | 28 ++++- frontend/src/services/documentService.js | 8 +- frontend/src/store/application.js | 4 +- frontend/src/store/navBar.js | 13 +- frontend/src/utils/constants.js | 3 - 11 files changed, 215 insertions(+), 52 deletions(-) create mode 100644 frontend/src/components/summary/group/AFSSummary.vue diff --git a/backend/src/components/document.js b/backend/src/components/document.js index 29c2165f..59b6c4e8 100644 --- a/backend/src/components/document.js +++ b/backend/src/components/document.js @@ -41,10 +41,12 @@ async function getApplicationDocuments(req, res) { async function deleteUploadedDocuments(req, res) { try { - let deletedDocuments = req.body; - for (let annotationid of deletedDocuments) { - await deleteDocument(annotationid); - } + const deletedDocuments = req.body; + await Promise.all( + deletedDocuments.map(async (annotationId) => { + await deleteDocument(annotationId); + }), + ); return res.sendStatus(HttpStatus.OK); } catch (e) { log.error(e); diff --git a/backend/src/util/mapping/Mappings.js b/backend/src/util/mapping/Mappings.js index a6117c6a..b5ea8e22 100644 --- a/backend/src/util/mapping/Mappings.js +++ b/backend/src/util/mapping/Mappings.js @@ -57,6 +57,8 @@ const CCFRIFacilityMappings = [ { back: 'ccof_chargefeeccfri', front: 'hasClosureFees' }, { back: 'ccof_applicationccfriid', front: 'ccfriApplicationId' }, { back: 'ccof_unlock_rfi', front: 'unlockRfi' }, + { back: 'ccof_unlock_afs', front: 'unlockAfs' }, + { back: 'ccof_unlock_afsenable', front: 'enableAfs' }, { back: 'ccof_afs_status', front: 'afsStatus' }, ]; diff --git a/frontend/src/components/SummaryDeclaration.vue b/frontend/src/components/SummaryDeclaration.vue index aa04afb8..897c066c 100644 --- a/frontend/src/components/SummaryDeclaration.vue +++ b/frontend/src/components/SummaryDeclaration.vue @@ -172,6 +172,14 @@ @is-summary-valid="isFormComplete" /> + + + @@ -141,10 +142,25 @@ export default { await this.save(false); next(); }, + props: { + readonly: { + type: Boolean, + default: false, + }, + ccfriApplicationId: { + type: String, + default: '', + }, + facilityId: { + type: String, + default: '', + }, + }, data() { return { afs: {}, documentsToUpload: [], + uploadedDocumentsToDelete: [], isValidForm: false, processing: false, }; @@ -156,15 +172,17 @@ export default { 'formattedProgramYear', 'isApplicationSubmitted', 'programYearId', - 'uploadedDocuments', + 'applicationUploadedDocuments', ]), ...mapState(useCcfriAppStore, ['approvableFeeSchedules']), ...mapState(useNavBarStore, ['navBarList', 'nextPath', 'previousPath']), currentFacility() { - return this.navBarList?.find((el) => el.ccfriApplicationId === this.$route.params.urlGuid); + return this.facilityId + ? this.navBarList?.find((el) => el.facilityId === this.facilityId) + : this.navBarList?.find((el) => el.ccfriApplicationId === this.$route.params.urlGuid); }, filteredUploadedDocuments() { - return this.uploadedDocuments?.filter( + return this.applicationUploadedDocuments?.filter( (document) => document.documentType === DOCUMENT_TYPES.APPLICATION_AFS && document.facilityId === this.currentFacility?.facilityId, @@ -175,7 +193,7 @@ export default { }, // Note: CCFRI-3752 - AFS for change request is not in scope at this time. isReadOnly() { - return this.isLoading || (this.isApplicationSubmitted && !this.currentFacility?.unlockAfs); + return this.readonly || this.isLoading || (this.isApplicationSubmitted && !this.currentFacility?.unlockAfs); }, isSupportingDocumentsUploaded() { return this.filteredUploadedDocuments?.length + this.documentsToUpload?.length > 0; @@ -212,7 +230,9 @@ export default { ...mapActions(useSupportingDocumentUploadStore, ['saveUploadedDocuments']), isEmpty, reloadAfs() { - this.afs = this.approvableFeeSchedules?.find((item) => item.ccfriApplicationId === this.$route.params.urlGuid); + this.afs = this.ccfriApplicationId + ? this.approvableFeeSchedules?.find((item) => item.ccfriApplicationId === this.ccfriApplicationId) + : this.approvableFeeSchedules?.find((item) => item.ccfriApplicationId === this.$route.params.urlGuid); }, next() { this.$router.push(this.nextPath); @@ -233,6 +253,8 @@ export default { }; await this.updateApplicationCCFRI(this.$route.params.urlGuid, payload); await this.processDocumentsToUpload(); + await DocumentService.deleteDocuments(this.uploadedDocumentsToDelete); + await this.getApplicationUploadedDocuments(); this.setNavBarAfsComplete({ ccfriId: this.$route.params.urlGuid, complete: this.isFormComplete }); if (showMessage) { this.setSuccessAlert('Changes Successfully Saved'); @@ -248,18 +270,20 @@ export default { this.documentsToUpload = updatedDocuments; }, async processDocumentsToUpload() { - try { - const payload = cloneDeep(this.documentsToUpload); - payload.forEach((document) => { - document.ccof_applicationid = this.applicationId; - document.ccof_facility = this.currentFacility?.facilityId; - delete document.file; - }); - await DocumentService.createDocuments(payload); - await this.getApplicationUploadedDocuments(); - } catch { - this.setFailureAlert('An error occurred while saving. Please try again later.'); + const payload = cloneDeep(this.documentsToUpload); + payload.forEach((document) => { + document.ccof_applicationid = this.applicationId; + document.ccof_facility = this.currentFacility?.facilityId; + delete document.file; + }); + await DocumentService.createDocuments(payload); + }, + updateUploadedDocumentsToDelete(annotationId) { + const index = this.applicationUploadedDocuments?.findIndex((item) => item.annotationId === annotationId); + if (index > -1) { + this.applicationUploadedDocuments?.splice(index, 1); } + this.uploadedDocumentsToDelete?.push(annotationId); }, }, }; diff --git a/frontend/src/components/summary/group/AFSSummary.vue b/frontend/src/components/summary/group/AFSSummary.vue new file mode 100644 index 00000000..92b49377 --- /dev/null +++ b/frontend/src/components/summary/group/AFSSummary.vue @@ -0,0 +1,112 @@ + + + diff --git a/frontend/src/components/util/AppDocumentUpload.vue b/frontend/src/components/util/AppDocumentUpload.vue index d9767794..87113b22 100644 --- a/frontend/src/components/util/AppDocumentUpload.vue +++ b/frontend/src/components/util/AppDocumentUpload.vue @@ -4,7 +4,10 @@ {{ title }} (Required) -
    {{ DOCUMENTS_REQUIREMENT_MESSAGE }}
    +
    + The maximum file size is 2MB for each document. Accepted file types are jpg, jpeg, heic, png, pdf, docx, doc, xls, + and xlsx. +
    @@ -79,7 +79,6 @@ import { uuid } from 'vue-uuid'; import AppButton from '@/components/guiComponents/AppButton.vue'; import alertMixin from '@/mixins/alertMixin.js'; -import { DOCUMENTS_REQUIREMENT_MESSAGE } from '@/utils/constants'; import { humanFileSize, getFileExtensionWithDot, getFileNameWithMaxNameLength } from '@/utils/file'; export default { @@ -143,8 +142,7 @@ export default { }, }, created() { - this.DOCUMENTS_REQUIREMENT_MESSAGE = DOCUMENTS_REQUIREMENT_MESSAGE; - this.MAX_FILE_SIZE = 4194304; // 4 MB + this.MAX_FILE_SIZE = 2100000; // 2.18 MB is max size since after base64 encoding it might grow upto 3 MB. this.fileExtensionAccept = ['.pdf', '.png', '.jpg', '.jpeg', '.heic', '.doc', '.docx', '.xls', '.xlsx']; this.fileFormats = 'PDF, JPEG, JPG, PNG, HEIC, DOC, DOCX, XLS, and XLSX'; this.fileRules = [ diff --git a/frontend/src/components/util/NavBar.vue b/frontend/src/components/util/NavBar.vue index 0db4106f..a430573a 100644 --- a/frontend/src/components/util/NavBar.vue +++ b/frontend/src/components/util/NavBar.vue @@ -99,6 +99,7 @@ diff --git a/frontend/src/services/documentService.js b/frontend/src/services/documentService.js index bfd7d80d..77b4a1b2 100644 --- a/frontend/src/services/documentService.js +++ b/frontend/src/services/documentService.js @@ -1,3 +1,5 @@ +import { isEmpty } from 'lodash'; + import ApiService from '@/common/apiService'; import { ApiRoutes } from '@/utils/constants'; @@ -22,6 +24,7 @@ export default { async createDocuments(payload) { try { + if (isEmpty(payload)) return; await ApiService.apiAxios.post(ApiRoutes.DOCUMENT_APPLICATION, payload); } catch (error) { console.log(`Failed to create application's documents - ${error}`); @@ -29,9 +32,10 @@ export default { } }, - async deleteDocuments(payload) { + async deleteDocuments(deletedFiles) { try { - await ApiService.apiAxios.delete(ApiRoutes.DOCUMENT_APPLICATION, payload); + if (isEmpty(deletedFiles)) return; + await ApiService.apiAxios.delete(ApiRoutes.DOCUMENT_APPLICATION, { data: deletedFiles }); } catch (error) { console.log(`Failed to delete application's documents - ${error}`); throw error; diff --git a/frontend/src/store/application.js b/frontend/src/store/application.js index 9c1464db..880ec135 100644 --- a/frontend/src/store/application.js +++ b/frontend/src/store/application.js @@ -30,7 +30,7 @@ export const useApplicationStore = defineStore('application', { ccofConfirmationEnabled: false, applicationMap: new Map(), - uploadedDocuments: [], + applicationUploadedDocuments: [], }), actions: { setApplicationId(value) { @@ -148,7 +148,7 @@ export const useApplicationStore = defineStore('application', { }, async getApplicationUploadedDocuments() { try { - this.uploadedDocuments = await DocumentService.getApplicationUploadedDocuments(this.applicationId); + this.applicationUploadedDocuments = await DocumentService.getApplicationUploadedDocuments(this.applicationId); } catch (error) { console.log(error); throw error; diff --git a/frontend/src/store/navBar.js b/frontend/src/store/navBar.js index 241ef7a5..209ae0df 100644 --- a/frontend/src/store/navBar.js +++ b/frontend/src/store/navBar.js @@ -3,10 +3,9 @@ import { defineStore } from 'pinia'; import { useAppStore } from '@/store/app.js'; import { useApplicationStore } from '@/store/application.js'; -import { useCcfriAppStore } from '@/store/ccfriApp.js'; import { useReportChangesStore } from '@/store/reportChanges.js'; import { filterFacilityListForPCF } from '@/utils/common.js'; -import { AFS_STATUSES, CHANGE_REQUEST_TYPES, PATHS } from '@/utils/constants.js'; +import { CHANGE_REQUEST_TYPES, PATHS } from '@/utils/constants.js'; function getActiveIndex(items) { let foundIndex = -1; @@ -391,15 +390,5 @@ export const useNavBarStore = defineStore('navBar', { this.navBarList = filterFacilityListForPCF(this.userProfileList, this.isRenewal, applicationStatus); } }, - checkApprovableFeeSchedulesComplete() { - const ccfriApStore = useCcfriAppStore(); - this.userProfileList?.forEach((facility) => { - const afs = ccfriApStore?.approvableFeeSchedules?.find( - (item) => item.ccfriApplicationId === facility?.ccfriApplicationId, - ); - facility.isAFSComplete = [AFS_STATUSES.ACCEPT, AFS_STATUSES.DECLINE].includes(afs?.afsStatus); - }); - this.refreshNavBarList(); - }, }, }); diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index 94f706ff..29ea3dba 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -295,9 +295,6 @@ export const PARENT_FEE_FREQUENCIES = Object.freeze({ DAILY: 100000002, }); -export const DOCUMENTS_REQUIREMENT_MESSAGE = - 'The maximum file size is 2MB for each document. Accepted file types are jpg, jpeg, heic, png, pdf, docx, doc, xls, and xlsx.'; - export const DOCUMENT_TYPES = Object.freeze({ APPLICATION_AFS: 'AFS - Supporting Documents', }); From 0dc1b998eb7bd56cada35d94dd54b057a359a6cd Mon Sep 17 00:00:00 2001 From: Le Date: Tue, 26 Nov 2024 14:54:21 -0800 Subject: [PATCH 06/11] ccfri-3756 - add relock AFS to submit appication payload and more code refactor --- .../src/components/SummaryDeclaration.vue | 13 +- .../ccfriApplication/AFS/AfsDecisionCard.vue | 63 ++++++++++ .../AFS/ApprovableFeeSchedule.vue | 58 +++------ .../components/summary/group/AFSSummary.vue | 117 +++++++++++++----- .../src/components/util/AppDocumentUpload.vue | 36 +++--- frontend/src/components/util/NavBar.vue | 6 +- frontend/src/store/summaryDeclaration.js | 7 +- 7 files changed, 207 insertions(+), 93 deletions(-) create mode 100644 frontend/src/components/ccfriApplication/AFS/AfsDecisionCard.vue diff --git a/frontend/src/components/SummaryDeclaration.vue b/frontend/src/components/SummaryDeclaration.vue index 897c066c..bc6e785c 100644 --- a/frontend/src/components/SummaryDeclaration.vue +++ b/frontend/src/components/SummaryDeclaration.vue @@ -441,9 +441,11 @@ import { useAppStore } from '@/store/app.js'; import { useOrganizationStore } from '@/store/ccof/organization.js'; import { useSummaryDeclarationStore } from '@/store/summaryDeclaration.js'; import { useApplicationStore } from '@/store/application.js'; +import { useCcfriAppStore } from '@/store/ccfriApp.js'; import { useReportChangesStore } from '@/store/reportChanges.js'; import { + AFS_STATUSES, PATHS, CHANGE_REQUEST_TYPES, PROGRAM_YEAR_LANGUAGE_TYPES, @@ -529,6 +531,7 @@ export default { 'isEceweComplete', 'applicationMap', ]), + ...mapState(useCcfriAppStore, ['approvableFeeSchedules']), ...mapState(useReportChangesStore, ['changeRequestStore', 'isCREceweComplete', 'isCRLicenseComplete']), languageYearLabel() { return this.getLanguageYearLabel; @@ -809,14 +812,22 @@ export default { unlockCcfri: facility.unlockCcfri, unlockNmf: facility.unlockNmf, unlockRfi: facility.unlockRfi, + unlockAfs: facility.unlockAfs, }; // Create payload with only unlock propteries set to 1. - unlockPayload = Object.fromEntries(Object.entries(unlockPayload).filter(([_, v]) => v == 1)); // Update payload unlock properties from 1 to 0. Object.keys(unlockPayload).forEach((key) => { unlockPayload[key] = '0'; }); + + const afs = this.approvableFeeSchedules?.find( + (item) => item.ccfriApplicationId === facility.ccfriApplicationId, + ); + if (afs?.afsStatus === AFS_STATUSES.UPLOAD_DOCUMENTS) { + unlockPayload.enableAfs = '0'; + } + if (Object.keys(unlockPayload).length > 0) { ccrfiRelockPayload.push({ ...applicationIdPayload, ...unlockPayload }); } diff --git a/frontend/src/components/ccfriApplication/AFS/AfsDecisionCard.vue b/frontend/src/components/ccfriApplication/AFS/AfsDecisionCard.vue new file mode 100644 index 00000000..5bd0df51 --- /dev/null +++ b/frontend/src/components/ccfriApplication/AFS/AfsDecisionCard.vue @@ -0,0 +1,63 @@ + + + + diff --git a/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue b/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue index 8068ef81..e5f2ee3b 100644 --- a/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue +++ b/frontend/src/components/ccfriApplication/AFS/ApprovableFeeSchedule.vue @@ -67,29 +67,13 @@ - -
    - Please select one of the following options regarding the approvable fee schedule: -
    - - -
    - After submission please wait to receive notification confirming your approval to participate in - CCFRI. -
    - - -
    - After submission please wait to receive confirmation from the ministry on the results of your CCFRI - application. -
    -
    -
    + el.facilityId === this.facilityId) - : this.navBarList?.find((el) => el.ccfriApplicationId === this.$route.params.urlGuid); + return this.navBarList?.find((el) => el.ccfriApplicationId === this.$route.params.urlGuid); }, filteredUploadedDocuments() { return this.applicationUploadedDocuments?.filter( @@ -193,7 +163,7 @@ export default { }, // Note: CCFRI-3752 - AFS for change request is not in scope at this time. isReadOnly() { - return this.readonly || this.isLoading || (this.isApplicationSubmitted && !this.currentFacility?.unlockAfs); + return this.isLoading || (this.isApplicationSubmitted && !this.currentFacility?.unlockAfs); }, isSupportingDocumentsUploaded() { return this.filteredUploadedDocuments?.length + this.documentsToUpload?.length > 0; @@ -214,6 +184,7 @@ export default { '$route.params.urlGuid': { handler() { this.reloadAfs(); + this.$refs.form?.validate(); }, }, }, @@ -230,15 +201,14 @@ export default { ...mapActions(useSupportingDocumentUploadStore, ['saveUploadedDocuments']), isEmpty, reloadAfs() { - this.afs = this.ccfriApplicationId - ? this.approvableFeeSchedules?.find((item) => item.ccfriApplicationId === this.ccfriApplicationId) - : this.approvableFeeSchedules?.find((item) => item.ccfriApplicationId === this.$route.params.urlGuid); + this.afs = this.approvableFeeSchedules?.find((item) => item.ccfriApplicationId === this.$route.params.urlGuid); }, next() { this.$router.push(this.nextPath); }, validateForm() { this.$refs.form?.validate(); + this.showErrorMessage = true; }, back() { this.$router.push(this.previousPath); @@ -251,9 +221,11 @@ export default { const payload = { afsStatus: this.afs?.afsStatus, }; - await this.updateApplicationCCFRI(this.$route.params.urlGuid, payload); - await this.processDocumentsToUpload(); - await DocumentService.deleteDocuments(this.uploadedDocumentsToDelete); + await Promise.all([ + this.updateApplicationCCFRI(this.$route.params.urlGuid, payload), + this.processDocumentsToUpload(), + DocumentService.deleteDocuments(this.uploadedDocumentsToDelete), + ]); await this.getApplicationUploadedDocuments(); this.setNavBarAfsComplete({ ccfriId: this.$route.params.urlGuid, complete: this.isFormComplete }); if (showMessage) { diff --git a/frontend/src/components/summary/group/AFSSummary.vue b/frontend/src/components/summary/group/AFSSummary.vue index 92b49377..ab2e4533 100644 --- a/frontend/src/components/summary/group/AFSSummary.vue +++ b/frontend/src/components/summary/group/AFSSummary.vue @@ -1,37 +1,62 @@ diff --git a/frontend/src/components/util/AppDocumentUpload.vue b/frontend/src/components/util/AppDocumentUpload.vue index 0a2e3d59..5c4a31da 100644 --- a/frontend/src/components/util/AppDocumentUpload.vue +++ b/frontend/src/components/util/AppDocumentUpload.vue @@ -255,8 +255,4 @@ export default { overflow: hidden; text-overflow: ellipsis; } - -.error-message { - color: #ff5252; -}