From 4c7fde582b8e4676871a8476b375ff40a7875842 Mon Sep 17 00:00:00 2001 From: Jamil Date: Wed, 11 Dec 2024 12:32:15 +0600 Subject: [PATCH 1/4] chore: add translations for v2 pages (#336) * chore: add translations for v2 review page * chore: add translations for event config * chore: remove duplicate translation --- src/translations/client.csv | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/translations/client.csv b/src/translations/client.csv index f634e7454..bc9f86e13 100644 --- a/src/translations/client.csv +++ b/src/translations/client.csv @@ -168,6 +168,10 @@ certificate.receipt.service.targetDay,,{event} registration after 45 days of eve certificate.receipt.service.targetDay.amount,,৳ 25.00,৳ 25.00 certificate.receipt.subheader,Subheader for receipt on payment on certificate,{event} Registration after {DOBDiff} of {DOE},{event} Déclaration après {DOBDiff} de {DOE} changeEmail.validation.msg,Phone number validation message,Must be a valid email address,Doit être une adresse e-mail valide +changeModal.cancel,The label for cancel button of change modal,Cancel,Annuler +changeModal.continue,The label for continue button of change modal,Continue,Continuer +changeModal.description,The description for change modal,A record will be created of any changes you make,Un enregistrement sera créé pour chaque modification que vous apporterez. +changeModal.title,The title for change modal,Edit declaration?,Modifier la déclaration? changePhone.validation.msg,Phone number validation message,Must be a valid 10 digit number that starts with 0,Doit être un numéro valide à {num} chiffres qui commence par {start}. config.advanced.search,This is used for the advanced search,Advanced Search,Recherche avancée config.advanced.search.instruction,This is used for the advanced search,Select the options to build an advanced search. A minimum of two search parameters is required.,Sélectionnez les options pour construire une recherche avancée. Un minimum de deux paramètres de recherche est requis. @@ -786,6 +790,21 @@ error.title,Error title,Oops!,Oups ! error.title.unauthorized,Error title unauthorized,Unauthorized!,Non autorisé ! error.userListError,Error message when user list loads fails,Failed to load users,Impossible de charger les utilisateurs error.weAreTryingToFixThisError,Error description,This page could not be found,"Ce n'est pas vous, c'est nous. C'est notre faute." +event.tennis-club-membership.action.declare.form.label,This is what this form is referred as in the system,Tennis club membership application,Demande d'adhésion au club de tennis +event.tennis-club-membership.action.declare.form.section.recommender.field.firstname.label,This is the label for the field,Recommender's first name,Prénom du recommandeur +event.tennis-club-membership.action.declare.form.section.recommender.field.id.label,This is the label for the field,Recommender's membership ID,ID d'adhésion du recommandeur +event.tennis-club-membership.action.declare.form.section.recommender.field.surname.label,This is the label for the field,Recommender's surname,Nom de famille du recommandeur +event.tennis-club-membership.action.declare.form.section.recommender.title,This is the title of the section,Who is recommending the applicant?,Qui recommande le demandeur? +event.tennis-club-membership.action.declare.form.section.who.field.dob.label,This is the label for the field,Applicant's date of birth,Date de naissance du demandeur +event.tennis-club-membership.action.declare.form.section.who.field.firstname.label,This is the label for the field,Applicant's first name,Prénom du demandeur +event.tennis-club-membership.action.declare.form.section.who.field.surname.label,This is the label for the field,Applicant's surname,Nom de famille du demandeur +event.tennis-club-membership.action.declare.form.section.who.title,This is the title of the section,Who is applying for the membership?,Qui postule pour l'adhésion? +event.tennis-club-membership.action.declare.form.version.1,This is the first version of the form,Version 1,Version 1 +event.tennis-club-membership.action.declare.label,This is shown as the action name anywhere the user can trigger the action from,Send an application,Envoyer une demande +event.tennis-club-membership.label,This is what this event is referred as in the system,Tennis club membership application,Demande d'adhésion au club de tennis +exitModal.cancel,The label for cancel button in exit modal,Cancel,Annuler +exitModal.exitWithoutSaving,The title for exit without saving modal,Exit without saving changes?,Quitter sans enregistrer les modifications? +exitModal.exitWithoutSavingDescription,The description for exit without saving modal,You have unsaved changes on your declaration form. Are you sure you want to exit without saving?,Vous avez des modifications non enregistrées sur votre formulaire de déclaration. Êtes-vous sûr de vouloir quitter sans enregistrer? fieldAgentHome.allUpdatesText,,Great job! You have updated all declarations,Bon travail ! Vous avez mis à jour toutes les déclarations fieldAgentHome.inProgressCount,,In progress ({total}),En cours ({total}) fieldAgentHome.queryError,The text when error ocurred loading rejected declarations,An error occurred while loading declarations,Une erreur s'est produite lors du chargement des déclarations @@ -1761,6 +1780,16 @@ register.selectVitalEvent.registerNewEventHeading,The section heading on the pag register.selectVitalEvent.registerNewEventTitle,The title that appears on the select vital event page,New declaration,Nouvelle déclaration register.selectinformant.legalGuardian,,Legal guardian,Tuteur légal register.workQueue.declarations.banner,,Declarations to register in your area,Déclarations à enregistrer dans votre région +registerModal.cancel,The label for cancel button of register modal,Cancel,Annuler +registerModal.description,The description for register modal,The declarant will be notified of this correction and a record of this decision will be recorded,Le déclarant sera informé de cette correction et un enregistrement de cette décision sera créé. +registerModal.register,The label for register button of register modal,Register,Enregistrer +registerModal.title,The title for register modal,Register the member?,Enregistrer le membre? +rejectModal.archive,The label for archive button of reject modal,Archive,Archiver +rejectModal.cancel,The label for cancel button of reject modal,Cancel,Annuler +rejectModal.description,The description for reject modal,Please describe the updates required to this record for follow up action.,Veuillez décrire les mises à jour nécessaires à ce dossier pour un suivi. +rejectModal.markAsDuplicate,The label for mark as duplicate checkbox of reject modal,Mark as a duplicate,Marquer comme doublon +rejectModal.sendForUpdate,The label for send For Update button of reject modal,Send For Update,Envoyer pour mise à jour +rejectModal.title,The title for reject modal,Reason for rejection?,Raison du rejet? reloadmodal.body,Body of reload modal,There’s a new version of {app_name} available. Please update to continue.,Une nouvelle version de {app_name} est disponible. Veuillez effectuer la mise à jour pour continuer. reloadmodal.button.update,Label of update button,Update,Mise à jour reloadmodal.title,Title when update is available,Update available,Mise à jour disponible @@ -1817,6 +1846,10 @@ review.signature.delete,Label for button that deletes signature,Delete,Supprimer review.signature.description,Label awknowledging the correctness of the declaration,"I, the undersigned, hereby declare that the particulars in this form are true and correct to the best of my knowledge.","Je soussigné(e) déclare par la présente que les informations contenues dans ce formulaire sont, à ma connaissance, vraies et correctes." review.signature.input.description,Description awknowledging the correctness of the declaration,"By signing this document with an electronic signature, I agree that such signature will be valid as handwritten signatures to the extent allowed by the laws of Farajaland.","En signant ce document avec une signature électronique, j'accepte que cette signature soit valable comme les signatures manuscrites dans la mesure où les lois du Farajaland le permettent." review.signature.open,Label for button that opens the signature input,Sign,Signer +reviewAction.description,The description for review action,"By clicking register, you confirm that the information entered is correct and the member can be registered.","En cliquant sur enregistrer, vous confirmez que les informations saisies sont correctes et que le membre peut être enregistré." +reviewAction.register,The label for register button of review action,Register,Enregistrer +reviewAction.reject,The label for reject button of review action,Reject,Rejeter +reviewAction.title,The title for review action,Register member,Enregistrer un membre search.bookmark.error.notification,Error Notification messages for bookmark advanced search result,"Sorry, something went wrong. Please try again","Désolé, quelque chose s'est mal passé. Veuillez réessayer" search.bookmark.loading.notification,Loading Notification messages for bookmark advanced search result,Bookmarking your advanced search results...,Mettre en signet les résultats de votre recherche avancée... search.bookmark.remove.loading.notification,Loading Notification messages for remove advanced search bookmark,Removing your advanced search bookmark...,Suppression de votre signet de recherche avancée... From 180ea298cbc34138316b07a63711eaf03ff5c310 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Tue, 17 Dec 2024 10:26:18 +0200 Subject: [PATCH 2/4] Events v2: add config for summary and workqueues (#344) * feat: add config for summary and workqueues * configure statusm created at, modified at to be default columns * feat: move review title to config * feat: add form for register * add conditional rules for action visibility * add more actions and conditionality * do not show register action after a record already has a register action * Events v2: form field validation example (#343) * add conditional rules for action visibility * add more actions and conditionality * do not show register action after a record already has a register action * add example form field validation * comment out file field for now * remove conditionals * update toolkit version --------- Co-authored-by: Markus Co-authored-by: jamil314 --- package.json | 2 +- src/form/tennis-club-membership.ts | 384 +++++++++++++++++++++-------- 2 files changed, 283 insertions(+), 103 deletions(-) diff --git a/package.json b/package.json index de35fc4b0..fd4ac8e66 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@hapi/boom": "^9.1.1", "@hapi/hapi": "^20.0.1", "@hapi/inert": "^6.0.3", - "@opencrvs/toolkit": "^0.0.5", + "@opencrvs/toolkit": "0.0.6-events", "@types/chalk": "^2.2.0", "@types/csv2json": "^1.4.0", "@types/fhir": "^0.0.30", diff --git a/src/form/tennis-club-membership.ts b/src/form/tennis-club-membership.ts index 7cd31b438..efb0ec55d 100644 --- a/src/form/tennis-club-membership.ts +++ b/src/form/tennis-club-membership.ts @@ -9,7 +9,142 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { defineConfig } from '@opencrvs/toolkit/events' +import { defineConfig, defineForm } from '@opencrvs/toolkit/events' +import { + defineConditional, + or, + eventHasAction, + userHasScope, + and, + not, + field +} from '@opencrvs/toolkit/conditionals' + +const TENNIS_CLUB_FORM = defineForm({ + label: { + id: 'event.tennis-club-membership.action.declare.form.label', + defaultMessage: 'Tennis club membership application', + description: 'This is what this form is referred as in the system' + }, + review: { + title: { + id: 'event.tennis-club-membership.action.declare.form.review.title', + defaultMessage: 'Member declaration for {firstname} {surname}', + description: 'Title of the form to show in review page' + } + }, + active: true, + version: { + id: '1.0.0', + label: { + id: 'event.tennis-club-membership.action.declare.form.version.1', + defaultMessage: 'Version 1', + description: 'This is the first version of the form' + } + }, + pages: [ + { + id: 'applicant', + title: { + id: 'event.tennis-club-membership.action.declare.form.section.who.title', + defaultMessage: 'Who is applying for the membership?', + description: 'This is the title of the section' + }, + fields: [ + { + id: 'applicant.firstname', + type: 'TEXT', + required: true, + label: { + defaultMessage: "Applicant's first name", + description: 'This is the label for the field', + id: 'event.tennis-club-membership.action.declare.form.section.who.field.firstname.label' + } + }, + { + id: 'applicant.surname', + type: 'TEXT', + required: true, + label: { + defaultMessage: "Applicant's surname", + description: 'This is the label for the field', + id: 'event.tennis-club-membership.action.declare.form.section.who.field.surname.label' + } + }, + { + id: 'applicant.dob', + type: 'DATE', + required: true, + validation: [ + { + message: { + defaultMessage: 'Please enter a valid date', + description: 'This is the error message for invalid date', + id: 'event.tennis-club-membership.action.declare.form.section.who.field.dob.error' + }, + validator: field('applicant.dob').isBeforeNow() + } + ], + label: { + defaultMessage: "Applicant's date of birth", + description: 'This is the label for the field', + id: 'event.tennis-club-membership.action.declare.form.section.who.field.dob.label' + } + } + // { + // id: 'applicant.image', + // type: 'FILE', + // required: false, + // label: { + // defaultMessage: "Applicant's profile picture", + // description: 'This is the label for the field', + // id: 'event.tennis-club-membership.action.declare.form.section.who.field.image.label' + // } + // } + ] + }, + { + id: 'recommender', + title: { + id: 'event.tennis-club-membership.action.declare.form.section.recommender.title', + defaultMessage: 'Who is recommending the applicant?', + description: 'This is the title of the section' + }, + fields: [ + { + id: 'recommender.firstname', + type: 'TEXT', + required: true, + label: { + defaultMessage: "Recommender's first name", + description: 'This is the label for the field', + id: 'event.tennis-club-membership.action.declare.form.section.recommender.field.firstname.label' + } + }, + { + id: 'recommender.surname', + type: 'TEXT', + required: true, + label: { + defaultMessage: "Recommender's surname", + description: 'This is the label for the field', + id: 'event.tennis-club-membership.action.declare.form.section.recommender.field.surname.label' + } + }, + { + id: 'recommender.id', + type: 'TEXT', + required: true, + label: { + defaultMessage: "Recommender's membership ID", + description: 'This is the label for the field', + id: 'event.tennis-club-membership.action.declare.form.section.recommender.field.id.label' + } + } + ] + } + ] +}) export const tennisClubMembershipEvent = defineConfig({ id: 'TENNIS_CLUB_MEMBERSHIP', @@ -18,115 +153,160 @@ export const tennisClubMembershipEvent = defineConfig({ description: 'This is what this event is referred as in the system', id: 'event.tennis-club-membership.label' }, + summary: { + title: { + defaultMessage: '{applicant.firstname} {applicant.surname}', + description: 'This is the title of the summary', + id: 'event.tennis-club-membership.summary.title' + }, + fields: [ + { + id: 'applicant.firstname' + }, + { + id: 'applicant.surname' + }, + { + id: 'recommender.firstname' + }, + { + id: 'recommender.surname' + }, + { + id: 'recommender.id' + } + ] + }, + workqueues: [ + { + id: 'all', + title: { + defaultMessage: 'All events', + description: 'Label for in progress workqueue', + id: 'event.tennis-club-membership.workqueue.all.label' + }, + fields: [ + { + id: 'applicant.firstname' + }, + { + id: 'applicant.surname' + } + ], + filters: [] + }, + { + id: 'ready-for-review', + title: { + defaultMessage: 'Ready for review', + description: 'Label for in review workqueue', + id: 'event.tennis-club-membership.workqueue.in-review.label' + }, + fields: [ + { + id: 'applicant.firstname' + }, + { + id: 'event.type' + }, + { + id: 'event.createdAt' + }, + { + id: 'event.modifiedAt' + } + ], + filters: [ + { + status: ['DECLARED'] + } + ] + }, + { + id: 'registered', + title: { + defaultMessage: 'Ready to print', + description: 'Label for registered workqueue', + id: 'event.tennis-club-membership.workqueue.registered.label' + }, + fields: [ + { + id: 'applicant.firstname' + }, + { + id: 'event.type' + }, + { + id: 'event.createdAt' + }, + { + id: 'event.modifiedAt' + } + ], + filters: [ + { + status: ['REGISTERED'] + } + ] + } + ], actions: [ { type: 'DECLARE', label: { - defaultMessage: 'Send an application', + defaultMessage: 'Declare', description: 'This is shown as the action name anywhere the user can trigger the action from', id: 'event.tennis-club-membership.action.declare.label' }, - forms: [ - { - label: { - id: 'event.tennis-club-membership.action.declare.form.label', - defaultMessage: 'Tennis club membership application', - description: 'This is what this form is referred as in the system' - }, - active: true, - version: { - id: '1.0.0', - label: { - id: 'event.tennis-club-membership.action.declare.form.version.1', - defaultMessage: 'Version 1', - description: 'This is the first version of the form' - } - }, - pages: [ - { - id: 'applicant', - title: { - id: 'event.tennis-club-membership.action.declare.form.section.who.title', - defaultMessage: 'Who is applying for the membership?', - description: 'This is the title of the section' - }, - fields: [ - { - id: 'applicant.firstname', - type: 'TEXT', - required: true, - label: { - defaultMessage: "Applicant's first name", - description: 'This is the label for the field', - id: 'event.tennis-club-membership.action.declare.form.section.who.field.firstname.label' - } - }, - { - id: 'applicant.surname', - type: 'TEXT', - required: true, - label: { - defaultMessage: "Applicant's surname", - description: 'This is the label for the field', - id: 'event.tennis-club-membership.action.declare.form.section.who.field.surname.label' - } - }, - { - id: 'applicant.dob', - type: 'DATE', - required: true, - label: { - defaultMessage: "Applicant's date of birth", - description: 'This is the label for the field', - id: 'event.tennis-club-membership.action.declare.form.section.who.field.dob.label' - } - } - ] - }, - { - id: 'recommender', - title: { - id: 'event.tennis-club-membership.action.declare.form.section.recommender.title', - defaultMessage: 'Who is recommending the applicant?', - description: 'This is the title of the section' - }, - fields: [ - { - id: 'recommender.firstname', - type: 'TEXT', - required: true, - label: { - defaultMessage: "Recommender's first name", - description: 'This is the label for the field', - id: 'event.tennis-club-membership.action.declare.form.section.recommender.field.firstname.label' - } - }, - { - id: 'recommender.surname', - type: 'TEXT', - required: true, - label: { - defaultMessage: "Recommender's surname", - description: 'This is the label for the field', - id: 'event.tennis-club-membership.action.declare.form.section.recommender.field.surname.label' - } - }, - { - id: 'recommender.id', - type: 'TEXT', - required: true, - label: { - defaultMessage: "Recommender's membership ID", - description: 'This is the label for the field', - id: 'event.tennis-club-membership.action.declare.form.section.recommender.field.id.label' - } - } - ] - } - ] - } - ] + forms: [TENNIS_CLUB_FORM], + allowedWhen: defineConditional(not(eventHasAction('DECLARE'))) + }, + { + type: 'VALIDATE', + label: { + defaultMessage: 'Validate', + description: + 'This is shown as the action name anywhere the user can trigger the action from', + id: 'event.tennis-club-membership.action.validate.label' + }, + allowedWhen: defineConditional(eventHasAction('DECLARE')), + forms: [TENNIS_CLUB_FORM] + }, + { + type: 'REGISTER', + label: { + defaultMessage: 'Register', + description: + 'This is shown as the action name anywhere the user can trigger the action from', + id: 'event.tennis-club-membership.action.register.label' + }, + allowedWhen: defineConditional( + and( + or( + eventHasAction('VALIDATE'), + and(eventHasAction('DECLARE'), userHasScope('register')) + ), + not(eventHasAction('REGISTER')) + ) + ), + forms: [TENNIS_CLUB_FORM] + }, + { + type: 'CUSTOM', + label: { + defaultMessage: 'My custom action', + description: + 'This is shown as the action name anywhere the user can trigger the action from', + id: 'event.tennis-club-membership.action.sdf.label' + }, + allowedWhen: defineConditional( + or( + eventHasAction('VALIDATE'), + and(eventHasAction('DECLARE'), userHasScope('register')) + ) + ), + forms: [] } ] }) From 04ea6f6bf4ab52951d301951c283cf638b00cbfe Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 18 Dec 2024 16:01:30 +0200 Subject: [PATCH 3/4] add FILE input --- src/form/tennis-club-membership.ts | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/form/tennis-club-membership.ts b/src/form/tennis-club-membership.ts index efb0ec55d..a25cedbee 100644 --- a/src/form/tennis-club-membership.ts +++ b/src/form/tennis-club-membership.ts @@ -90,17 +90,27 @@ const TENNIS_CLUB_FORM = defineForm({ description: 'This is the label for the field', id: 'event.tennis-club-membership.action.declare.form.section.who.field.dob.label' } + }, + { + id: 'applicant.image', + type: 'FILE', + required: false, + label: { + defaultMessage: "Applicant's profile picture", + description: 'This is the label for the field', + id: 'event.tennis-club-membership.action.declare.form.section.who.field.image.label' + } + }, + { + id: 'applicant.image.label', + type: 'TEXT', + required: false, + label: { + defaultMessage: "Applicant's profile picture description", + description: 'This is the label for the field', + id: 'event.tennis-club-membership.action.declare.form.section.who.field.image.label' + } } - // { - // id: 'applicant.image', - // type: 'FILE', - // required: false, - // label: { - // defaultMessage: "Applicant's profile picture", - // description: 'This is the label for the field', - // id: 'event.tennis-club-membership.action.declare.form.section.who.field.image.label' - // } - // } ] }, { From 5ed237d041191a84d765b0940996094e9dac1ead Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Thu, 19 Dec 2024 12:34:04 +0200 Subject: [PATCH 4/4] add minio url to window config --- src/client-config.js | 1 + src/client-config.prod.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/client-config.js b/src/client-config.js index 19aa2a2d5..d423e7c05 100644 --- a/src/client-config.js +++ b/src/client-config.js @@ -14,6 +14,7 @@ window.config = { LOGIN_URL: 'http://localhost:3020', AUTH_URL: 'http://localhost:7070/auth/', MINIO_BUCKET: 'ocrvs', + MINIO_URL: 'http://localhost:3535/ocrvs/', COUNTRY_CONFIG_URL: 'http://localhost:3040', // Country code in uppercase ALPHA-3 format COUNTRY: 'FAR', diff --git a/src/client-config.prod.js b/src/client-config.prod.js index 7b5e597bf..6735e1529 100644 --- a/src/client-config.prod.js +++ b/src/client-config.prod.js @@ -13,6 +13,7 @@ window.config = { CONFIG_API_URL: 'https://config.{{hostname}}', LOGIN_URL: 'https://login.{{hostname}}', AUTH_URL: 'https://gateway.{{hostname}}/auth/', + MINIO_URL: 'https://minio.{{hostname}}/ocrvs/', MINIO_BUCKET: 'ocrvs', COUNTRY_CONFIG_URL: 'https://countryconfig.{{hostname}}', // Country code in uppercase ALPHA-3 format