@gov-cy/govcy-express-services 1.0.0-alpha.17 → 1.0.0-alpha.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1263,7 +1263,7 @@ The data is collected from the form elements and the data layer and are sent via
1263
1263
  "submissionDataVersion": "0.1", // Submission data version
1264
1264
  "submissionData": { // Submission raw data. Object, will be stringified
1265
1265
  "index": { // Page level
1266
- "id_select": ["id", "arc"], // field level. Could be string or array
1266
+ "id_select": ["id", "arc"], // field level: checkboxes are ALWAYS arrays (may be []); radios/select/text are strings
1267
1267
  "id_number": "654654",
1268
1268
  "arc_number": "",
1269
1269
  "aka": "232323",
@@ -1516,8 +1516,8 @@ The data is collected from the form elements and the data layer and are sent via
1516
1516
  "el": "Ταυτοποίηση",
1517
1517
  "en": "Identification"
1518
1518
  },
1519
- "value": ["id", "arc"], // Field value. Could be string or array
1520
- "valueLabel": [ // Field value label. Could be string or array
1519
+ "value": ["id", "arc"], // Field value. // field level: checkboxes are ALWAYS arrays (may be []); radios/select/text are strings
1520
+ "valueLabel": [ // Field value label
1521
1521
  {
1522
1522
  "el": "Ταυτότητα",
1523
1523
  "en": "ID",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gov-cy/govcy-express-services",
3
- "version": "1.0.0-alpha.17",
3
+ "version": "1.0.0-alpha.18",
4
4
  "description": "An Express-based system that dynamically renders services using @gov-cy/govcy-frontend-renderer and posts data to a submission API.",
5
5
  "author": "DMRID - DSF Team",
6
6
  "license": "MIT",
@@ -220,6 +220,12 @@ export function govcyFileDeletePostHandler() {
220
220
 
221
221
  //if no validation errors
222
222
  if (req.body.deleteFile === "yes") {
223
+ //TODO: Check if fileDeleteAPIEndpoint exists and call the API to delete the file from the storage
224
+ // if it exists, check that the Env vars are set
225
+ // construct url
226
+ // get user
227
+ // call the API
228
+ // if succeeded all good
223
229
  dataLayer.storePageDataElement(req.session, siteId, pageUrl, elementName, "");
224
230
  logger.info(`File deleted by user`, { siteId, pageUrl, elementName });
225
231
  }
@@ -17,7 +17,7 @@ import { logger } from "./govcyLogger.mjs";
17
17
  export function prepareSubmissionData(req, siteId, service) {
18
18
  // Get the raw data from the session store
19
19
  // const rawData = dataLayer.getSiteInputData(req.session, siteId);
20
-
20
+
21
21
  // ----- Conditional logic comes here
22
22
  // Filter site input data based on active pages only
23
23
  // const rawData = {};
@@ -143,7 +143,7 @@ export function prepareSubmissionData(req, siteId, service) {
143
143
  * @returns {object} The API-ready submission data object with all fields as strings
144
144
  */
145
145
  export function prepareSubmissionDataAPI(data) {
146
-
146
+
147
147
  return {
148
148
  submissionUsername: String(data.submissionUsername ?? ""),
149
149
  submissionEmail: String(data.submissionEmail ?? ""),
@@ -232,7 +232,7 @@ export function preparePrintFriendlyData(req, siteId, service) {
232
232
  }
233
233
  }
234
234
 
235
- return submissionData ;
235
+ return submissionData;
236
236
  }
237
237
 
238
238
  //------------------------------- Helper Functions -------------------------------//
@@ -317,6 +317,19 @@ function getValue(formElement, pageUrl, req, siteId) {
317
317
  } else {
318
318
  value = dataLayer.getFormDataValue(req.session, siteId, pageUrl, formElement.params.name);
319
319
  }
320
+
321
+ // 🔁 Normalize checkboxes: always return an array
322
+ if (formElement.element === "checkboxes") {
323
+ // If no value, return empty array
324
+ if (value == null || value === "") return [];
325
+ // If already an array, return as-is (but strip empties just in case)
326
+ if (Array.isArray(value)) {
327
+ // Strip empties just in case
328
+ return value.filter(v => v != null && v !== "");
329
+ }
330
+ // Else single value, convert to array
331
+ return [String(value)];
332
+ }
320
333
  return value;
321
334
  }
322
335
 
@@ -460,10 +473,10 @@ export function generateReviewSummary(submissionData, req, siteId, showChangeLin
460
473
  {
461
474
  "element": "htmlElement",
462
475
  "params": {
463
- "text": {
464
- "en": `<a href="/${siteId}/${pageUrl}/view-file/${elementName}" target="_blank">${govcyResources.staticResources.text.viewFile.en}<span class="govcy-visually-hidden"> ${key?.en || ""}</span></a>`,
465
- "el": `<a href="/${siteId}/${pageUrl}/view-file/${elementName}" target="_blank">${govcyResources.staticResources.text.viewFile.el}<span class="govcy-visually-hidden"> ${key?.el || ""}</span></a>`,
466
- "tr": `<a href="/${siteId}/${pageUrl}/view-file/${elementName}" target="_blank">${govcyResources.staticResources.text.viewFile.tr}<span class="govcy-visually-hidden"> ${key?.tr || ""}</span></a>`
476
+ "text": {
477
+ "en": `<a href="/${siteId}/${pageUrl}/view-file/${elementName}" target="_blank">${govcyResources.staticResources.text.viewFile.en}<span class="govcy-visually-hidden"> ${key?.en || ""}</span></a>`,
478
+ "el": `<a href="/${siteId}/${pageUrl}/view-file/${elementName}" target="_blank">${govcyResources.staticResources.text.viewFile.el}<span class="govcy-visually-hidden"> ${key?.el || ""}</span></a>`,
479
+ "tr": `<a href="/${siteId}/${pageUrl}/view-file/${elementName}" target="_blank">${govcyResources.staticResources.text.viewFile.tr}<span class="govcy-visually-hidden"> ${key?.tr || ""}</span></a>`
467
480
  }
468
481
  }
469
482
  }
@@ -471,7 +484,7 @@ export function generateReviewSummary(submissionData, req, siteId, showChangeLin
471
484
  };
472
485
  }
473
486
 
474
-
487
+
475
488
 
476
489
 
477
490
  // Loop through each page in the submission data
@@ -550,7 +563,7 @@ export function generateSubmitEmail(service, submissionData, submissionId, req)
550
563
  }
551
564
  );
552
565
  }
553
-
566
+
554
567
  // Add data title to the body
555
568
  body.push(
556
569
  {
@@ -568,7 +581,7 @@ export function generateSubmitEmail(service, submissionData, submissionId, req)
568
581
  body.push(
569
582
  {
570
583
  component: "bodyHeading",
571
- params: {"headingLevel":2},
584
+ params: { "headingLevel": 2 },
572
585
  body: govcyResources.getLocalizeContent(pageTitle, req.globalLang)
573
586
  }
574
587
  );
@@ -578,14 +591,14 @@ export function generateSubmitEmail(service, submissionData, submissionId, req)
578
591
  for (const field of fields) {
579
592
  const label = govcyResources.getLocalizeContent(field.label, req.globalLang);
580
593
  const valueLabel = getSubmissionValueLabelString(field.valueLabel, req.globalLang);
581
- dataUl.push({key: label, value: valueLabel});
594
+ dataUl.push({ key: label, value: valueLabel });
582
595
  }
583
596
  // add data to the body
584
597
  body.push(
585
- {
586
- component: "bodyKeyValue",
587
- params: {type:"ul", items: dataUl},
588
- });
598
+ {
599
+ component: "bodyKeyValue",
600
+ params: { type: "ul", items: dataUl },
601
+ });
589
602
 
590
603
  }
591
604
 
@@ -606,84 +619,84 @@ export function generateSubmitEmail(service, submissionData, submissionId, req)
606
619
 
607
620
 
608
621
 
609
- /*
622
+ /*
610
623
  {
611
- "bank-details": {
612
- "formData": {
613
- "AccountName": "asd",
614
- "Iban": "CY12 0020 0123 0000 0001 2345 6789",
615
- "Swift": "BANKCY2NXXX",
616
- "_csrf": "sjknv79rxjgv0uggo0d5312vzgz37jsh"
617
- }
618
- },
619
- "answer-bank-boc": {
620
- "formData": {
621
- "Objection": "Object",
622
- "country": "Azerbaijan",
623
- "ObjectionReason": "ObjectionReasonCode1",
624
- "ObjectionExplanation": "asdsa",
625
- "DepositsBOCAttachment": "",
626
- "_csrf": "sjknv79rxjgv0uggo0d5312vzgz37jsh"
627
- }
628
- },
629
- "bank-settlement": {
630
- "formData": {
631
- "ReceiveSettlementExplanation": "",
632
- "ReceiveSettlementDate_day": "",
633
- "ReceiveSettlementDate_month": "",
634
- "ReceiveSettlementDate_year": "",
635
- "ReceiveSettlement": "no",
636
- "_csrf": "sjknv79rxjgv0uggo0d5312vzgz37jsh"
637
- }
638
- }
624
+ "bank-details": {
625
+ "formData": {
626
+ "AccountName": "asd",
627
+ "Iban": "CY12 0020 0123 0000 0001 2345 6789",
628
+ "Swift": "BANKCY2NXXX",
629
+ "_csrf": "sjknv79rxjgv0uggo0d5312vzgz37jsh"
630
+ }
631
+ },
632
+ "answer-bank-boc": {
633
+ "formData": {
634
+ "Objection": "Object",
635
+ "country": "Azerbaijan",
636
+ "ObjectionReason": "ObjectionReasonCode1",
637
+ "ObjectionExplanation": "asdsa",
638
+ "DepositsBOCAttachment": "",
639
+ "_csrf": "sjknv79rxjgv0uggo0d5312vzgz37jsh"
640
+ }
641
+ },
642
+ "bank-settlement": {
643
+ "formData": {
644
+ "ReceiveSettlementExplanation": "",
645
+ "ReceiveSettlementDate_day": "",
646
+ "ReceiveSettlementDate_month": "",
647
+ "ReceiveSettlementDate_year": "",
648
+ "ReceiveSettlement": "no",
649
+ "_csrf": "sjknv79rxjgv0uggo0d5312vzgz37jsh"
650
+ }
651
+ }
639
652
  }
640
653
 
641
654
 
642
655
 
643
656
  [
644
- {
645
- pageUrl: "personal-details",
646
- pageTitle: { en: "Personal data", el: "Προσωπικά στοιχεία" }, // from pageData.title in correct language
647
- fields: [
648
- [
649
- {
650
- id: "firstName",
651
- label: { en: "First Name", el: "Όνομα" },
652
- value: "John", // The actual user input value
653
- valueLabel: { en: "John", el: "John" } // Same label as the value for text inputs
654
- },
655
- {
656
- id: "lastName",
657
- label: { en: "Last Name", el: "Επίθετο" },
658
- value: "Doe", // The actual user input value
659
- valueLabel: { en: "Doe", el: "Doe" } // Same label as the value for text inputs
660
- },
661
- {
662
- id: "gender",
663
- label: { en: "Gender", el: "Φύλο" },
664
- value: "m", // The actual value ("male")
665
- valueLabel: { en: "Male", el: "Άντρας" } // The corresponding label for "male"
666
- },
667
- {
668
- id: "languages",
669
- label: { en: "Languages", el: "Γλώσσες" },
670
- value: ["en", "el"], // The selected values ["en", "el"]
671
- valueLabel: [
672
- { en: "English", el: "Αγγλικά" }, // Labels corresponding to "en" and "el"
673
- { en: "Greek", el: "Ελληνικά" }
674
- ]
675
- },
676
- {
677
- id: "birthDate",
678
- label: { en: "Birth Date", el: "Ημερομηνία Γέννησης" },
679
- value: "1990-01-13", // The actual value based on user input
680
- valueLabel: "13/1/1990" // Date inputs label will be conveted to D/M/YYYY
681
- }
682
- ]
683
- },
684
- ...
657
+ {
658
+ pageUrl: "personal-details",
659
+ pageTitle: { en: "Personal data", el: "Προσωπικά στοιχεία" }, // from pageData.title in correct language
660
+ fields: [
661
+ [
662
+ {
663
+ id: "firstName",
664
+ label: { en: "First Name", el: "Όνομα" },
665
+ value: "John", // The actual user input value
666
+ valueLabel: { en: "John", el: "John" } // Same label as the value for text inputs
667
+ },
668
+ {
669
+ id: "lastName",
670
+ label: { en: "Last Name", el: "Επίθετο" },
671
+ value: "Doe", // The actual user input value
672
+ valueLabel: { en: "Doe", el: "Doe" } // Same label as the value for text inputs
673
+ },
674
+ {
675
+ id: "gender",
676
+ label: { en: "Gender", el: "Φύλο" },
677
+ value: "m", // The actual value ("male")
678
+ valueLabel: { en: "Male", el: "Άντρας" } // The corresponding label for "male"
679
+ },
680
+ {
681
+ id: "languages",
682
+ label: { en: "Languages", el: "Γλώσσες" },
683
+ value: ["en", "el"], // The selected values ["en", "el"]
684
+ valueLabel: [
685
+ { en: "English", el: "Αγγλικά" }, // Labels corresponding to "en" and "el"
686
+ { en: "Greek", el: "Ελληνικά" }
687
+ ]
688
+ },
689
+ {
690
+ id: "birthDate",
691
+ label: { en: "Birth Date", el: "Ημερομηνία Γέννησης" },
692
+ value: "1990-01-13", // The actual value based on user input
693
+ valueLabel: "13/1/1990" // Date inputs label will be conveted to D/M/YYYY
694
+ }
695
+ ]
696
+ },
697
+ ...
685
698
  ]
686
699
 
687
700
 
688
701
 
689
- */
702
+ */